|
@@ -988,7 +988,7 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
|
|
|
answer = ! we_are_hibernating();
|
|
|
} else if (router->is_hibernating &&
|
|
|
(router->cache_info.published_on +
|
|
|
- HIBERNATION_PUBLICATION_SKEW) > router->last_reachable) {
|
|
|
+ HIBERNATION_PUBLICATION_SKEW) > node->last_reachable) {
|
|
|
/* A hibernating router is down unless we (somehow) had contact with it
|
|
|
* since it declared itself to be hibernating. */
|
|
|
answer = 0;
|
|
@@ -998,7 +998,7 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
|
|
|
} else {
|
|
|
/* Otherwise, a router counts as up if we found it reachable in the last
|
|
|
REACHABLE_TIMEOUT seconds. */
|
|
|
- answer = (now < router->last_reachable + REACHABLE_TIMEOUT);
|
|
|
+ answer = (now < node->last_reachable + REACHABLE_TIMEOUT);
|
|
|
}
|
|
|
|
|
|
if (!answer && running_long_enough_to_decide_unreachable()) {
|
|
@@ -1010,9 +1010,9 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
|
|
|
it.
|
|
|
*/
|
|
|
time_t when = now;
|
|
|
- if (router->last_reachable &&
|
|
|
- router->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD < now)
|
|
|
- when = router->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD;
|
|
|
+ if (node->last_reachable &&
|
|
|
+ node->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD < now)
|
|
|
+ when = node->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD;
|
|
|
rep_hist_note_router_unreachable(router->cache_info.identity_digest, when);
|
|
|
}
|
|
|
|
|
@@ -2088,6 +2088,21 @@ routerstatus_format_entry(char *buf, size_t buf_len,
|
|
|
return 0;
|
|
|
|
|
|
cp = buf + strlen(buf);
|
|
|
+
|
|
|
+ /* Possible "a" line, not included in consensus for now. */
|
|
|
+ if (!tor_addr_is_null(&rs->ipv6_addr)) {
|
|
|
+ const char *addr_str = fmt_and_decorate_addr(&rs->ipv6_addr);
|
|
|
+ r = tor_snprintf(cp, buf_len - (cp-buf),
|
|
|
+ "a %s:%d\n",
|
|
|
+ addr_str,
|
|
|
+ (int)rs->ipv6_orport);
|
|
|
+ if (r<0) {
|
|
|
+ log_warn(LD_BUG, "Not enough space in buffer.");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ cp += strlen(cp);
|
|
|
+ }
|
|
|
+
|
|
|
/* NOTE: Whenever this list expands, be sure to increase MAX_FLAG_LINE_LEN*/
|
|
|
r = tor_snprintf(cp, buf_len - (cp-buf),
|
|
|
"s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
|
@@ -2453,6 +2468,16 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
|
|
|
strlcpy(rs->nickname, ri->nickname, sizeof(rs->nickname));
|
|
|
rs->or_port = ri->or_port;
|
|
|
rs->dir_port = ri->dir_port;
|
|
|
+ if (options->AuthDirPublishIPv6 == 1 &&
|
|
|
+ !tor_addr_is_null(&ri->ipv6_addr) &&
|
|
|
+ (options->AuthDirHasIPv6Connectivity == 0 ||
|
|
|
+ node->last_reachable6 >= now - REACHABLE_TIMEOUT)) {
|
|
|
+ /* We're configured for publishing IPv6 OR ports. There's an IPv6
|
|
|
+ OR port and it's reachable (or we know that we're not on IPv6)
|
|
|
+ so copy it to the routerstatus. */
|
|
|
+ tor_addr_copy(&rs->ipv6_addr, &ri->ipv6_addr);
|
|
|
+ rs->ipv6_orport = ri->ipv6_orport;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/** Routerstatus <b>rs</b> is part of a group of routers that are on
|
|
@@ -3273,36 +3298,42 @@ 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)
|
|
|
{
|
|
|
- routerinfo_t *ri;
|
|
|
+ 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);
|
|
|
|
|
|
- ri = router_get_mutable_by_digest(digest_rcvd);
|
|
|
-
|
|
|
- if (ri == NULL)
|
|
|
+ node = node_get_mutable_by_id(digest_rcvd);
|
|
|
+ if (node == NULL || node->ri == NULL)
|
|
|
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);
|
|
|
- ri->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;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -3325,7 +3356,7 @@ dirserv_should_launch_reachability_test(const routerinfo_t *ri,
|
|
|
/* It just came out of hibernation; launch a reachability test */
|
|
|
return 1;
|
|
|
}
|
|
|
- if (! routers_have_same_or_addr(ri, ri_old)) {
|
|
|
+ if (! routers_have_same_or_addrs(ri, ri_old)) {
|
|
|
/* Address or port changed; launch a reachability test */
|
|
|
return 1;
|
|
|
}
|
|
@@ -3338,15 +3369,35 @@ dirserv_should_launch_reachability_test(const routerinfo_t *ri,
|
|
|
void
|
|
|
dirserv_single_reachability_test(time_t now, routerinfo_t *router)
|
|
|
{
|
|
|
+ node_t *node = NULL;
|
|
|
tor_addr_t router_addr;
|
|
|
+
|
|
|
+ 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 */
|
|
|
- if (!router->testing_since)
|
|
|
- router->testing_since = now;
|
|
|
+ if (!node->testing_since)
|
|
|
+ node->testing_since = now;
|
|
|
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
|