diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 53f19f9beb..db0d7191a5 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1290,6 +1290,7 @@ dirserv_orconn_tls_done(const char *address, } else { /* correct nickname and digest. mark this router reachable! */ log_fn(LOG_INFO,"Found router %s to be reachable. Yay.", ri->nickname); ri->last_reachable = time(NULL); + ri->num_unreachable_notifications = 0; } } } diff --git a/src/or/or.h b/src/or/or.h index 8cd7573dfe..2c6220dbb7 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -750,8 +750,13 @@ typedef struct { /* The below items are used only by authdirservers for * reachability testing. */ - time_t last_reachable; /**< When was the last time we could reach this OR? */ - time_t testing_since; /**< When did we start testing reachability for this OR? */ + /** When was the last time we could reach this OR? */ + time_t last_reachable; + /** When did we start testing reachability for this OR? */ + time_t testing_since; + /** How many times has a descriptor been posted and we believed + * this router to be unreachable? We only actually warn on the third. */ + int num_unreachable_notifications; } routerinfo_t; /** Contents of a running-routers list */ diff --git a/src/or/routerlist.c b/src/or/routerlist.c index d765208765..9395d1cf3c 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -912,7 +912,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg) *msg = "Router descriptor was not new."; return -1; } else { - int unreachable; + int unreachable = 0; log_fn(LOG_DEBUG, "Replacing entry for router '%s/%s' [%s]", router->nickname, old_router->nickname, hex_str(id_digest,DIGEST_LEN)); @@ -921,13 +921,20 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg) /* these carry over when the address and orport are unchanged.*/ router->last_reachable = old_router->last_reachable; router->testing_since = old_router->testing_since; + router->num_unreachable_notifications = + old_router->num_unreachable_notifications; } - unreachable = authdir && - dirserv_thinks_router_is_blatantly_unreachable(router, time(NULL)); - if (unreachable) { - log_fn(LOG_WARN, "Notifying server '%s' that it's unreachable. (ContactInfo '%s', platform '%s').", - router->nickname, router->contact_info ? router->contact_info : "", - router->platform ? router->platform : ""); + if (authdir && + dirserv_thinks_router_is_blatantly_unreachable(router, time(NULL))) { + if (router->num_unreachable_notifications >= 3) { + unreachable = 1; + log_fn(LOG_WARN, "Notifying server '%s' that it's unreachable. (ContactInfo '%s', platform '%s').", + router->nickname, router->contact_info ? router->contact_info : "", + router->platform ? router->platform : ""); + } else { + log_fn(LOG_NOTICE,"'%s' may be unreachable -- the %d previous descriptors were thought to be unreachable.", router->nickname, router->num_unreachable_notifications); + router->num_unreachable_notifications++; + } } routerinfo_free(old_router); smartlist_set(routerlist->routers, i, router);