From 4cce8ab742999900a4c5f1f3f8faf13d217014e0 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 9 May 2012 17:58:01 +0200 Subject: [PATCH] Add last_reachable and testing_since for IPv6 OR port. --- src/or/connection_or.c | 2 +- src/or/dirserv.c | 42 +++++++++++++++++++++++++++++++----------- src/or/dirserv.h | 2 +- src/or/nodelist.c | 4 ++-- src/or/or.h | 14 +++++++++----- src/or/router.c | 20 ++++++++++++++++++++ src/or/router.h | 2 ++ src/or/routerlist.c | 4 +++- 8 files changed, 69 insertions(+), 21 deletions(-) diff --git a/src/or/connection_or.c b/src/or/connection_or.c index d016387935..55ea32e57b 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -1540,7 +1540,7 @@ connection_or_client_learned_peer_id(or_connection_t *conn, return -1; } if (authdir_mode_tests_reachability(options)) { - dirserv_orconn_tls_done(conn->_base.address, conn->_base.port, + dirserv_orconn_tls_done(&conn->_base.addr, conn->_base.port, (const char*)peer_id); } diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 3518d9ea57..ad3c45da7b 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -3273,14 +3273,15 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key, * Inform the reachability checker that we could get to this guy. */ void -dirserv_orconn_tls_done(const char *address, +dirserv_orconn_tls_done(const tor_addr_t *addr, uint16_t or_port, const char *digest_rcvd) { node_t *node = NULL; + tor_addr_port_t orport; routerinfo_t *ri = NULL; time_t now = time(NULL); - tor_assert(address); + tor_assert(addr); tor_assert(digest_rcvd); node = node_get_mutable_by_id(digest_rcvd); @@ -3288,22 +3289,26 @@ dirserv_orconn_tls_done(const char *address, return; ri = node->ri; - if (!strcasecmp(address, ri->address) && or_port == ri->or_port) { + tor_addr_copy(&orport.addr, addr); + orport.port = or_port; + if (router_has_orport(ri, &orport)) { /* Found the right router. */ if (!authdir_mode_bridge(get_options()) || ri->purpose == ROUTER_PURPOSE_BRIDGE) { + char addrstr[TOR_ADDR_BUF_LEN]; /* This is a bridge or we're not a bridge authorititative -- mark it as reachable. */ - tor_addr_t addr, *addrp=NULL; log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.", router_describe(ri), - address, ri->or_port); - if (tor_addr_parse(&addr, ri->address) != -1) - addrp = &addr; - else - log_warn(LD_BUG, "Couldn't parse IP address \"%s\"", ri->address); - rep_hist_note_router_reachable(digest_rcvd, addrp, or_port, now); - node->last_reachable = now; + tor_addr_to_str(addrstr, addr, sizeof(addrstr), 1), + ri->or_port); + if (tor_addr_family(addr) == AF_INET) { + rep_hist_note_router_reachable(digest_rcvd, addr, or_port, now); + node->last_reachable = now; + } else if (tor_addr_family(addr) == AF_INET6) { + /* No rephist for IPv6. */ + node->last_reachable6 = now; + } } } } @@ -3345,6 +3350,8 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router) tor_assert(router); node = node_get_mutable_by_id(router->cache_info.identity_digest); tor_assert(node); + + /* IPv4. */ log_debug(LD_OR,"Testing reachability of %s at %s:%u.", router->nickname, router->address, router->or_port); /* Remember when we started trying to determine reachability */ @@ -3353,6 +3360,19 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router) tor_addr_from_ipv4h(&router_addr, router->addr); connection_or_connect(&router_addr, router->or_port, router->cache_info.identity_digest); + + /* Possible IPv6. */ + if (!tor_addr_is_null(&router->ipv6_addr)) { + char addrstr[TOR_ADDR_BUF_LEN]; + log_debug(LD_OR, "Testing reachability of %s at %s:%u.", + router->nickname, + tor_addr_to_str(addrstr, &router->ipv6_addr, sizeof(addrstr), 1), + router->ipv6_orport); + if (!node->testing_since6) + node->testing_since6 = now; + connection_or_connect(&router->ipv6_addr, router->ipv6_orport, + router->cache_info.identity_digest); + } } /** Auth dir server only: load balance such that we only diff --git a/src/or/dirserv.h b/src/or/dirserv.h index 22269b2009..8508c938a8 100644 --- a/src/or/dirserv.h +++ b/src/or/dirserv.h @@ -107,7 +107,7 @@ int dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key, int is_extrainfo); int dirserv_get_routerdescs(smartlist_t *descs_out, const char *key, const char **msg); -void dirserv_orconn_tls_done(const char *address, +void dirserv_orconn_tls_done(const tor_addr_t *addr, uint16_t or_port, const char *digest_rcvd); int dirserv_should_launch_reachability_test(const routerinfo_t *ri, diff --git a/src/or/nodelist.c b/src/or/nodelist.c index 1e07c82e35..cb94173985 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -139,8 +139,8 @@ nodelist_replace_routerinfo(routerinfo_t *old, routerinfo_t *new) if (!routers_have_same_or_addr(old, new)) { /* These mustn't carry over when the address and orport change. */ - node->last_reachable = 0; - node->testing_since = 0; + node->last_reachable = node->last_reachable6 = 0; + node->testing_since = node->testing_since6 = 0; } } } else { diff --git a/src/or/or.h b/src/or/or.h index a330f770e8..0684b9d6fe 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1997,13 +1997,13 @@ typedef struct node_t { routerstatus_t *rs; /* local info: copied from routerstatus, then possibly frobbed based - * on experience. Authorities set this stuff directly. */ + * on experience. Authorities set this stuff directly. Note that + * these reflect knowledge of the primary (IPv4) OR port only. */ unsigned int is_running:1; /**< As far as we know, is this OR currently * running? */ unsigned int is_valid:1; /**< Has a trusted dirserver validated this OR? - * (For Authdir: Have we validated this OR?) - */ + * (For Authdir: Have we validated this OR?) */ unsigned int is_fast:1; /** Do we think this is a fast OR? */ unsigned int is_stable:1; /** Do we think this is a stable OR? */ unsigned int is_possible_guard:1; /**< Do we think this is an OK guard? */ @@ -2027,15 +2027,19 @@ typedef struct node_t { /* Local info: derived. */ /** According to the geoip db what country is this router in? */ + /* XXXprop186 what is this suppose to mean with multiple OR ports? */ country_t country; /* The below items are used only by authdirservers for * reachability testing. */ /** When was the last time we could reach this OR? */ - time_t last_reachable; /* IPv4 */ + time_t last_reachable; /* IPv4. */ + time_t last_reachable6; /* IPv6. */ + /** When did we start testing reachability for this OR? */ - time_t testing_since; /* IPv4 */ + time_t testing_since; /* IPv4. */ + time_t testing_since6; /* IPv6. */ } node_t; /** How many times will we try to download a router's descriptor before giving diff --git a/src/or/router.c b/src/or/router.c index df44a76d8a..20767d8a3f 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -2230,6 +2230,26 @@ router_get_pref_ipv6_orport(const routerinfo_t *router, ap_out->port = router->ipv6_orport; } +/** Return 1 if any of router's addresses are addr. + * Otherwise return 0. */ +int +router_has_addr(const routerinfo_t *router, const tor_addr_t *addr) +{ + return + tor_addr_eq_ipv4h(addr, router->addr) || + tor_addr_eq(&router->ipv6_addr, addr); +} + +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->ipv6_addr) && + orport->port == router->ipv6_orport); +} + /** Load the contents of filename, find the last line starting with * end_line, ensure that its timestamp is not more than 25 hours in * the past or more than 1 hour in the future with respect to now, diff --git a/src/or/router.h b/src/or/router.h index 69805d6f2d..81df183953 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -93,6 +93,8 @@ void router_get_pref_orport(const routerinfo_t *router, void router_get_pref_ipv6_orport(const routerinfo_t *router, tor_addr_port_t *addr_port_out); int router_ipv6_preferred(const routerinfo_t *router); +int router_has_addr(const routerinfo_t *router, const tor_addr_t *addr); +int router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport); int extrainfo_dump_to_string(char **s, extrainfo_t *extrainfo, crypto_pk_t *ident_key); int is_legal_nickname(const char *s); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index f984d93e8e..cc47299fce 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1345,7 +1345,9 @@ mark_all_trusteddirservers_up(void) int routers_have_same_or_addr(const routerinfo_t *r1, const routerinfo_t *r2) { - return r1->addr == r2->addr && r1->or_port == r2->or_port; + return r1->addr == r2->addr && r1->or_port == r2->or_port && + tor_addr_eq(&r1->ipv6_addr, &r2->ipv6_addr) && + r1->ipv6_orport == r2->ipv6_orport; } /** Reset all internal variables used to count failed downloads of network