commit 0cf90bac2a7136e0abb9fed160f70c543ad8b88a
Author: teor (Tim Wilson-Brown) <teor2345(a)gmail.com>
Date: Thu Apr 28 16:03:23 2016 +1000
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.
---
changes/bug18921 | 4 ++++
src/or/directory.c | 30 +++++++++++++++++++-----------
2 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/changes/bug18921 b/changes/bug18921
new file mode 100644
index 0000000..934a604
--- /dev/null
+++ b/changes/bug18921
@@ -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".
diff --git a/src/or/directory.c b/src/or/directory.c
index ab9f738..ca3b3e3 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -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. */