Choose the correct address for one-hop connections

After #17840 in 0.2.8.1-alpha, we incorrectly chose an IPv4
address for all DIRIND_ONEHOP directory connections,
even if the routerstatus didn't have an IPv4 address.

This likely affected bridge clients with IPv6 bridges.

Resolves #18921.
This commit is contained in:
teor (Tim Wilson-Brown) 2016-04-28 16:03:23 +10:00 committed by Nick Mathewson
parent de08f2d96b
commit 0cf90bac2a
2 changed files with 23 additions and 11 deletions

4
changes/bug18921 Normal file
View File

@ -0,0 +1,4 @@
o Major bugfixes (IPv6 bridges):
- Fix directory address selection for IPv6 bridges.
Resolves #18921, bugfix on #17840 in 0.2.8.1-alpha.
Patch by "teor".

View File

@ -630,7 +630,6 @@ directory_choose_address_routerstatus(const routerstatus_t *status,
tor_assert(use_or_ap != NULL);
tor_assert(use_dir_ap != NULL);
const int anonymized_connection = dirind_is_anon(indirection);
int have_or = 0, have_dir = 0;
/* We expect status to have at least one reachable address if we're
@ -652,13 +651,16 @@ directory_choose_address_routerstatus(const routerstatus_t *status,
tor_addr_make_null(&use_dir_ap->addr, AF_UNSPEC);
use_dir_ap->port = 0;
if (anonymized_connection) {
/* Use the primary (IPv4) OR address if we're making an indirect
* connection. */
tor_addr_from_ipv4h(&use_or_ap->addr, status->addr);
use_or_ap->port = status->or_port;
have_or = 1;
} else {
/* ORPort connections */
if (indirection == DIRIND_ANONYMOUS) {
if (status->addr) {
/* Since we're going to build a 3-hop circuit and ask the 2nd relay
* to extend to this address, always use the primary (IPv4) OR address */
tor_addr_from_ipv4h(&use_or_ap->addr, status->addr);
use_or_ap->port = status->or_port;
have_or = 1;
}
} else if (indirection == DIRIND_ONEHOP) {
/* We use an IPv6 address if we have one and we prefer it.
* Use the preferred address and port if they are reachable, otherwise,
* use the alternate address and port (if any).
@ -668,9 +670,15 @@ directory_choose_address_routerstatus(const routerstatus_t *status,
use_or_ap);
}
have_dir = fascist_firewall_choose_address_rs(status,
FIREWALL_DIR_CONNECTION, 0,
use_dir_ap);
/* DirPort connections
* DIRIND_ONEHOP uses ORPort, but may fall back to the DirPort */
if (indirection == DIRIND_DIRECT_CONN ||
indirection == DIRIND_ANON_DIRPORT ||
indirection == DIRIND_ONEHOP) {
have_dir = fascist_firewall_choose_address_rs(status,
FIREWALL_DIR_CONNECTION, 0,
use_dir_ap);
}
/* We rejected all addresses in the relay's status. This means we can't
* connect to it. */