[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] [tor/master 2/7] Decide whether to ignore SENDMEs based on streams_blocked, not queue size



Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Wed, 18 Aug 2010 14:14:28 -0400
Subject: Decide whether to ignore SENDMEs based on streams_blocked, not queue size
Commit: 80391b88a58a747fe6ac326442557a827e350d4f

---
 changes/bug1653 |    8 ++++++++
 src/or/relay.c  |   28 +++++++++-------------------
 2 files changed, 17 insertions(+), 19 deletions(-)
 create mode 100644 changes/bug1653

diff --git a/changes/bug1653 b/changes/bug1653
new file mode 100644
index 0000000..26cf55b
--- /dev/null
+++ b/changes/bug1653
@@ -0,0 +1,8 @@
+  o Major bugfixes:
+    - When the exit relay gets a circuit-level sendme cell, it started
+      reading on the exit streams, even if had 500 cells queued in our
+      circuit queue already, so our circuit queue just grew and grew
+      in some cases.  We fix this by not re-enabling reading on SENDME
+      while the cell queue is blocked.  Fixes bug 1653.  Bugfix on
+      0.2.0.1-alpha.  Detected by Mashael ??.  Original patch by
+      "yetonetime".
diff --git a/src/or/relay.c b/src/or/relay.c
index bc17b6d..c123eb3 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -52,8 +52,7 @@ circuit_resume_edge_reading_helper(edge_connection_t *conn,
                                    crypt_path_t *layer_hint);
 static int
 circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint);
-static int
-circuit_queue_high(circuit_t *circ);
+static int circuit_queue_streams_are_blocked(circuit_t *circ);
 
 /** Cache the current hi-res time; the cache gets reset when libevent
  * calls us. */
@@ -1238,7 +1237,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
       conn->package_window += STREAMWINDOW_INCREMENT;
       log_debug(domain,"stream-level sendme, packagewindow now %d.",
                 conn->package_window);
-      if (circuit_queue_high(circ)) { /* Too high, don't touch conn */
+      if (circuit_queue_streams_are_blocked(circ)) {
+        /* Still waiting for queue to flush; don't touch conn */
         return 0;
       }
       connection_start_reading(TO_CONN(conn));
@@ -1441,8 +1441,7 @@ connection_edge_consider_sending_sendme(edge_connection_t *conn)
 static void
 circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
 {
-
-  if (circuit_queue_high(circ)) {
+  if (circuit_queue_streams_are_blocked(circ)) {
     log_debug(layer_hint?LD_APP:LD_EXIT,"Too big queue, no resuming");
     return;
   }
@@ -2414,24 +2413,15 @@ assert_active_circuits_ok(or_connection_t *orconn)
   tor_assert(n == smartlist_len(orconn->active_circuit_pqueue));
 }
 
-/** Return 1 if the number of cells waiting on the queue
- *  more than a watermark or equal it. Else return 0.
- *  XXXY: Only for edges: origin and exit. Middles out of luck for such,
- *  need the proposal. 
+/** Return 1 if we shouldn't restart reading on this circuit, even if
+ * we get a SENDME.  Else return 0.
 */
 static int
-circuit_queue_high(circuit_t *circ)
+circuit_queue_streams_are_blocked(circuit_t *circ)
 {
-  cell_queue_t *queue;
-
   if (CIRCUIT_IS_ORIGIN(circ)) {
-    queue = &circ->n_conn_cells;
+    return circ->streams_blocked_on_n_conn;
   } else {
-    or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
-    queue = &orcirc->p_conn_cells;
+    return circ->streams_blocked_on_p_conn;
   }
-
-  if (queue->n >= CELL_QUEUE_HIGHWATER_SIZE)
-    return 1;
-  return 0;
 }
-- 
1.7.1