commit 83c892603a3953829a88a40c1ead3fa1088494b3 Author: Steven Cheung steven.cheung@sri.com Date: Mon Apr 16 16:25:21 2012 -0700
fixed race condition in connection establishment --- src/connections.h | 3 ++- src/network.cc | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/src/connections.h b/src/connections.h index 9b51ce5..ddf787a 100644 --- a/src/connections.h +++ b/src/connections.h @@ -19,8 +19,9 @@ struct conn_t { unsigned int serial; bool connected : 1; bool flushing : 1; + bool ever_received : 1;
- conn_t() : connected(false), flushing(false) {} + conn_t() : connected(false), flushing(false), ever_received(false) {}
/** Close and deallocate a connection. If the connection is part of a circuit, disconnect it from the circuit; this may cause the circuit diff --git a/src/network.cc b/src/network.cc index f312067..fb17e99 100644 --- a/src/network.cc +++ b/src/network.cc @@ -312,6 +312,8 @@ downstream_read_cb(struct bufferevent *bev, void *arg) { conn_t *down = (conn_t *)arg;
+ down->ever_received = 1; + log_debug(down, "%lu bytes available", (unsigned long)evbuffer_get_length(bufferevent_get_input(bev)));
@@ -375,6 +377,11 @@ downstream_event_cb(struct bufferevent *bev, short what, void *arg) { conn_t *conn = (conn_t *)arg;
+ log_debug(conn, "what=%04hx enabled=%x inbound=%ld outbound=%ld", + what, bufferevent_get_enabled(bev), + evbuffer_get_length(bufferevent_get_input(bev)), + evbuffer_get_length(bufferevent_get_output(bev))); + if (what & (BEV_EVENT_ERROR|BEV_EVENT_EOF|BEV_EVENT_TIMEOUT)) { if (what & BEV_EVENT_ERROR) log_info(conn, "network error in %s: %s", @@ -393,7 +400,8 @@ downstream_event_cb(struct bufferevent *bev, short what, void *arg) /* Peer is done sending us data. */ conn->recv_eof(); if (bufferevent_get_enabled(bev) || - evbuffer_get_length(bufferevent_get_input(bev)) > 0) { + evbuffer_get_length(bufferevent_get_input(bev)) > 0 || + evbuffer_get_length(bufferevent_get_output(bev)) > 0) { log_debug(conn, "acknowledging EOF downstream"); shutdown(bufferevent_getfd(bev), SHUT_RD); } else { @@ -444,14 +452,15 @@ downstream_flush_cb(struct bufferevent *bev, void *arg) { conn_t *conn = (conn_t *)arg; size_t remain = evbuffer_get_length(bufferevent_get_output(bev)); - log_debug(conn, "%lu bytes still to transmit%s%s%s", + log_debug(conn, "%lu bytes still to transmit%s%s%s%s", (unsigned long)remain, conn->connected ? "" : " (not connected)", conn->flushing ? "" : " (not flushing)", - conn->circuit() ? "" : " (no circuit)"); + conn->circuit() ? "" : " (no circuit)", + conn->ever_received ? "" : " (never received)");
if (remain == 0 && ((conn->flushing && conn->connected) - || !conn->circuit())) { + || (!conn->circuit() && conn->ever_received))) { bufferevent_disable(bev, EV_WRITE); if (bufferevent_get_enabled(bev)) { log_debug(conn, "sending EOF downstream"); @@ -822,5 +831,6 @@ conn_do_flush(conn_t *conn) if (remain == 0) downstream_flush_cb(conn->buffer, conn); else - log_debug(conn, "flushing %lu bytes to peer", (unsigned long)remain); + log_debug(conn, "flushing %lu bytes to peer [enabled=%x]", (unsigned long)remain, + bufferevent_get_enabled(conn->buffer)); }
tor-commits@lists.torproject.org