diff --git a/src/or/dirserv.c b/src/or/dirserv.c index b24b63014c..69b066ee31 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -484,6 +484,40 @@ list_single_server_status(routerinfo_t *desc, int is_live) #define REACHABLE_TIMEOUT (60*60) /* an hour */ /* Make sure this is 3 times the value of get_dir_fetch_period() */ +/** Treat a router as alive if + * - It's me, and I'm not hibernating. + * or - we're connected to it and we've found it reachable recently. */ +static int +dirserv_thinks_router_is_reachable(routerinfo_t *router, time_t now) +{ + connection_t *conn; + if (router_is_me(router) && !we_are_hibernating()) + return 1; + conn = connection_get_by_identity_digest(router->identity_digest, + CONN_TYPE_OR); + if (conn && conn->state == OR_CONN_STATE_OPEN) + return get_options()->AssumeReachable || + now < router->last_reachable + REACHABLE_TIMEOUT; + return 0; +} + +/** Return 1 if we're confident that there's a problem with + * router's reachability and its operator should be notified. + */ +static int +dirserv_thinks_router_is_blatantly_unreachable(routerinfo_t *router, time_t now) +{ + connection_t *conn; + conn = connection_get_by_identity_digest(router->identity_digest, + CONN_TYPE_OR); + if (conn && conn->state == OR_CONN_STATE_OPEN && + now >= router->last_reachable + 2*REACHABLE_TIMEOUT && + router->testing_since && + now >= router->testing_since + 2*REACHABLE_TIMEOUT) + return 1; + return 0; +} + /** Based on the routerinfo_ts in routers, allocate the * contents of a router-status line, and store it in * *router_status_out. Return 0 on success, -1 on failure. @@ -502,29 +536,14 @@ list_server_status(smartlist_t *routers, char **router_status_out) SMARTLIST_FOREACH(routers, routerinfo_t *, ri, { - int is_live = 0; - connection_t *conn; - conn = connection_get_by_identity_digest( - ri->identity_digest, CONN_TYPE_OR); if (authdir_mode) { - /* Treat a router as alive if - * - It's me, and I'm not hibernating. - * or - we're connected to it and we've found it reachable recently. */ - if (router_is_me(ri) && !we_are_hibernating()) { - is_live = 1; - } else if (conn && conn->state == OR_CONN_STATE_OPEN) { - is_live = get_options()->AssumeReachable || - now < ri->last_reachable + REACHABLE_TIMEOUT; - } /* Update router status in routerinfo_t. */ - ri->is_running = is_live; - } else { - is_live = ri->is_running; + ri->is_running = dirserv_thinks_router_is_reachable(ri, now); } - smartlist_add(rs_entries, list_single_server_status(ri, is_live)); + smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running)); }); - *router_status_out = smartlist_join_strings(rs_entries, " ", 0,NULL); + *router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL); SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp)); smartlist_free(rs_entries); @@ -544,35 +563,10 @@ dirserv_log_unreachable_servers(time_t now) SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, { - connection_t *conn; - conn = connection_get_by_identity_digest( - ri->identity_digest, CONN_TYPE_OR); - if (conn && conn->state == OR_CONN_STATE_OPEN && - now >= ri->last_reachable + 2*REACHABLE_TIMEOUT && - ri->testing_since && - now >= ri->testing_since + 2*REACHABLE_TIMEOUT) { + if (dirserv_thinks_router_is_blatantly_unreachable(ri, now)) log_fn(LOG_NOTICE, "Router %s (%s:%d) is connected to us but not reachable by us.", ri->nickname, ri->address, ri->or_port); - } - }); -} - -/** Record the fact that we've started trying to determine reachability - * for the router with identity digest. - * (This function can go away when we merge descriptor-list and router-list.) - */ -void -dirserv_router_has_begun_reachability_testing(char *digest, time_t now) -{ - smartlist_t *descriptor_list = get_descriptor_list(); - if (!descriptor_list) - return; - SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, - { - if (!memcmp(ri->identity_digest, digest, DIGEST_LEN)) - if (!ri->testing_since) - ri->testing_since = now; }); } diff --git a/src/or/or.h b/src/or/or.h index 31f3828172..6b07ffedcf 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1633,7 +1633,6 @@ char *dirserver_getinfo_unregistered(const char *question); void dirserv_free_descriptors(void); int list_server_status(smartlist_t *routers, char **router_status_out); void dirserv_log_unreachable_servers(time_t now); -void dirserv_router_has_begun_reachability_testing(char *digest, time_t now); int dirserv_dump_directory_to_string(char **dir_out, crypto_pk_env_t *private_key); void directory_set_dirty(void); diff --git a/src/or/router.c b/src/or/router.c index 6a719652e5..27d8154ea2 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -606,7 +606,9 @@ router_retry_connections(int force) log_fn(LOG_INFO,"%sconnecting to %s at %s:%u.", clique_mode(options) ? "(forced) " : "", router->nickname, router->address, router->or_port); - dirserv_router_has_begun_reachability_testing(router->identity_digest, now); + /* Remember when we started trying to determine reachability */ + if (!router->testing_since) + router->testing_since = now; connection_or_connect(router->addr, router->or_port, router->identity_digest); } }