Skip to content

Commit

Permalink
Merge cebfeb9 into 06c31b1
Browse files Browse the repository at this point in the history
  • Loading branch information
nmathewson committed Aug 12, 2020
2 parents 06c31b1 + cebfeb9 commit 6106d6b
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 7 deletions.
6 changes: 6 additions & 0 deletions changes/bug20165
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 2 additions & 0 deletions src/core/or/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/core/or/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/core/or/channeltls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 17 additions & 7 deletions src/feature/relay/circuitbuild_relay.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/feature/relay/router.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *,
Expand Down
1 change: 1 addition & 0 deletions src/feature/relay/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 6106d6b

Please sign in to comment.