diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-09-09 11:04:54 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-09-09 11:04:54 -0400 |
commit | 8eed82b3d4bc8d15bd4ec7f229717f903dd6d6c7 (patch) | |
tree | 0587bfcb5b0a84db5060b5b95f452963b774968e | |
parent | dd22ab519ab9ac7affa3bd775b6021049ebe7dd9 (diff) | |
parent | 39a017809b6e7f8f779cfa0b4ebea3c0209bef0c (diff) | |
download | tor-8eed82b3d4bc8d15bd4ec7f229717f903dd6d6c7.tar.gz tor-8eed82b3d4bc8d15bd4ec7f229717f903dd6d6c7.zip |
Merge remote-tracking branch 'andrea/bug12160_025' into maint-0.2.5
-rw-r--r-- | changes/bug12160 | 4 | ||||
-rw-r--r-- | src/or/channel.c | 17 | ||||
-rw-r--r-- | src/or/channel.h | 1 | ||||
-rw-r--r-- | src/or/channeltls.c | 64 | ||||
-rw-r--r-- | src/or/channeltls.h | 1 | ||||
-rw-r--r-- | src/or/connection_or.c | 9 |
6 files changed, 94 insertions, 2 deletions
diff --git a/changes/bug12160 b/changes/bug12160 new file mode 100644 index 0000000000..2a7ace3410 --- /dev/null +++ b/changes/bug12160 @@ -0,0 +1,4 @@ + o Bugfixes + - Correctly update the local mark on the controlling channel when changing + the address of an or_connection_t after the handshake. Fixes bug #12160; + bugfix on 0.2.4.4-alpha. diff --git a/src/or/channel.c b/src/or/channel.c index ffd68493d0..b2b670e4fb 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -3760,6 +3760,23 @@ channel_mark_local(channel_t *chan) } /** + * Mark a channel as remote + * + * This internal-only function should be called by the lower layer if the + * channel is not to a local address but has previously been marked local. + * See channel_is_local() above or the description of the is_local bit in + * channel.h + */ + +void +channel_mark_remote(channel_t *chan) +{ + tor_assert(chan); + + chan->is_local = 0; +} + +/** * Test outgoing flag * * This function gets the outgoing flag; this is the inverse of the incoming diff --git a/src/or/channel.h b/src/or/channel.h index 3e164c6892..148199235a 100644 --- a/src/or/channel.h +++ b/src/or/channel.h @@ -349,6 +349,7 @@ void channel_clear_remote_end(channel_t *chan); void channel_mark_local(channel_t *chan); void channel_mark_incoming(channel_t *chan); void channel_mark_outgoing(channel_t *chan); +void channel_mark_remote(channel_t *chan); void channel_set_identity_digest(channel_t *chan, const char *identity_digest); void channel_set_remote_end(channel_t *chan, diff --git a/src/or/channeltls.c b/src/or/channeltls.c index 632bc328b7..245e33583b 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -156,7 +156,18 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port, tlschan, U64_PRINTF_ARG(chan->global_identifier)); - if (is_local_addr(addr)) channel_mark_local(chan); + if (is_local_addr(addr)) { + log_debug(LD_CHANNEL, + "Marking new outgoing channel " U64_FORMAT " at %p as local", + U64_PRINTF_ARG(chan->global_identifier), chan); + channel_mark_local(chan); + } else { + log_debug(LD_CHANNEL, + "Marking new outgoing channel " U64_FORMAT " at %p as remote", + U64_PRINTF_ARG(chan->global_identifier), chan); + channel_mark_remote(chan); + } + channel_mark_outgoing(chan); /* Set up or_connection stuff */ @@ -286,7 +297,18 @@ channel_tls_handle_incoming(or_connection_t *orconn) tlschan->conn = orconn; orconn->chan = tlschan; - if (is_local_addr(&(TO_CONN(orconn)->addr))) channel_mark_local(chan); + if (is_local_addr(&(TO_CONN(orconn)->addr))) { + log_debug(LD_CHANNEL, + "Marking new incoming channel " U64_FORMAT " at %p as local", + U64_PRINTF_ARG(chan->global_identifier), chan); + channel_mark_local(chan); + } else { + log_debug(LD_CHANNEL, + "Marking new incoming channel " U64_FORMAT " at %p as remote", + U64_PRINTF_ARG(chan->global_identifier), chan); + channel_mark_remote(chan); + } + channel_mark_incoming(chan); /* Register it */ @@ -1209,6 +1231,44 @@ channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn) } /** + * Update channel marks after connection_or.c has changed an address + * + * This is called from connection_or_init_conn_from_address() after the + * connection's _base.addr or real_addr fields have potentially been changed + * so we can recalculate the local mark. Notably, this happens when incoming + * connections are reverse-proxied and we only learn the real address of the + * remote router by looking it up in the consensus after we finish the + * handshake and know an authenticated identity digest. + */ + +void +channel_tls_update_marks(or_connection_t *conn) +{ + channel_t *chan = NULL; + + tor_assert(conn); + tor_assert(conn->chan); + + chan = TLS_CHAN_TO_BASE(conn->chan); + + if (is_local_addr(&(TO_CONN(conn)->addr))) { + if (!channel_is_local(chan)) { + log_debug(LD_CHANNEL, + "Marking channel " U64_FORMAT " at %p as local", + U64_PRINTF_ARG(chan->global_identifier), chan); + channel_mark_local(chan); + } + } else { + if (channel_is_local(chan)) { + log_debug(LD_CHANNEL, + "Marking channel " U64_FORMAT " at %p as remote", + U64_PRINTF_ARG(chan->global_identifier), chan); + channel_mark_remote(chan); + } + } +} + +/** * Check if this cell type is allowed before the handshake is finished * * Return true if <b>command</b> is a cell command that's allowed to start a diff --git a/src/or/channeltls.h b/src/or/channeltls.h index b4a7e2beac..c872a09d79 100644 --- a/src/or/channeltls.h +++ b/src/or/channeltls.h @@ -49,6 +49,7 @@ void channel_tls_handle_state_change_on_orconn(channel_tls_t *chan, uint8_t state); void channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn); +void channel_tls_update_marks(or_connection_t *conn); /* Cleanup at shutdown */ void channel_tls_free_all(void); diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 16f87349fc..c372270b4c 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -923,6 +923,15 @@ connection_or_init_conn_from_address(or_connection_t *conn, tor_free(conn->base_.address); conn->base_.address = tor_dup_addr(addr); } + + /* + * We have to tell channeltls.c to update the channel marks (local, in + * particular), since we may have changed the address. + */ + + if (conn->chan) { + channel_tls_update_marks(conn); + } } /** These just pass all the is_bad_for_new_circs manipulation on to |