diff options
author | Roger Dingledine <arma@torproject.org> | 2004-02-27 04:42:14 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2004-02-27 04:42:14 +0000 |
commit | 195dfd35a80685a1cc545a5a308a588bd2b12220 (patch) | |
tree | b967b8271b10d6d8355626f3ba73ef4c93675bc7 /src/or | |
parent | feafba073dc06ae3deb2e716923f3ec2907115dc (diff) | |
download | tor-195dfd35a80685a1cc545a5a308a588bd2b12220.tar tor-195dfd35a80685a1cc545a5a308a588bd2b12220.tar.gz |
Fix a bug where you might flush some data on a tls connection, and then
add some more data to be flushed but never turn POLLOUT on. not sure
how commonly this bug was hit, but it would be a doozy.
Also add some asserts to see if it happens elsewhere.
svn:r1142
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/connection.c | 15 | ||||
-rw-r--r-- | src/or/main.c | 4 | ||||
-rw-r--r-- | src/or/or.h | 1 |
3 files changed, 16 insertions, 4 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 4d7933696..1e9876f8c 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -506,7 +506,7 @@ int connection_handle_write(connection_t *conn) { } else { if(flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen) < 0) return -1; - /* conns in CONNECTING state will fall through... */ + /* conns in CONNECTING state will fall through... */ } if(!connection_wants_to_flush(conn)) /* it's done flushing */ @@ -527,9 +527,8 @@ void connection_write_to_buf(const char *string, int len, connection_t *conn) { return; } - /* XXX if linkpadding, this only applies to conns that aren't open OR connections */ connection_start_writing(conn); -#define MIN_TLS_FLUSHLEN 16300 +#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 @@ -544,7 +543,11 @@ void connection_write_to_buf(const char *string, int len, connection_t *conn) { log_fn(LOG_WARN,"flushing failed."); } } - conn->outbuf_flushlen += len; + if(len > 0) { /* if there's any left over */ + conn->outbuf_flushlen += len; + connection_start_writing(conn); + /* because connection_handle_write() above might have stopped writing */ + } } connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port) { @@ -758,6 +761,10 @@ void assert_connection_ok(connection_t *conn, time_t now) assert(conn->type >= _CONN_TYPE_MIN); assert(conn->type <= _CONN_TYPE_MAX); + if(conn->outbuf_flushlen > 0) { + assert(connection_is_writing(conn) || conn->wants_to_write); + } + /* XXX check: wants_to_read, wants_to_write, s, poll_index, * marked_for_close. */ diff --git a/src/or/main.c b/src/or/main.c index 9abb8aef2..7a394fd5a 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -136,6 +136,10 @@ void connection_start_reading(connection_t *conn) { poll_array[conn->poll_index].events |= POLLIN; } +int connection_is_writing(connection_t *conn) { + return poll_array[conn->poll_index].events & POLLOUT; +} + void connection_stop_writing(connection_t *conn) { assert(conn && conn->poll_index < nfds); diff --git a/src/or/or.h b/src/or/or.h index 3aff94637..d7cd00cdb 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -748,6 +748,7 @@ void connection_watch_events(connection_t *conn, short events); int connection_is_reading(connection_t *conn); void connection_stop_reading(connection_t *conn); void connection_start_reading(connection_t *conn); +int connection_is_writing(connection_t *conn); void connection_stop_writing(connection_t *conn); void connection_start_writing(connection_t *conn); |