commit ca2e7eabc293791bb6d4664f851fb2a6374bbfb6
parent 3ef7e6f1870bf6bc2c26076c6abb545a576f9a42
Author: Nick Mathewson <nickm@torproject.org>
Date: Fri, 29 Sep 2017 17:26:40 -0400
Merge branches 'bug8185_031' and 'bug8185_diagnostic_032'
Diffstat:
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/changes/8185_diagnostic b/changes/8185_diagnostic
@@ -0,0 +1,4 @@
+ o Minor features (logging diagnostic):
+ - Log more circuit information whenever we are about to try to
+ package a relay cell on a circuit with a nonexistent n_chan.
+ Attempt to diagnose bug 8185.
diff --git a/changes/bug8185_025 b/changes/bug8185_025
@@ -0,0 +1,6 @@
+ o Minor bugfixes (logging, relay shutdown, annoyance):
+ - When a circuit is marked for close, do not attempt to package any cells
+ for channels on that circuit. Previously, we would detect this
+ condition lower in the call stack, when we noticed that the circuit had
+ no attached channel, and log an annoying message. Fixes bug 8185;
+ bugfix on 0.2.5.4-alpha.
diff --git a/src/or/relay.c b/src/or/relay.c
@@ -495,12 +495,25 @@ circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
{
channel_t *chan; /* where to send the cell */
+ if (circ->marked_for_close) {
+ /* Circuit is marked; send nothing. */
+ return 0;
+ }
+
if (cell_direction == CELL_DIRECTION_OUT) {
crypt_path_t *thishop; /* counter for repeated crypts */
chan = circ->n_chan;
if (!chan) {
log_warn(LD_BUG,"outgoing relay cell sent from %s:%d has n_chan==NULL."
- " Dropping.", filename, lineno);
+ " Dropping. Circuit is in state %s (%d), and is "
+ "%smarked for close. (%s:%d, %d)", filename, lineno,
+ circuit_state_to_string(circ->state), circ->state,
+ circ->marked_for_close ? "" : "not ",
+ circ->marked_for_close_file?circ->marked_for_close_file:"",
+ circ->marked_for_close, circ->marked_for_close_reason);
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ circuit_log_path(LOG_WARN, LD_BUG, TO_ORIGIN_CIRCUIT(circ));
+ }
log_backtrace(LOG_WARN,LD_BUG,"");
return 0; /* just drop it */
}
@@ -810,6 +823,12 @@ connection_edge_send_command(edge_connection_t *fromconn,
return -1;
}
+ if (circ->marked_for_close) {
+ /* The circuit has been marked, but not freed yet. When it's freed, it
+ * will mark this connection for close. */
+ return -1;
+ }
+
#ifdef MEASUREMENTS_21206
/* Keep track of the number of RELAY_DATA cells sent for directory
* connections. */