summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-10-02 21:42:24 -0400
committerNick Mathewson <nickm@torproject.org>2013-10-02 22:20:18 -0400
commit557f3329575cd6d1a2dd36fa8fb9cf0ac0b3f721 (patch)
tree1d45f04713d62a5ee1c9aae2fb4c8ae1bda0f728
parent938ee9b24dfda03a68a71d43b88e9fb00a90f9c8 (diff)
downloadtor-557f3329575cd6d1a2dd36fa8fb9cf0ac0b3f721.tar.gz
tor-557f3329575cd6d1a2dd36fa8fb9cf0ac0b3f721.zip
Fix a bug in our bug 9776 fix.
By calling circuit_n_chan_done() unconditionally on close, we were closing pending connections that might not have been pending quite for the connection we were closing. Fix for bug 9880. Thanks to skruffy for finding this and explaining it patiently until we understood.
-rw-r--r--changes/bug98808
-rw-r--r--src/or/channel.c7
-rw-r--r--src/or/channel.h3
3 files changed, 17 insertions, 1 deletions
diff --git a/changes/bug9880 b/changes/bug9880
new file mode 100644
index 0000000000..a7dda8f82f
--- /dev/null
+++ b/changes/bug9880
@@ -0,0 +1,8 @@
+ o Minor bugfixes:
+
+ - When closing a channel that has already been open, do not close
+ pending circuits that were waiting to connect to the same relay.
+ Fixes bug 9880; bugfix on 0.2.5.1-alpha. Thanks to skruffy for
+ finding this bug. (Bug was merged to 0.2.4 branch but not released
+ in any 0.2.4 version)
+
diff --git a/src/or/channel.c b/src/or/channel.c
index 1fb39b88ca..1270eace7d 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -743,6 +743,9 @@ channel_init(channel_t *chan)
/* Timestamp it */
channel_timestamp_created(chan);
+
+ /* It hasn't been open yet. */
+ chan->has_been_open = 0;
}
/**
@@ -1294,7 +1297,8 @@ channel_closed(channel_t *chan)
/* Inform any pending (not attached) circs that they should
* give up. */
- circuit_n_chan_done(chan, 0);
+ if (! chan->has_been_open)
+ circuit_n_chan_done(chan, 0);
/* Now close all the attached circuits on it. */
circuit_unlink_all_from_channel(chan, END_CIRC_REASON_CHANNEL_CLOSED);
@@ -1935,6 +1939,7 @@ channel_change_state(channel_t *chan, channel_state_t to_state)
/* Tell circuits if we opened and stuff */
if (to_state == CHANNEL_STATE_OPEN) {
channel_do_open_actions(chan);
+ chan->has_been_open = 1;
/* Check for queued cells to process */
if (! TOR_SIMPLEQ_EMPTY(&chan->incoming_queue))
diff --git a/src/or/channel.h b/src/or/channel.h
index 0933ec8d39..2dca81705f 100644
--- a/src/or/channel.h
+++ b/src/or/channel.h
@@ -46,6 +46,9 @@ struct channel_s {
/* Should we expect to see this channel in the channel lists? */
unsigned char registered:1;
+ /** has this channel ever been open? */
+ unsigned int has_been_open:1;
+
/** Why did we close?
*/
enum {