aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Kadianakis <desnacked@riseup.net>2020-08-25 20:37:04 +0300
committerGeorge Kadianakis <desnacked@riseup.net>2020-08-25 20:37:04 +0300
commitd4f3cfe99a4c3ef3495a8f8848981f9b30cc8a34 (patch)
treef38c8af8720c9be4790466ed030e1ba8bb8867bb
parentcc4e42ee3257d5157172cedb73ed86ba88ca271d (diff)
parent75772ea096e030ecc79f67b1444cac42aaed7449 (diff)
downloadtor-d4f3cfe99a4c3ef3495a8f8848981f9b30cc8a34.tar.gz
tor-d4f3cfe99a4c3ef3495a8f8848981f9b30cc8a34.zip
Merge branch 'mr/113'
-rw-r--r--changes/bug201656
-rw-r--r--src/core/or/channel.c2
-rw-r--r--src/core/or/channel.h3
-rw-r--r--src/core/or/channeltls.c7
-rw-r--r--src/feature/relay/circuitbuild_relay.c24
-rw-r--r--src/feature/relay/router.c25
-rw-r--r--src/feature/relay/router.h1
7 files changed, 61 insertions, 7 deletions
diff --git a/changes/bug20165 b/changes/bug20165
new file mode 100644
index 0000000000..bbe9f00032
--- /dev/null
+++ b/changes/bug20165
@@ -0,0 +1,6 @@
+ o Minor bugfixes (self-testing):
+ - When receiving an incoming circuit, only accept it as evidence that we
+ are reachable if the declared address of its channel is the same
+ address we think that we have. Otherwise, it could be evidence that
+ we're reachable on some other address. Fixes bug 20165; bugfix on
+ 0.1.0.1-rc.
diff --git a/src/core/or/channel.c b/src/core/or/channel.c
index 91f083ec00..d082174dc8 100644
--- a/src/core/or/channel.c
+++ b/src/core/or/channel.c
@@ -871,6 +871,8 @@ channel_init(channel_t *chan)
/* Channel is not in the scheduler heap. */
chan->sched_heap_idx = -1;
+
+ tor_addr_make_unspec(&chan->addr_according_to_peer);
}
/**
diff --git a/src/core/or/channel.h b/src/core/or/channel.h
index 10b80aa7d5..606b0730b8 100644
--- a/src/core/or/channel.h
+++ b/src/core/or/channel.h
@@ -236,6 +236,9 @@ struct channel_t {
/** The handle to this channel (to free on canceled timers) */
struct channel_handle_t *timer_handle;
+ /** If not UNSPEC, the address that the peer says we have. */
+ tor_addr_t addr_according_to_peer;
+
/**
* These two fields specify the minimum and maximum negotiated timeout
* values for inactivity (send or receive) before we decide to pad a
diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c
index 51b772728e..a0debf8d22 100644
--- a/src/core/or/channeltls.c
+++ b/src/core/or/channeltls.c
@@ -1856,6 +1856,13 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
}
}
+ if (me) {
+ /* We have a descriptor, so we are a relay: record the address that the
+ * other side said we had. */
+ tor_addr_copy(&TLS_CHAN_TO_BASE(chan)->addr_according_to_peer,
+ &my_apparent_addr);
+ }
+
n_other_addrs = netinfo_cell_get_n_my_addrs(netinfo_cell);
for (uint8_t i = 0; i < n_other_addrs; i++) {
/* Consider all the other addresses; if any matches, this connection is
diff --git a/src/feature/relay/circuitbuild_relay.c b/src/feature/relay/circuitbuild_relay.c
index ad20e143be..64f3c341ae 100644
--- a/src/feature/relay/circuitbuild_relay.c
+++ b/src/feature/relay/circuitbuild_relay.c
@@ -588,13 +588,23 @@ onionskin_answer(struct or_circuit_t *circ,
if ((!channel_is_local(circ->p_chan)
|| get_options()->ExtendAllowPrivateAddresses)
&& !channel_is_outgoing(circ->p_chan)) {
- /* record that we could process create cells from a non-local conn
- * that we didn't initiate; presumably this means that create cells
- * can reach us too. */
- tor_addr_t remote_addr;
- if (channel_get_addr_if_possible(circ->p_chan, &remote_addr)) {
- int family = tor_addr_family(&remote_addr);
- router_orport_found_reachable(family);
+ /* Okay, it's a create cell from a non-local connection
+ * that we didn't initiate. Presumably this means that create cells
+ * can reach us too. But what address can they reach us on? */
+ const tor_addr_t *my_supposed_addr = &circ->p_chan->addr_according_to_peer;
+ if (router_addr_is_my_published_addr(my_supposed_addr)) {
+ /* Great, this create cell came on connection where the peer says
+ * that the our address is an address we're actually advertising!
+ * That should mean that we're reachable. But before we finally
+ * declare ourselves reachable, make sure that the address listed
+ * by the peer is the same family as the peer is actually using.
+ */
+ tor_addr_t remote_addr;
+ int family = tor_addr_family(my_supposed_addr);
+ if (channel_get_addr_if_possible(circ->p_chan, &remote_addr) &&
+ tor_addr_family(&remote_addr) == family) {
+ router_orport_found_reachable(family);
+ }
}
}
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 9bf0e7026f..11847a2616 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -1729,6 +1729,31 @@ router_is_me(const routerinfo_t *router)
return router_digest_is_me(router->cache_info.identity_digest);
}
+/**
+ * Return true if we are a server, and if @a addr is an address we are
+ * currently publishing (or trying to publish) in our descriptor.
+ * Return false otherwise.
+ **/
+bool
+router_addr_is_my_published_addr(const tor_addr_t *addr)
+{
+ IF_BUG_ONCE(!addr)
+ return false;
+
+ const routerinfo_t *me = router_get_my_routerinfo();
+ if (!me)
+ return false;
+
+ switch (tor_addr_family(addr)) {
+ case AF_INET:
+ return tor_addr_eq(addr, &me->ipv4_addr);
+ case AF_INET6:
+ return tor_addr_eq(addr, &me->ipv6_addr);
+ default:
+ return false;
+ }
+}
+
/** Return a routerinfo for this OR, rebuilding a fresh one if
* necessary. Return NULL on error, or if called on an OP. */
MOCK_IMPL(const routerinfo_t *,
diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h
index 89b4a479a4..f71ada8eb7 100644
--- a/src/feature/relay/router.h
+++ b/src/feature/relay/router.h
@@ -100,6 +100,7 @@ int router_digest_is_me(const char *digest);
const uint8_t *router_get_my_id_digest(void);
int router_extrainfo_digest_is_me(const char *digest);
int router_is_me(const routerinfo_t *router);
+bool router_addr_is_my_published_addr(const tor_addr_t *addr);
int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e);
int router_rebuild_descriptor(int force);
char *router_dump_router_to_string(routerinfo_t *router,