mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-23 22:47:12 +01:00
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
This commit is contained in:
parent
7b5f9887fa
commit
ab838bddb8
3 changed files with 51 additions and 36 deletions
|
@ -31,6 +31,9 @@ Changes in version 0.1.2.7-alpha - 2007-??-??
|
||||||
pointer loops.
|
pointer loops.
|
||||||
- Fix a memory leak when sending a 503 response for a networkstatus
|
- Fix a memory leak when sending a 503 response for a networkstatus
|
||||||
request.
|
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:
|
o Minor bugfixes:
|
||||||
- When computing clock skew from directory HTTP headers, consider what
|
- When computing clock skew from directory HTTP headers, consider what
|
||||||
|
|
|
@ -1780,6 +1780,13 @@ connection_handle_write(connection_t *conn, int force)
|
||||||
return 0;
|
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
|
/** Append <b>len</b> bytes of <b>string</b> onto <b>conn</b>'s
|
||||||
* outbuf, and ask it to start writing.
|
* 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
|
* 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
|
* negative, this is the last data to be compressed, and the connection's zlib
|
||||||
* state should be flushed.
|
* 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
|
void
|
||||||
_connection_write_to_buf_impl(const char *string, size_t len,
|
_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) {
|
if (zlib) {
|
||||||
dir_connection_t *dir_conn = TO_DIR_CONN(conn);
|
dir_connection_t *dir_conn = TO_DIR_CONN(conn);
|
||||||
int done = zlib < 0;
|
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,
|
CONN_LOG_PROTECT(conn, r = write_to_buf_zlib(conn->outbuf,
|
||||||
dir_conn->zlib_state,
|
dir_conn->zlib_state,
|
||||||
string, len, done));
|
string, len, done));
|
||||||
|
@ -1828,10 +1840,42 @@ _connection_write_to_buf_impl(const char *string, size_t len,
|
||||||
}
|
}
|
||||||
|
|
||||||
connection_start_writing(conn);
|
connection_start_writing(conn);
|
||||||
if (zlib)
|
if (zlib) {
|
||||||
conn->outbuf_flushlen += buf_datalen(conn->outbuf) - old_datalen;
|
conn->outbuf_flushlen += buf_datalen(conn->outbuf) - old_datalen;
|
||||||
else
|
} else {
|
||||||
|
int extra = 0;
|
||||||
conn->outbuf_flushlen += len;
|
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
|
/** 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 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.
|
* close.
|
||||||
*/
|
*/
|
||||||
edge_connection_t *
|
edge_connection_t *
|
||||||
|
|
|
@ -693,9 +693,6 @@ connection_tls_finish_handshake(or_connection_t *conn)
|
||||||
|
|
||||||
/** Pack <b>cell</b> into wire-format, and write it onto <b>conn</b>'s
|
/** Pack <b>cell</b> into wire-format, and write it onto <b>conn</b>'s
|
||||||
* outbuf.
|
* outbuf.
|
||||||
*
|
|
||||||
* If it's an OR conn, and an entire TLS record is
|
|
||||||
* ready, then try to flush the record now.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
connection_or_write_cell_to_buf(const cell_t *cell, or_connection_t *conn)
|
connection_or_write_cell_to_buf(const cell_t *cell, or_connection_t *conn)
|
||||||
|
@ -709,35 +706,6 @@ connection_or_write_cell_to_buf(const cell_t *cell, or_connection_t *conn)
|
||||||
cell_pack(n, cell);
|
cell_pack(n, cell);
|
||||||
|
|
||||||
connection_write_to_buf(n, CELL_NETWORK_SIZE, TO_CONN(conn));
|
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.
|
/** Process cells from <b>conn</b>'s inbuf.
|
||||||
|
|
Loading…
Add table
Reference in a new issue