[or-cvs] Do round-robin writes of at most 16 kB per write. This might

arma at seul.org arma at seul.org
Sat Oct 29 18:19:39 UTC 2005


Update of /home2/or/cvsroot/tor/src/or
In directory moria:/home/arma/work/onion/cvs/tor/src/or

Modified Files:
	or.h connection.c buffers.c main.c 
Log Message:
Do round-robin writes of at most 16 kB per write. This might
be more fair on loaded Tor servers, and it might resolve our
Windows crash bug. It might also slow things down.


Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.727
retrieving revision 1.728
diff -u -d -r1.727 -r1.728
--- or.h	27 Oct 2005 00:34:39 -0000	1.727
+++ or.h	29 Oct 2005 18:19:37 -0000	1.728
@@ -1363,8 +1363,8 @@
 int read_to_buf(int s, size_t at_most, buf_t *buf, int *reached_eof);
 int read_to_buf_tls(tor_tls_t *tls, size_t at_most, buf_t *buf);
 
-int flush_buf(int s, buf_t *buf, size_t *buf_flushlen);
-int flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t *buf_flushlen);
+int flush_buf(int s, buf_t *buf, size_t sz, size_t *buf_flushlen);
+int flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t sz, size_t *buf_flushlen);
 
 int write_to_buf(const char *string, size_t string_len, buf_t *buf);
 int fetch_from_buf(char *string, size_t string_len, buf_t *buf);
@@ -1541,6 +1541,7 @@
 int retry_all_listeners(int force, smartlist_t *replaced_conns,
                         smartlist_t *new_conns);
 
+int connection_bucket_write_limit(connection_t *conn);
 void connection_bucket_init(void);
 void connection_bucket_refill(struct timeval *now);
 

Index: connection.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.414
retrieving revision 1.415
diff -u -d -r1.414 -r1.415
--- connection.c	25 Oct 2005 18:01:01 -0000	1.414
+++ connection.c	29 Oct 2005 18:19:37 -0000	1.415
@@ -23,7 +23,6 @@
 static int connection_reached_eof(connection_t *conn);
 static int connection_read_to_buf(connection_t *conn, int *max_to_read);
 static int connection_process_inbuf(connection_t *conn, int package_partial);
-static int connection_bucket_read_limit(connection_t *conn);
 static void client_check_address_changed(int sock);
 
 static uint32_t last_interface_ip = 0;
@@ -983,6 +982,29 @@
   return at_most;
 }
 
+/** How many bytes at most can we write onto this connection? */
+int
+connection_bucket_write_limit(connection_t *conn)
+{
+  int at_most;
+
+  /* do a rudimentary round-robin so one circuit can't hog a connection */
+  if (connection_speaks_cells(conn)) {
+    at_most = 32*(CELL_NETWORK_SIZE);
+  } else {
+    at_most = 32*(RELAY_PAYLOAD_SIZE);
+  }
+
+  if (at_most > conn->outbuf_flushlen)
+    at_most = conn->outbuf_flushlen;
+
+#if 0 /* don't enable til we actually do write limiting */
+  if (at_most > global_write_bucket)
+    at_most = global_write_bucket;
+#endif
+  return at_most;
+}
+
 /** We just read num_read onto conn. Decrement buckets appropriately. */
 static void
 connection_read_bucket_decrement(connection_t *conn, int num_read)
@@ -1317,6 +1339,7 @@
   int e;
   socklen_t len=sizeof(e);
   int result;
+  int max_to_write;
   time_t now = time(NULL);
 
   tor_assert(!connection_is_listener(conn));
@@ -1359,6 +1382,8 @@
       return -1;
   }
 
+  max_to_write = connection_bucket_write_limit(conn);
+
   if (connection_speaks_cells(conn) && conn->state > OR_CONN_STATE_PROXY_READING) {
     if (conn->state == OR_CONN_STATE_HANDSHAKING) {
       connection_stop_writing(conn);
@@ -1371,7 +1396,8 @@
     }
 
     /* else open, or closing */
-    result = flush_buf_tls(conn->tls, conn->outbuf, &conn->outbuf_flushlen);
+    result = flush_buf_tls(conn->tls, conn->outbuf,
+                           max_to_write, &conn->outbuf_flushlen);
     switch (result) {
       case TOR_TLS_ERROR:
       case TOR_TLS_CLOSE:
@@ -1403,7 +1429,8 @@
     }
   } else {
     CONN_LOG_PROTECT(conn,
-             result = flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen));
+             result = flush_buf(conn->s, conn->outbuf,
+                                max_to_write, &conn->outbuf_flushlen));
     if (result < 0) {
       if (CONN_IS_EDGE(conn))
         connection_edge_end_errno(conn, conn->cpath_layer);
@@ -1429,7 +1456,8 @@
   return 0;
 }
 
-/* DOCDOC */
+/* A controller event has just happened with such urgency that we
+ * need to write it onto controller <b>conn</b> immediately. */
 void
 _connection_controller_force_write(connection_t *conn)
 {
@@ -1445,7 +1473,8 @@
     return;
 
   CONN_LOG_PROTECT(conn,
-      result = flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen));
+      result = flush_buf(conn->s, conn->outbuf,
+                         conn->outbuf_flushlen, &conn->outbuf_flushlen));
   if (result < 0) {
     connection_close_immediate(conn); /* Don't flush; connection is dead. */
     connection_mark_for_close(conn);

Index: buffers.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/buffers.c,v
retrieving revision 1.177
retrieving revision 1.178
diff -u -d -r1.177 -r1.178
--- buffers.c	25 Oct 2005 18:01:01 -0000	1.177
+++ buffers.c	29 Oct 2005 18:19:37 -0000	1.178
@@ -576,21 +576,19 @@
     return 0;
   } else {
     *buf_flushlen -= write_result;
-
     buf_remove_from_front(buf, write_result);
-
     return write_result;
   }
 }
 
 /** Write data from <b>buf</b> to the socket <b>s</b>.  Write at most
- * *<b>buf_flushlen</b> bytes, decrement *<b>buf_flushlen</b> by
+ * <b>sz</b> bytes, decrement *<b>buf_flushlen</b> by
  * the number of bytes actually written, and remove the written bytes
  * from the buffer.  Return the number of bytes written on success,
  * -1 on failure.  Return 0 if write() would block.
  */
 int
-flush_buf(int s, buf_t *buf, size_t *buf_flushlen)
+flush_buf(int s, buf_t *buf, size_t sz, size_t *buf_flushlen)
 {
   int r;
   size_t flushed = 0;
@@ -600,11 +598,12 @@
   tor_assert(buf_flushlen);
   tor_assert(s>=0);
   tor_assert(*buf_flushlen <= buf->datalen);
+  tor_assert(sz <= *buf_flushlen);
 
-  if (*buf_flushlen == 0) /* nothing to flush */
+  if (sz == 0) /* nothing to flush */
     return 0;
 
-  flushlen0 = *buf_flushlen;
+  flushlen0 = sz;
   _split_range(buf, buf->cur, &flushlen0, &flushlen1);
 
   r = flush_buf_impl(s, buf, flushlen0, buf_flushlen);
@@ -653,7 +652,7 @@
 /** As flush_buf(), but writes data to a TLS connection.
  */
 int
-flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t *buf_flushlen)
+flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t sz, size_t *buf_flushlen)
 {
   int r;
   size_t flushed=0;
@@ -661,12 +660,14 @@
   assert_buf_ok(buf);
   tor_assert(tls);
   tor_assert(buf_flushlen);
+  tor_assert(*buf_flushlen <= buf->datalen);
+  tor_assert(sz <= *buf_flushlen);
 
   /* we want to let tls write even if flushlen is zero, because it might
    * have a partial record pending */
   check_no_tls_errors();
 
-  flushlen0 = *buf_flushlen;
+  flushlen0 = sz;
   _split_range(buf, buf->cur, &flushlen0, &flushlen1);
 
   r = flush_buf_tls_impl(tls, buf, flushlen0, buf_flushlen);

Index: main.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/main.c,v
retrieving revision 1.584
retrieving revision 1.585
diff -u -d -r1.584 -r1.585
--- main.c	25 Oct 2005 18:01:01 -0000	1.584
+++ main.c	29 Oct 2005 18:19:37 -0000	1.585
@@ -439,8 +439,9 @@
 
   debug(LD_NET,"Cleaning up connection (fd %d).",conn->s);
   if (conn->s >= 0 && connection_wants_to_flush(conn)) {
-    /* -1 means it's an incomplete edge connection, or that the socket
+    /* s == -1 means it's an incomplete edge connection, or that the socket
      * has already been closed as unflushable. */
+    int sz = connection_bucket_write_limit(conn);
     if (!conn->hold_open_until_flushed)
       info(LD_NET,
         "Conn (addr %s, fd %d, type %s, state %d) marked, but wants to flush %d bytes. "
@@ -449,14 +450,15 @@
         (int)conn->outbuf_flushlen, conn->marked_for_close_file, conn->marked_for_close);
     if (connection_speaks_cells(conn)) {
       if (conn->state == OR_CONN_STATE_OPEN) {
-        retval = flush_buf_tls(conn->tls, conn->outbuf, &conn->outbuf_flushlen);
+        retval = flush_buf_tls(conn->tls, conn->outbuf, sz, &conn->outbuf_flushlen);
       } else
         retval = -1; /* never flush non-open broken tls connections */
     } else {
-      retval = flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen);
+      retval = flush_buf(conn->s, conn->outbuf, sz, &conn->outbuf_flushlen);
     }
-    if (retval >= 0 &&
-       conn->hold_open_until_flushed && connection_wants_to_flush(conn)) {
+    if (retval >= 0 && /* Technically, we could survive things like
+                          TLS_WANT_WRITE here. But don't bother for now. */
+        conn->hold_open_until_flushed && connection_wants_to_flush(conn)) {
       LOG_FN_CONN(conn,
                   (LOG_INFO,LD_NET,"Holding conn (fd %d) open for more flushing.",conn->s));
       /* XXX should we reset timestamp_lastwritten here? */



More information about the tor-commits mailing list