Decide whether to ignore SENDMEs based on streams_blocked, not queue size

This commit is contained in:
Nick Mathewson 2010-08-18 14:14:28 -04:00
parent 4dd3245abb
commit 80391b88a5
2 changed files with 17 additions and 19 deletions

8
changes/bug1653 Normal file
View File

@ -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".

View File

@ -52,8 +52,7 @@ circuit_resume_edge_reading_helper(edge_connection_t *conn,
crypt_path_t *layer_hint); crypt_path_t *layer_hint);
static int static int
circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint); circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint);
static int static int circuit_queue_streams_are_blocked(circuit_t *circ);
circuit_queue_high(circuit_t *circ);
/** Cache the current hi-res time; the cache gets reset when libevent /** Cache the current hi-res time; the cache gets reset when libevent
* calls us. */ * calls us. */
@ -1238,7 +1237,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
conn->package_window += STREAMWINDOW_INCREMENT; conn->package_window += STREAMWINDOW_INCREMENT;
log_debug(domain,"stream-level sendme, packagewindow now %d.", log_debug(domain,"stream-level sendme, packagewindow now %d.",
conn->package_window); 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; return 0;
} }
connection_start_reading(TO_CONN(conn)); connection_start_reading(TO_CONN(conn));
@ -1441,8 +1441,7 @@ connection_edge_consider_sending_sendme(edge_connection_t *conn)
static void static void
circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint) circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
{ {
if (circuit_queue_streams_are_blocked(circ)) {
if (circuit_queue_high(circ)) {
log_debug(layer_hint?LD_APP:LD_EXIT,"Too big queue, no resuming"); log_debug(layer_hint?LD_APP:LD_EXIT,"Too big queue, no resuming");
return; return;
} }
@ -2414,24 +2413,15 @@ assert_active_circuits_ok(or_connection_t *orconn)
tor_assert(n == smartlist_len(orconn->active_circuit_pqueue)); tor_assert(n == smartlist_len(orconn->active_circuit_pqueue));
} }
/** Return 1 if the number of cells waiting on the queue /** Return 1 if we shouldn't restart reading on this circuit, even if
* more than a watermark or equal it. Else return 0. * we get a SENDME. Else return 0.
* XXXY: Only for edges: origin and exit. Middles out of luck for such,
* need the proposal.
*/ */
static int 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)) { if (CIRCUIT_IS_ORIGIN(circ)) {
queue = &circ->n_conn_cells; return circ->streams_blocked_on_n_conn;
} else { } else {
or_circuit_t *orcirc = TO_OR_CIRCUIT(circ); return circ->streams_blocked_on_p_conn;
queue = &orcirc->p_conn_cells;
} }
if (queue->n >= CELL_QUEUE_HIGHWATER_SIZE)
return 1;
return 0;
} }