diff options
-rw-r--r-- | src/or/circuitbuild.c | 17 | ||||
-rw-r--r-- | src/or/or.h | 4 | ||||
-rw-r--r-- | src/or/rendservice.c | 2 | ||||
-rw-r--r-- | src/or/routerlist.c | 43 |
4 files changed, 40 insertions, 26 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 83a7eb522..c67d29d14 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1157,13 +1157,13 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime, // router->nickname, i); continue; /* skip routers that are known to be down */ } - if (router_is_unreliable(router, need_uptime, need_capacity)) { + if (router_is_unreliable(router, need_uptime, need_capacity, 0)) { n_supported[i] = -1; continue; /* skip routers that are not suitable */ } if (!router->is_verified && (!(options->_AllowUnverified & ALLOW_UNVERIFIED_EXIT) || - router_is_unreliable(router, 1, 1))) { + router_is_unreliable(router, 1, 1, 0))) { /* if it's unverified, and either we don't want it or it's unsuitable */ n_supported[i] = -1; // log_fn(LOG_DEBUG,"Skipping node %s (index %d) -- unverified router.", @@ -1303,14 +1303,14 @@ choose_good_exit_server(uint8_t purpose, routerlist_t *dir, case CIRCUIT_PURPOSE_C_GENERAL: if (is_internal) /* pick it like a middle hop */ return router_choose_random_node(NULL, get_options()->ExcludeNodes, - NULL, need_uptime, need_capacity, + NULL, need_uptime, need_capacity, 0, get_options()->_AllowUnverified & ALLOW_UNVERIFIED_MIDDLE, 0); else return choose_good_exit_server_general(dir,need_uptime,need_capacity); case CIRCUIT_PURPOSE_C_ESTABLISH_REND: return router_choose_random_node( options->RendNodes, options->RendExcludeNodes, - NULL, need_uptime, need_capacity, + NULL, need_uptime, need_capacity, 0, options->_AllowUnverified & ALLOW_UNVERIFIED_RENDEZVOUS, 0); } warn(LD_BUG,"Bug: unhandled purpose %d", purpose); @@ -1479,7 +1479,7 @@ choose_good_middle_server(uint8_t purpose, } choice = router_choose_random_node( NULL, get_options()->ExcludeNodes, excluded, - state->need_uptime, state->need_capacity, + state->need_uptime, state->need_capacity, 0, get_options()->_AllowUnverified & ALLOW_UNVERIFIED_MIDDLE, 0); smartlist_free(excluded); return choice; @@ -1529,8 +1529,9 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state) // but only if there are enough other nodes available. choice = router_choose_random_node( NULL, options->ExcludeNodes, - excluded, state ? state->need_uptime : 1, - state ? state->need_capacity : 1, + excluded, state ? state->need_uptime : 0, + state ? state->need_capacity : 0, + state ? 0 : 1, options->_AllowUnverified & ALLOW_UNVERIFIED_ENTRY, 0); smartlist_free(excluded); return choice; @@ -1710,7 +1711,7 @@ entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity) r = router_get_by_digest(e->identity); if (!r) return NULL; - if (router_is_unreliable(r, need_uptime, need_capacity)) + if (router_is_unreliable(r, need_uptime, need_capacity, 0)) return NULL; if (firewall_is_fascist() && !fascist_firewall_allows_address(r->addr,r->or_port)) diff --git a/src/or/or.h b/src/or/or.h index 47c1901ec..b4e71ff87 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -809,6 +809,7 @@ typedef struct { * us? */ 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? */ /* The below items are used only by authdirservers for * reachability testing. */ @@ -2271,12 +2272,13 @@ routerinfo_t *router_find_exact_exit_enclave(const char *address, #define ROUTER_REQUIRED_MIN_BANDWIDTH 10000 int router_is_unreliable(routerinfo_t *router, int need_uptime, - int need_capacity); + int need_capacity, int need_guard); routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl); routerinfo_t *router_choose_random_node(const char *preferred, const char *excluded, smartlist_t *excludedsmartlist, int need_uptime, int need_bandwidth, + int need_guard, int allow_unverified, int strict); routerinfo_t *router_get_by_nickname(const char *nickname, int warn_if_unnamed); diff --git a/src/or/rendservice.c b/src/or/rendservice.c index a9f9c9d1d..7881d3ffc 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -992,7 +992,7 @@ rend_services_introduce(void) for (j=prev_intro_nodes; j < NUM_INTRO_POINTS; ++j) { char *hex_digest; router = router_choose_random_node(service->intro_prefer_nodes, - service->intro_exclude_nodes, exclude_routers, 1, 0, + service->intro_exclude_nodes, exclude_routers, 1, 0, 0, get_options()->_AllowUnverified & ALLOW_UNVERIFIED_INTRODUCTION, 0); if (!router) { diff --git a/src/or/routerlist.c b/src/or/routerlist.c index df56fe64c..3151bd7cd 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -643,7 +643,8 @@ router_nickname_is_in_list(routerinfo_t *router, const char *list) */ static void router_add_running_routers_to_smartlist(smartlist_t *sl, int allow_unverified, - int need_uptime, int need_capacity) + int need_uptime, int need_capacity, + int need_guard) { if (!routerlist) return; @@ -653,7 +654,8 @@ router_add_running_routers_to_smartlist(smartlist_t *sl, int allow_unverified, if (router->is_running && (router->is_verified || (allow_unverified && - !router_is_unreliable(router, need_uptime, need_capacity)))) { + !router_is_unreliable(router, need_uptime, + need_capacity, need_guard)))) { /* If it's running, and either it's verified or we're ok picking * unverified routers and this one is suitable. */ @@ -709,25 +711,30 @@ router_find_exact_exit_enclave(const char *address, uint16_t port) * bandwidth. */ int -router_is_unreliable(routerinfo_t *router, int need_uptime, int need_capacity) +router_is_unreliable(routerinfo_t *router, int need_uptime, + int need_capacity, int need_guard) { if (need_uptime && !router->is_stable) return 1; if (need_capacity && !router->is_fast) return 1; + if (need_guard && !router->is_possible_guard) + return 1; return 0; } -/** Remove from routerlist <b>sl</b> all routers who have a low uptime. */ +/** Remove from routerlist <b>sl</b> all routers that are not + * sufficiently stable. */ static void -routerlist_sl_remove_unreliable_routers(smartlist_t *sl) +routerlist_sl_remove_unreliable_routers(smartlist_t *sl, + int need_uptime, int need_guard) { int i; routerinfo_t *router; for (i = 0; i < smartlist_len(sl); ++i) { router = smartlist_get(sl, i); - if (router_is_unreliable(router, 1, 0)) { + if (router_is_unreliable(router, need_uptime, 0, need_guard)) { // log(LOG_DEBUG, "Router '%s' has insufficient uptime; deleting.", // router->nickname); smartlist_del(sl, i--); @@ -801,6 +808,7 @@ router_choose_random_node(const char *preferred, const char *excluded, smartlist_t *excludedsmartlist, int need_uptime, int need_capacity, + int need_guard, int allow_unverified, int strict) { smartlist_t *sl, *excludednodes; @@ -809,8 +817,8 @@ router_choose_random_node(const char *preferred, excludednodes = smartlist_create(); add_nickname_list_to_smartlist(excludednodes,excluded,0,0,1); - /* Try the preferred nodes first. Ignore need_uptime and need_capacity, - * since the user explicitly asked for these nodes. */ + /* Try the preferred nodes first. Ignore need_uptime and need_capacity + * and need_guard, since the user explicitly asked for these nodes. */ if (preferred) { sl = smartlist_create(); add_nickname_list_to_smartlist(sl,preferred,1,1,1); @@ -825,25 +833,27 @@ router_choose_random_node(const char *preferred, * will do that has the required attributes. */ sl = smartlist_create(); router_add_running_routers_to_smartlist(sl, allow_unverified, - need_uptime, need_capacity); + need_uptime, need_capacity, + need_guard); smartlist_subtract(sl,excludednodes); if (excludedsmartlist) smartlist_subtract(sl,excludedsmartlist); - if (need_uptime) - routerlist_sl_remove_unreliable_routers(sl); + if (need_uptime || need_guard) + routerlist_sl_remove_unreliable_routers(sl, need_uptime, need_guard); if (need_capacity) choice = routerlist_sl_choose_by_bandwidth(sl); else choice = smartlist_choose(sl); smartlist_free(sl); - if (!choice && (need_uptime || need_capacity)) { + if (!choice && (need_uptime || need_capacity || need_guard)) { /* try once more -- recurse but with fewer restrictions. */ - info(LD_CIRC, "We couldn't find any live%s%s routers; falling back " + info(LD_CIRC, "We couldn't find any live%s%s%s routers; falling back " "to list of all routers.", need_capacity?", fast":"", - need_uptime?", stable":""); + need_uptime?", stable":"", + need_guard?", guard":""); choice = router_choose_random_node( - NULL, excluded, excludedsmartlist, 0, 0, allow_unverified, 0); + NULL, excluded, excludedsmartlist, 0, 0, 0, allow_unverified, 0); } } smartlist_free(excludednodes); @@ -2458,7 +2468,7 @@ router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port, SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router, { if (router->is_running && - !router_is_unreliable(router, need_uptime, 0)) { + !router_is_unreliable(router, need_uptime, 0, 0)) { r = router_compare_addr_to_addr_policy(addr, port, router->exit_policy); if (r != ADDR_POLICY_REJECTED && r != ADDR_POLICY_PROBABLY_REJECTED) return 0; /* this one could be ok. good enough. */ @@ -3203,6 +3213,7 @@ routers_update_status_from_networkstatus(smartlist_t *routers, router->is_running = rs->status.is_running; router->is_fast = rs->status.is_fast; router->is_stable = rs->status.is_stable; + router->is_possible_guard = rs->status.is_possible_guard; } if (router->is_running && ds) { ds->n_networkstatus_failures = 0; |