[tor-commits] [stegotorus/master] Fix bug causing connections to remain open forever.

zwol at torproject.org zwol at torproject.org
Fri Jul 20 23:17:08 UTC 2012


commit d1f6f3fc8ad3ad9fcc79e239e10ba7f0fe49e37d
Author: Zack Weinberg <zackw at cmu.edu>
Date:   Wed Jun 27 18:48:06 2012 -0700

    Fix bug causing connections to remain open forever.
    
    We failed to record when connections reached 'read EOF' state, so close()
    never got called.  The analogous case for circuits is handled by the protocol.
    
    Also fix how the close_cleanup_cb gets activated per advice from libevent
    maintainer.
---
 src/connections.cc |   24 ++++++++++--------------
 src/network.cc     |    8 +++++---
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/src/connections.cc b/src/connections.cc
index 99957fe..8f8a8c6 100644
--- a/src/connections.cc
+++ b/src/connections.cc
@@ -89,6 +89,10 @@ close_cleanup_cb(evutil_socket_t, short, void *arg)
 {
   conn_global_state *cgs = (conn_global_state *)arg;
 
+  log_debug("cleaning up %lu circuits and %lu connections",
+            (unsigned long)cgs->closed_circuits.size(),
+            (unsigned long)cgs->closed_connections.size());
+
   if (!cgs->closed_circuits.empty()) {
     unordered_set<circuit_t *> v;
     v.swap(cgs->closed_circuits);
@@ -197,18 +201,14 @@ conn_t::close()
   if (this->buffer)
     bufferevent_disable(this->buffer, EV_READ|EV_WRITE);
 
-  bool need_event_add =
+  bool need_event =
     cgs->closed_connections.empty() && cgs->closed_circuits.empty();
 
   cgs->connections.erase(this);
   cgs->closed_connections.insert(this);
 
-  if (need_event_add) {
-    struct timeval tv;
-    tv.tv_sec = 0;
-    tv.tv_usec = 0;
-    event_add(cgs->close_cleanup, &tv);
-  }
+  if (need_event)
+    event_active(cgs->close_cleanup, 0, 0);
 }
 
 /** Potentially called during connection construction or destruction. */
@@ -308,18 +308,14 @@ circuit_t::close()
   if (this->axe_timer)
     event_del(this->axe_timer);
 
-  bool need_event_add =
+  bool need_event =
     cgs->closed_connections.empty() && cgs->closed_circuits.empty();
 
   cgs->circuits.erase(this);
   cgs->closed_circuits.insert(this);
 
-  if (need_event_add) {
-    struct timeval tv;
-    tv.tv_sec = 0;
-    tv.tv_usec = 0;
-    event_add(cgs->close_cleanup, &tv);
-  }
+  if (need_event)
+    event_active(cgs->close_cleanup, 0, 0);
 }
 
 config_t *
diff --git a/src/network.cc b/src/network.cc
index 7a8f4ce..945fcbf 100644
--- a/src/network.cc
+++ b/src/network.cc
@@ -389,6 +389,7 @@ downstream_event_cb(struct bufferevent *bev, short what, void *arg)
     if (what == (BEV_EVENT_EOF|BEV_EVENT_READING)) {
       /* Peer is done sending us data. */
       conn->recv_eof();
+      conn->read_eof = true;
       if (conn->read_eof && conn->write_eof)
         conn->close();
     } else {
@@ -435,11 +436,12 @@ 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%s%s",
+  log_debug(conn, "%lu bytes still to transmit%s%s%s%s%s%s",
             (unsigned long)remain,
             conn->connected ? "" : " (not connected)",
-            conn->pending_write_eof ? " (received EOF)" : "",
-            conn->write_eof ? " (at EOF)" : "",
+            conn->pending_write_eof ? " (reached EOF)" : "",
+            conn->write_eof ? " (sent EOF)" : "",
+            conn->read_eof ? " (received EOF)" : "",
             conn->circuit() ? "" : " (no circuit)",
             conn->ever_received ? "" : " (never received)");
 





More information about the tor-commits mailing list