[tor-commits] [stegotorus/master] Fix another subtle circuit-teardown bug.

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


commit 77316e9364db0d629354148145f2575fbd835260
Author: Zack Weinberg <zackw at cmu.edu>
Date:   Fri Jun 15 13:37:28 2012 -0700

    Fix another subtle circuit-teardown bug.
---
 src/connections.cc   |    5 +++--
 src/connections.h    |    7 +++++--
 src/network.cc       |   15 +++++++++------
 src/protocol/chop.cc |    7 +++++--
 src/protocol/null.cc |    1 +
 5 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/connections.cc b/src/connections.cc
index 4f95d12..f252b23 100644
--- a/src/connections.cc
+++ b/src/connections.cc
@@ -247,6 +247,7 @@ circuit_send(circuit_t *ckt)
 void
 circuit_send_eof(circuit_t *ckt)
 {
+  ckt->pending_eof_send = true;
   if (ckt->socks_state) {
     log_debug(ckt, "EOF during SOCKS phase");
     delete ckt;
@@ -271,11 +272,11 @@ circuit_recv_eof(circuit_t *ckt)
       shutdown(bufferevent_getfd(ckt->up_buffer), SHUT_WR);
     } else {
       log_debug(ckt, "holding EOF till connection");
-      ckt->pending_eof = 1;
+      ckt->pending_eof_recv = true;
     }
   } else {
     log_debug(ckt, "no buffer, holding EOF till connection");
-    ckt->pending_eof = 1;
+    ckt->pending_eof_recv = true;
   }
 }
 
diff --git a/src/connections.h b/src/connections.h
index 64a4252..76c5f56 100644
--- a/src/connections.h
+++ b/src/connections.h
@@ -121,9 +121,12 @@ struct circuit_t {
 
   bool                connected : 1;
   bool                flushing : 1;
-  bool                pending_eof : 1;
+  bool                pending_eof_recv : 1;
+  bool                pending_eof_send : 1;
 
-  circuit_t() : connected(false), flushing(false), pending_eof(false) {}
+  circuit_t()
+  : connected(false), flushing(false),
+    pending_eof_recv(false), pending_eof_send(false) {}
   virtual ~circuit_t();
 
   /** Return the configuration that this circuit belongs to. */
diff --git a/src/network.cc b/src/network.cc
index b5f6d4b..25a05e4 100644
--- a/src/network.cc
+++ b/src/network.cc
@@ -346,9 +346,11 @@ upstream_event_cb(struct bufferevent *bev, short what, void *arg)
       /* Upstream is done sending us data. */
       circuit_send_eof(ckt);
       if (bufferevent_get_enabled(bev) ||
-          evbuffer_get_length(bufferevent_get_input(bev)) > 0) {
+          evbuffer_get_length(bufferevent_get_input(bev)) > 0 ||
+          ckt->pending_eof_send) {
         log_debug(ckt, "acknowledging EOF upstream");
         shutdown(bufferevent_getfd(bev), SHUT_RD);
+        bufferevent_disable(bev, EV_READ);
       } else {
         delete ckt;
       }
@@ -428,11 +430,12 @@ upstream_flush_cb(struct bufferevent *bev, void *arg)
 
   if (remain == 0 && ckt->flushing && ckt->connected
       && (!ckt->flush_timer || !evtimer_pending(ckt->flush_timer, NULL))) {
-    bufferevent_disable(bev, EV_WRITE);
     if (bufferevent_get_enabled(bev) ||
-        evbuffer_get_length(bufferevent_get_input(bev)) > 0) {
+        evbuffer_get_length(bufferevent_get_input(bev)) > 0 ||
+        ckt->pending_eof_send) {
       log_debug(ckt, "sending EOF upstream");
       shutdown(bufferevent_getfd(bev), SHUT_WR);
+      bufferevent_disable(bev, EV_WRITE);
     } else {
       delete ckt;
     }
@@ -485,7 +488,7 @@ upstream_connect_cb(struct bufferevent *bev, short what, void *arg)
                       upstream_event_cb, ckt);
     bufferevent_enable(ckt->up_buffer, EV_READ|EV_WRITE);
     ckt->connected = 1;
-    if (ckt->pending_eof) {
+    if (ckt->pending_eof_recv) {
       /* Try again to process the EOF. */
       circuit_recv_eof(ckt);
     }
@@ -530,7 +533,7 @@ downstream_connect_cb(struct bufferevent *bev, short what, void *arg)
       return;
     }
 
-    if (ckt->pending_eof) {
+    if (ckt->pending_eof_recv) {
       /* Try again to process the EOF. */
       circuit_recv_eof(ckt);
     }
@@ -624,7 +627,7 @@ downstream_socks_connect_cb(struct bufferevent *bev, short what, void *arg)
          connection. */
       upstream_read_cb(ckt->up_buffer, ckt);
 
-    if (ckt->pending_eof) {
+    if (ckt->pending_eof_recv) {
       /* Try again to process the EOF. */
       circuit_recv_eof(ckt);
     }
diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc
index a30dd94..65ee661 100644
--- a/src/protocol/chop.cc
+++ b/src/protocol/chop.cc
@@ -569,6 +569,7 @@ chop_circuit_t::~chop_circuit_t()
              sent_fin ? '+' : '-', received_fin ? '+' : '-',
              upstream_eof ? '+' : '-',
              (unsigned long)downstreams.size());
+    *(volatile char *)0 = 0;
   }
 
   for (unordered_set<chop_conn_t *>::iterator i = downstreams.begin();
@@ -870,9 +871,11 @@ chop_circuit_t::send_targeted(chop_conn_t *conn, size_t d, size_t p, opcode_t f,
   evbuffer_drain(payload, d);
 
   send_seq++;
-  if (f == op_FIN)
+  if (f == op_FIN) {
     sent_fin = true;
-  if ((f == op_DAT || f == op_FIN) && d > 0)
+    pending_eof_send = false;
+  }
+  if ((f == op_DAT && d > 0) || f == op_FIN)
     // We are making forward progress if we are _either_ sending or
     // receiving data.
     dead_cycles = 0;
diff --git a/src/protocol/null.cc b/src/protocol/null.cc
index ca6cc74..dab712a 100644
--- a/src/protocol/null.cc
+++ b/src/protocol/null.cc
@@ -208,6 +208,7 @@ null_circuit_t::send_eof()
 {
   if (this->downstream)
     conn_send_eof(this->downstream);
+  this->pending_eof_send = false;
   return 0;
 }
 





More information about the tor-commits mailing list