summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-09-22 15:17:00 -0400
committerNick Mathewson <nickm@torproject.org>2016-09-22 15:17:00 -0400
commit6e96eababe8f05ac03b2e83911e6fae5654884b4 (patch)
tree7f3c4aefeaaa56ae84cc91b22c64445282fe8f73
parent1edea87c2ac66d9d9ba5c92e6b2e4baddb6bd886 (diff)
parente4aaf7666028c30866ad63053ad9f6eb6bf16bf7 (diff)
downloadtor-6e96eababe8f05ac03b2e83911e6fae5654884b4.tar.gz
tor-6e96eababe8f05ac03b2e83911e6fae5654884b4.zip
Merge branch 'bug20203_027_squashed' into maint-0.2.8
-rw-r--r--changes/bug202036
-rw-r--r--src/or/circuitlist.c10
-rw-r--r--src/or/relay.c9
3 files changed, 23 insertions, 2 deletions
diff --git a/changes/bug20203 b/changes/bug20203
new file mode 100644
index 0000000000..b4809ffbd6
--- /dev/null
+++ b/changes/bug20203
@@ -0,0 +1,6 @@
+ o Major bugfixes (relay, OOM handler)
+ - Fix a timing-dependent assertion failure that could occur when we
+ tried to flush from a circuit after having freed its cells because
+ of an out-of-memory condition. Fixes bug 20203; bugfix on
+ 0.2.8.1-alpha. Thanks to "cypherpunks" for help diagnosing this
+ one.
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 1efb7ef4d0..d7dbfe5744 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1918,8 +1918,14 @@ marked_circuit_free_cells(circuit_t *circ)
return;
}
cell_queue_clear(&circ->n_chan_cells);
- if (! CIRCUIT_IS_ORIGIN(circ))
- cell_queue_clear(& TO_OR_CIRCUIT(circ)->p_chan_cells);
+ if (circ->n_mux)
+ circuitmux_clear_num_cells(circ->n_mux, circ);
+ if (! CIRCUIT_IS_ORIGIN(circ)) {
+ or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
+ cell_queue_clear(&orcirc->p_chan_cells);
+ if (orcirc->p_mux)
+ circuitmux_clear_num_cells(orcirc->p_mux, circ);
+ }
}
static size_t
diff --git a/src/or/relay.c b/src/or/relay.c
index fb8c8e74d6..3f7751826c 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -2615,6 +2615,15 @@ channel_flush_from_first_active_circuit, (channel_t *chan, int max))
}
/* Circuitmux told us this was active, so it should have cells */
+ if (/*BUG(*/ queue->n == 0 /*)*/) {
+ log_warn(LD_BUG, "Found a supposedly active circuit with no cells "
+ "to send. Trying to recover.");
+ circuitmux_set_num_cells(cmux, circ, 0);
+ if (! circ->marked_for_close)
+ circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL);
+ continue;
+ }
+
tor_assert(queue->n > 0);
/*