[or-cvs] r9382: Flush local controller connection buffers periodically as we (in tor/trunk: . src/or)

arma at seul.org arma at seul.org
Mon Jan 22 06:08:00 UTC 2007


Author: arma
Date: 2007-01-22 01:07:51 -0500 (Mon, 22 Jan 2007)
New Revision: 9382

Modified:
   tor/trunk/ChangeLog
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_or.c
Log:
Flush local controller connection buffers periodically as we're
writing to them, so we avoid queueing 4+ megabytes of data before
trying to flush.

Also add a new XXX012.


Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-01-22 05:59:59 UTC (rev 9381)
+++ tor/trunk/ChangeLog	2007-01-22 06:07:51 UTC (rev 9382)
@@ -31,6 +31,9 @@
       pointer loops.
     - Fix a memory leak when sending a 503 response for a networkstatus
       request.
+    - Flush local controller connection buffers periodically as we're
+      writing to them, so we avoid queueing 4+ megabytes of data before
+      trying to flush.
 
   o Minor bugfixes:
     - When computing clock skew from directory HTTP headers, consider what

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2007-01-22 05:59:59 UTC (rev 9381)
+++ tor/trunk/src/or/connection.c	2007-01-22 06:07:51 UTC (rev 9382)
@@ -1780,6 +1780,13 @@
   return 0;
 }
 
+/** Openssl TLS record size is 16383; this is close. The goal here is to
+ * push data out as soon as we know there's enough for a TLS record, so
+ * during periods of high load we won't read entire megabytes from
+ * input before pushing any data out. It also has the feature of not
+ * growing huge outbufs unless something is slow. */
+#define MIN_TLS_FLUSHLEN 15872
+
 /** Append <b>len</b> bytes of <b>string</b> onto <b>conn</b>'s
  * outbuf, and ask it to start writing.
  *
@@ -1787,6 +1794,11 @@
  * its contents compressed or decompressed as they're written.  If zlib is
  * negative, this is the last data to be compressed, and the connection's zlib
  * state should be flushed.
+ *
+ * If it's an OR conn and an entire TLS record is ready, then try to
+ * flush the record now. Similarly, if it's a local control connection
+ * and a 64k chunk is ready, try to flush it all, so we don't end up with
+ * many megabytes of controller info queued at once.
  */
 void
 _connection_write_to_buf_impl(const char *string, size_t len,
@@ -1804,7 +1816,7 @@
   if (zlib) {
     dir_connection_t *dir_conn = TO_DIR_CONN(conn);
     int done = zlib < 0;
-    if (!dir_conn) return;
+    if (!dir_conn) return; /* <-- XXX012 This line is pointless, yes? */
     CONN_LOG_PROTECT(conn, r = write_to_buf_zlib(conn->outbuf,
                                                  dir_conn->zlib_state,
                                                  string, len, done));
@@ -1828,10 +1840,42 @@
   }
 
   connection_start_writing(conn);
-  if (zlib)
+  if (zlib) {
     conn->outbuf_flushlen += buf_datalen(conn->outbuf) - old_datalen;
-  else
+  } else {
+    int extra = 0;
     conn->outbuf_flushlen += len;
+
+    if (conn->type == CONN_TYPE_OR &&
+        conn->outbuf_flushlen-len < MIN_TLS_FLUSHLEN &&
+        conn->outbuf_flushlen >= MIN_TLS_FLUSHLEN) {
+      extra = conn->outbuf_flushlen - MIN_TLS_FLUSHLEN;
+      conn->outbuf_flushlen = MIN_TLS_FLUSHLEN;
+    } else if (conn->type == CONN_TYPE_CONTROL &&
+               is_internal_IP(conn->addr, 0) &&
+               conn->outbuf_flushlen-len < 1<<16 &&
+               conn->outbuf_flushlen >= 1<<16) {
+      /* just try to flush all of it */
+    } else
+      return; /* no need to try flushing */
+
+    if (connection_handle_write(conn, 0) < 0) {
+      if (!conn->marked_for_close) {
+        /* this connection is broken. remove it. */
+        log_warn(LD_BUG, "Bug: unhandled error on write for "
+                 "conn (type %d, fd %d); removing",
+                 conn->type, conn->s);
+        tor_fragile_assert();
+        /* do a close-immediate here, so we don't try to flush */
+        connection_close_immediate(conn);
+      }
+      return;
+    }
+    if (extra) {
+      conn->outbuf_flushlen += extra;
+      connection_start_writing(conn);
+    }
+  }
 }
 
 /** Return the conn to addr/port that has the most recent
@@ -1881,7 +1925,7 @@
   return NULL;
 }
 
-/** Return the connection with id <b>id</b> if it is not already marked for
+/** Return the stream with id <b>id</b> if it is not already marked for
  * close.
  */
 edge_connection_t *

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2007-01-22 05:59:59 UTC (rev 9381)
+++ tor/trunk/src/or/connection_or.c	2007-01-22 06:07:51 UTC (rev 9382)
@@ -693,9 +693,6 @@
 
 /** Pack <b>cell</b> into wire-format, and write it onto <b>conn</b>'s
  * outbuf.
- *
- * If it's an OR conn, and an entire TLS record is
- * ready, then try to flush the record now.
  */
 void
 connection_or_write_cell_to_buf(const cell_t *cell, or_connection_t *conn)
@@ -709,35 +706,6 @@
   cell_pack(n, cell);
 
   connection_write_to_buf(n, CELL_NETWORK_SIZE, TO_CONN(conn));
-
-#define MIN_TLS_FLUSHLEN 15872
-/* openssl tls record size is 16383, this is close. The goal here is to
- * push data out as soon as we know there's enough for a tls record, so
- * during periods of high load we won't read the entire megabyte from
- * input before pushing any data out. It also has the feature of not
- * growing huge outbufs unless something is slow. */
-  if (conn->_base.outbuf_flushlen-CELL_NETWORK_SIZE < MIN_TLS_FLUSHLEN &&
-      conn->_base.outbuf_flushlen >= MIN_TLS_FLUSHLEN) {
-    int extra = conn->_base.outbuf_flushlen - MIN_TLS_FLUSHLEN;
-    conn->_base.outbuf_flushlen = MIN_TLS_FLUSHLEN;
-    connection_start_writing(TO_CONN(conn));
-    if (connection_handle_write(TO_CONN(conn), 0) < 0) {
-      if (!conn->_base.marked_for_close) {
-        /* this connection is broken. remove it. */
-        log_warn(LD_BUG,
-                 "Bug: unhandled error on write for OR conn (fd %d); removing",
-                 conn->_base.s);
-        tor_fragile_assert();
-        /* do a close-immediate here, so we don't try to flush */
-        connection_close_immediate(TO_CONN(conn));
-      }
-      return;
-    }
-    if (extra) {
-      conn->_base.outbuf_flushlen += extra;
-      connection_start_writing(TO_CONN(conn));
-    }
-  }
 }
 
 /** Process cells from <b>conn</b>'s inbuf.



More information about the tor-commits mailing list