commit 18174fb82f236dd2c8c841f61cfe3d53697be2f8 Author: teor teor@torproject.org Date: Thu Apr 30 15:38:41 2020 +1000
relay: Add an address family to self-test launches
Add an address family argument to the functions that launch relay ORPort self-test circuits.
Part of 33222. --- src/feature/nodelist/routerinfo.c | 27 ++++++++++++++++++++++----- src/feature/nodelist/routerinfo.h | 5 +++-- src/feature/relay/selftest.c | 24 ++++++++++++++++++------ 3 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/src/feature/nodelist/routerinfo.c b/src/feature/nodelist/routerinfo.c index 0bf2a977f..d2462a53d 100644 --- a/src/feature/nodelist/routerinfo.c +++ b/src/feature/nodelist/routerinfo.c @@ -17,14 +17,31 @@ #include "feature/nodelist/node_st.h" #include "feature/nodelist/routerinfo_st.h"
-/** Copy the primary (IPv4) OR port (IP address and TCP port) for - * <b>router</b> into *<b>ap_out</b>. */ +/** Copy the OR port (IP address and TCP port) for <b>router</b> and + * <b>family</b> into *<b>ap_out</b>. + * + * If the requested ORPort does not exist, sets *<b>ap_out</b> to the null + * address and port. You can check the returned value using + * tor_addr_port_is_valid_ap(ap_out, 0). */ void -router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *ap_out) +router_get_orport(const routerinfo_t *router, + tor_addr_port_t *ap_out, + int family) { tor_assert(ap_out != NULL); - tor_addr_from_ipv4h(&ap_out->addr, router->addr); - ap_out->port = router->or_port; + if (family == AF_INET) { + tor_addr_from_ipv4h(&ap_out->addr, router->addr); + ap_out->port = router->or_port; + } else if (family == AF_INET6) { + /* If there is no IPv6 address, ipv6_addr will be the null address and + * port. */ + tor_addr_copy(&ap_out->addr, &router->ipv6_addr); + ap_out->port = router->ipv6_orport; + } else { + /* Unsupported address family */ + tor_assert_nonfatal_unreached(); + tor_addr_port_make_null_ap(ap_out, AF_UNSPEC); + } }
int diff --git a/src/feature/nodelist/routerinfo.h b/src/feature/nodelist/routerinfo.h index 604e47899..47601a131 100644 --- a/src/feature/nodelist/routerinfo.h +++ b/src/feature/nodelist/routerinfo.h @@ -12,8 +12,9 @@ #ifndef TOR_ROUTERINFO_H #define TOR_ROUTERINFO_H
-void router_get_prim_orport(const routerinfo_t *router, - tor_addr_port_t *addr_port_out); +void router_get_orport(const routerinfo_t *router, + tor_addr_port_t *addr_port_out, + int family); int router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport);
diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c index 79d56a0bc..5fc23b7e1 100644 --- a/src/feature/relay/selftest.c +++ b/src/feature/relay/selftest.c @@ -127,15 +127,23 @@ router_should_check_reachability(int test_or, int test_dir) }
/** Allocate and return a new extend_info_t that can be used to build - * a circuit to or through the router <b>r</b>. Uses the primary - * address of the router, so should only be called on a server. */ + * a circuit to or through the router <b>r</b>, using an address from + * <b>family</b> (if available). + * + * Clients don't have routerinfos, so this function should only be called on a + * server. + * + * If the requested address is not available, returns NULL. */ static extend_info_t * -extend_info_from_router(const routerinfo_t *r) +extend_info_from_router(const routerinfo_t *r, int family) { crypto_pk_t *rsa_pubkey; extend_info_t *info; tor_addr_port_t ap; - tor_assert(r); + + if (BUG(!r)) { + return NULL; + }
/* Relays always assume that the first hop is reachable. They ignore * ReachableAddresses. */ @@ -147,7 +155,11 @@ extend_info_from_router(const routerinfo_t *r) else ed_id_key = NULL;
- router_get_prim_orport(r, &ap); + router_get_orport(r, &ap, family); + if (!tor_addr_port_is_valid_ap(&ap, 0)) { + /* We don't have an ORPort for the requested family. */ + return NULL; + } rsa_pubkey = router_get_rsa_onion_pkey(r->onion_pkey, r->onion_pkey_len); info = extend_info_new(r->nickname, r->cache_info.identity_digest, ed_id_key, @@ -178,7 +190,7 @@ router_do_reachability_checks(int test_or, int test_dir)
if (router_should_check_reachability(test_or, test_dir)) { if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) { - extend_info_t *ei = extend_info_from_router(me); + extend_info_t *ei = extend_info_from_router(me, AF_INET); /* XXX IPv6 self testing */ log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.", !orport_reachable ? "reachability" : "bandwidth",