summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Shepard <andrea@torproject.org>2012-11-07 11:43:04 -0800
committerAndrea Shepard <andrea@torproject.org>2012-11-07 11:43:04 -0800
commit9f3f5372b880b3372fd7b9fc98bd3d78f969390a (patch)
tree061b2f60cac277f8a64792e7845497be3accc0da
parentcd054ceadaa4723f076c7050160424b356b985ca (diff)
parent3b270e86be0ab8edcda2907f41ca3abb57f8c59a (diff)
downloadtor-9f3f5372b880b3372fd7b9fc98bd3d78f969390a.tar.gz
tor-9f3f5372b880b3372fd7b9fc98bd3d78f969390a.zip
Merge branch 'bug7350' of ssh://git-rw.torproject.org/user/andrea/tor
-rw-r--r--changes/bug73505
-rw-r--r--src/or/channel.c32
-rw-r--r--src/or/circuitlist.c14
3 files changed, 39 insertions, 12 deletions
diff --git a/changes/bug7350 b/changes/bug7350
new file mode 100644
index 0000000000..9c2f20dab6
--- /dev/null
+++ b/changes/bug7350
@@ -0,0 +1,5 @@
+ o Minor bugfixes:
+ - Avoid a possible assert that can occur when channel_send_destroy() is
+ called on a channel in CHANNEL_STATE_CLOSING, CHANNEL_STATE_CLOSED
+ or CHANNEL_STATE_ERROR when the Tor process is resumed after being
+ blocked for a long interval. Fixes bug 7350.
diff --git a/src/or/channel.c b/src/or/channel.c
index cbf7f99be1..16dd9f903a 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -2585,17 +2585,29 @@ channel_send_destroy(circid_t circ_id, channel_t *chan, int reason)
tor_assert(chan);
- memset(&cell, 0, sizeof(cell_t));
- cell.circ_id = circ_id;
- cell.command = CELL_DESTROY;
- cell.payload[0] = (uint8_t) reason;
- log_debug(LD_OR,
- "Sending destroy (circID %d) on channel %p "
- "(global ID " U64_FORMAT ")",
- circ_id, chan,
- U64_PRINTF_ARG(chan->global_identifier));
+ /* Check to make sure we can send on this channel first */
+ if (!(chan->state == CHANNEL_STATE_CLOSING ||
+ chan->state == CHANNEL_STATE_CLOSED ||
+ chan->state == CHANNEL_STATE_ERROR)) {
+ memset(&cell, 0, sizeof(cell_t));
+ cell.circ_id = circ_id;
+ cell.command = CELL_DESTROY;
+ cell.payload[0] = (uint8_t) reason;
+ log_debug(LD_OR,
+ "Sending destroy (circID %d) on channel %p "
+ "(global ID " U64_FORMAT ")",
+ circ_id, chan,
+ U64_PRINTF_ARG(chan->global_identifier));
- channel_write_cell(chan, &cell);
+ channel_write_cell(chan, &cell);
+ } else {
+ log_warn(LD_BUG,
+ "Someone called channel_send_destroy() for circID %d "
+ "on a channel " U64_FORMAT " at %p in state %s (%d)",
+ circ_id, U64_PRINTF_ARG(chan->global_identifier),
+ chan, channel_state_to_string(chan->state),
+ chan->state);
+ }
return 0;
}
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 3ec2bf15bb..32a478d744 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1411,7 +1411,12 @@ circuit_mark_for_close_(circuit_t *circ, int reason, int line,
}
if (circ->n_chan) {
circuit_clear_cell_queue(circ, circ->n_chan);
- channel_send_destroy(circ->n_circ_id, circ->n_chan, reason);
+ /* Only send destroy if the channel isn't closing anyway */
+ if (!(circ->n_chan->state == CHANNEL_STATE_CLOSING ||
+ circ->n_chan->state == CHANNEL_STATE_CLOSED ||
+ circ->n_chan->state == CHANNEL_STATE_ERROR)) {
+ channel_send_destroy(circ->n_circ_id, circ->n_chan, reason);
+ }
circuitmux_detach_circuit(circ->n_chan->cmux, circ);
}
@@ -1439,7 +1444,12 @@ circuit_mark_for_close_(circuit_t *circ, int reason, int line,
if (or_circ->p_chan) {
circuit_clear_cell_queue(circ, or_circ->p_chan);
- channel_send_destroy(or_circ->p_circ_id, or_circ->p_chan, reason);
+ /* Only send destroy if the channel isn't closing anyway */
+ if (!(or_circ->p_chan->state == CHANNEL_STATE_CLOSING ||
+ or_circ->p_chan->state == CHANNEL_STATE_CLOSED ||
+ or_circ->p_chan->state == CHANNEL_STATE_ERROR)) {
+ channel_send_destroy(or_circ->p_circ_id, or_circ->p_chan, reason);
+ }
circuitmux_detach_circuit(or_circ->p_chan->cmux, circ);
}
} else {