diff options
author | Mike Perry <mikeperry-git@torproject.org> | 2015-11-14 13:08:24 -0800 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-05-08 13:49:22 -0400 |
commit | 76c9330f9d41af48b64c0abe7a53749f1ee0d601 (patch) | |
tree | 4caef7fa2e5a80157ec9133a150f44f5cfb30434 /src/or/channeltls.c | |
parent | d5a151a06788c28ac1c50398c6e571d484774f47 (diff) | |
download | tor-76c9330f9d41af48b64c0abe7a53749f1ee0d601.tar.gz tor-76c9330f9d41af48b64c0abe7a53749f1ee0d601.zip |
Bug 17604: Converge on only one long-lived TLS conn between relays.
Accomplished via the following:
1. Use NETINFO cells to determine if both peers will agree on canonical
status. Prefer connections where they agree to those where they do not.
2. Alter channel_is_better() to prefer older orconns in the case of multiple
canonical connections, and use the orconn with more circuits on it in case
of age ties.
Also perform some hourly accounting on how many of these types of connections
there are and log it at info or notice level.
Diffstat (limited to 'src/or/channeltls.c')
-rw-r--r-- | src/or/channeltls.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/or/channeltls.c b/src/or/channeltls.c index 155684c0ce..4f2663adab 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -739,6 +739,15 @@ channel_tls_matches_target_method(channel_t *chan, return 0; } + /* real_addr is the address this connection came from. + * base_.addr is updated by connection_or_init_conn_from_address() + * to be the address in the descriptor. It may be tempting to + * allow either address to be allowed, but if we did so, it would + * enable someone who steals a relay's keys to impersonate/MITM it + * from anywhere on the Internet! (Because they could make long-lived + * TLS connections from anywhere to all relays, and wait for them to + * be used for extends). + */ return tor_addr_eq(&(tlschan->conn->real_addr), target); } @@ -1667,6 +1676,7 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) const uint8_t *cp, *end; uint8_t n_other_addrs; time_t now = time(NULL); + const routerinfo_t *me = router_get_my_routerinfo(); long apparent_skew = 0; tor_addr_t my_apparent_addr = TOR_ADDR_NULL; @@ -1745,8 +1755,20 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) { tor_addr_from_ipv4n(&my_apparent_addr, get_uint32(my_addr_ptr)); + + if (!get_options()->BridgeRelay && me && + get_uint32(my_addr_ptr) == htonl(me->addr)) { + chan->base_.is_canonical_to_peer = 1; + } + } else if (my_addr_type == RESOLVED_TYPE_IPV6 && my_addr_len == 16) { tor_addr_from_ipv6_bytes(&my_apparent_addr, (const char *) my_addr_ptr); + + if (!get_options()->BridgeRelay && me && + !tor_addr_is_null(&me->ipv6_addr) && + tor_addr_eq(&my_apparent_addr, &me->ipv6_addr)) { + chan->base_.is_canonical_to_peer = 1; + } } n_other_addrs = (uint8_t) *cp++; @@ -1762,6 +1784,14 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) connection_or_close_for_error(chan->conn, 0); return; } + /* A relay can connect from anywhere and be canonical, so + * long as it tells you from where it came. This may be a bit + * concerning.. Luckily we have another check in + * channel_tls_matches_target_method() to ensure that extends + * only go to the IP they ask for. + * + * XXX: Bleh. That check is not used if the connection is canonical. + */ if (tor_addr_eq(&addr, &(chan->conn->real_addr))) { connection_or_set_canonical(chan->conn, 1); break; @@ -1770,6 +1800,18 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) --n_other_addrs; } + if (me && !chan->base_.is_canonical_to_peer && chan->conn->is_canonical) { + log_info(LD_OR, + "We made a connection to a relay at %s (fp=%s) but we think " + "they will not consider this connection canonical. They " + "think we are at %s, but we think its %s.", + safe_str(chan->base_.get_remote_descr(&chan->base_, 0)), + safe_str(hex_str(chan->conn->identity_digest, DIGEST_LEN)), + safe_str(tor_addr_is_null(&my_apparent_addr) ? + "<none>" : fmt_and_decorate_addr(&my_apparent_addr)), + safe_str(fmt_addr32(me->addr))); + } + /* Act on apparent skew. */ /** Warn when we get a netinfo skew with at least this value. */ #define NETINFO_NOTICE_SKEW 3600 |