diff options
author | Roger Dingledine <arma@torproject.org> | 2007-01-22 06:07:51 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2007-01-22 06:07:51 +0000 |
commit | ab838bddb89fa3f37eeada29e8c10d16873b5e86 (patch) | |
tree | 8c908e7cb155cbc1ae02886c3ab097f398aadeab /src/or/connection.c | |
parent | 7b5f9887fa3a8bf37d1968ab547edbdd6cba1f02 (diff) | |
download | tor-ab838bddb89fa3f37eeada29e8c10d16873b5e86.tar.gz tor-ab838bddb89fa3f37eeada29e8c10d16873b5e86.zip |
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.
svn:r9382
Diffstat (limited to 'src/or/connection.c')
-rw-r--r-- | src/or/connection.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 5b31cec21d..6a25cac731 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1780,6 +1780,13 @@ connection_handle_write(connection_t *conn, int force) 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 @@ connection_handle_write(connection_t *conn, int force) * 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 @@ _connection_write_to_buf_impl(const char *string, size_t len, 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_write_to_buf_impl(const char *string, size_t len, } 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 @@ connection_get_by_type_addr_port_purpose(int type, 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 * |