]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Always call circuit_n_chan_done(chan, 0) from channel_closed()
authorAndrea Shepard <andrea@torproject.org>
Mon, 23 Sep 2013 16:37:26 +0000 (09:37 -0700)
committerNick Mathewson <nickm@torproject.org>
Tue, 24 Sep 2013 14:42:12 +0000 (10:42 -0400)
changes/bug9776 [new file with mode: 0644]
src/or/channel.c
src/or/connection_or.c

diff --git a/changes/bug9776 b/changes/bug9776
new file mode 100644 (file)
index 0000000..ea3a96a
--- /dev/null
@@ -0,0 +1,5 @@
+   o Normal bugfixes:
+     - Always call circuit_n_chan_done(chan, 0) from channel_closed(), so we
+       can't leak pending circuits in some cases where
+       run_connection_housekeeping() calls connection_or_close_normally().
+       Fixes bug #9776; bugfix on 0.2.4.17.
index 602797d0dc2bb449f87aab499fa529dd9f7af57b..1fb39b88cac42bc6ac36cc234dd13810b12ff4e9 100644 (file)
@@ -1292,11 +1292,10 @@ channel_closed(channel_t *chan)
   if (chan->state == CHANNEL_STATE_CLOSED ||
       chan->state == CHANNEL_STATE_ERROR) return;
 
-  if (chan->reason_for_closing == CHANNEL_CLOSE_FOR_ERROR) {
-    /* Inform any pending (not attached) circs that they should
-     * give up. */
-    circuit_n_chan_done(chan, 0);
-  }
+  /* Inform any pending (not attached) circs that they should
+   * give up. */
+  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);
 
index 0e9d06a72d93824b58a41ad21f8cd47636f0d5d3..3d16e1453cbbd7f63bc3648e1ddce0e8383a8e4c 100644 (file)
@@ -1160,6 +1160,16 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port,
 
 /** Mark orconn for close and transition the associated channel, if any, to
  * the closing state.
+ *
+ * It's safe to call this and connection_or_close_for_error() any time, and
+ * channel layer will treat it as a connection closing for reasons outside
+ * its control, like the remote end closing it.  It can also be a local
+ * reason that's specific to connection_t/or_connection_t rather than
+ * the channel mechanism, such as expiration of old connections in
+ * run_connection_housekeeping().  If you want to close a channel_t
+ * from somewhere that logically works in terms of generic channels
+ * rather than connections, use channel_mark_for_close(); see also
+ * the comment on that function in channel.c.
  */
 
 void