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);
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;
}