diff options
author | yetonetime <yetonetime@> | 2010-08-18 13:55:01 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2010-08-18 14:33:37 -0400 |
commit | 4dd3245abb32066e025bbf00e22dd40f4fc605cb (patch) | |
tree | 192b3a48ba8212c1778ce806a1d78221052b1f3c /src/or/relay.c | |
parent | d72edc4b78f0104823d156e605259d9d41e6f54c (diff) | |
download | tor-4dd3245abb32066e025bbf00e22dd40f4fc605cb.tar.gz tor-4dd3245abb32066e025bbf00e22dd40f4fc605cb.zip |
Avoid over-filling cell queues when we receive a SENDME
Do not start reading on exit streams when we get a SENDME unless we
have space in the appropriate circuit's cell queue.
Draft fix for bug 1653.
(commit message by nickm)
Diffstat (limited to 'src/or/relay.c')
-rw-r--r-- | src/or/relay.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/or/relay.c b/src/or/relay.c index b85cc84c52..bc17b6d126 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -52,6 +52,8 @@ 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); /** Cache the current hi-res time; the cache gets reset when libevent * calls us. */ @@ -1236,6 +1238,9 @@ 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 */ + return 0; + } connection_start_reading(TO_CONN(conn)); /* handle whatever might still be on the inbuf */ if (connection_edge_package_raw_inbuf(conn, 1) < 0) { @@ -1437,6 +1442,10 @@ static void circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint) { + if (circuit_queue_high(circ)) { + log_debug(layer_hint?LD_APP:LD_EXIT,"Too big queue, no resuming"); + return; + } log_debug(layer_hint?LD_APP:LD_EXIT,"resuming"); if (CIRCUIT_IS_ORIGIN(circ)) @@ -2405,3 +2414,24 @@ 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. +*/ +static int +circuit_queue_high(circuit_t *circ) +{ + cell_queue_t *queue; + + if (CIRCUIT_IS_ORIGIN(circ)) { + queue = &circ->n_conn_cells; + } else { + or_circuit_t *orcirc = TO_OR_CIRCUIT(circ); + queue = &orcirc->p_conn_cells; + } + + if (queue->n >= CELL_QUEUE_HIGHWATER_SIZE) + return 1; + return 0; +} |