diff options
Diffstat (limited to 'src/feature/nodelist/routerinfo.c')
-rw-r--r-- | src/feature/nodelist/routerinfo.c | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/src/feature/nodelist/routerinfo.c b/src/feature/nodelist/routerinfo.c index 0bf2a977f5..eb8eb74daa 100644 --- a/src/feature/nodelist/routerinfo.c +++ b/src/feature/nodelist/routerinfo.c @@ -13,26 +13,50 @@ #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerinfo.h" +#include "feature/nodelist/torcert.h" #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>. */ -void -router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *ap_out) +/** 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, and returns -1. Otherwise, returns 0. */ +int +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_copy(&ap_out->addr, &router->ipv4_addr); + ap_out->port = router->ipv4_orport; + return 0; + } else if (family == AF_INET6) { + /* IPv6 addresses are optional, so check if it is valid. */ + if (tor_addr_port_is_valid(&router->ipv6_addr, router->ipv6_orport, 0)) { + tor_addr_copy(&ap_out->addr, &router->ipv6_addr); + ap_out->port = router->ipv6_orport; + return 0; + } else { + tor_addr_port_make_null_ap(ap_out, AF_INET6); + return -1; + } + } else { + /* Unsupported address family */ + tor_assert_nonfatal_unreached(); + tor_addr_port_make_null_ap(ap_out, AF_UNSPEC); + return -1; + } } int router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport) { return - (tor_addr_eq_ipv4h(&orport->addr, router->addr) && - orport->port == router->or_port) || + (tor_addr_eq(&orport->addr, &router->ipv4_addr) && + orport->port == router->ipv4_orport) || (tor_addr_eq(&orport->addr, &router->ipv6_addr) && orport->port == router->ipv6_orport); } @@ -52,6 +76,21 @@ router_get_all_orports(const routerinfo_t *ri) return node_get_all_orports(&fake_node); } +/** Return the Ed25519 identity key for this routerinfo, or NULL if it + * doesn't have one. */ +const ed25519_public_key_t * +routerinfo_get_ed25519_id(const routerinfo_t *ri) +{ + if (BUG(! ri)) + return NULL; + + const tor_cert_t *cert = ri->cache_info.signing_key_cert; + if (cert && ! ed25519_public_key_is_zero(&cert->signing_key)) + return &cert->signing_key; + else + return NULL; +} + /** Given a router purpose, convert it to a string. Don't call this on * ROUTER_PURPOSE_UNKNOWN: The whole point of that value is that we don't * know its string representation. */ |