diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuituse.c | 6 | ||||
-rw-r--r-- | src/or/control.c | 5 | ||||
-rw-r--r-- | src/or/directory.c | 93 | ||||
-rw-r--r-- | src/or/directory.h | 6 | ||||
-rw-r--r-- | src/or/dirserv.c | 32 | ||||
-rw-r--r-- | src/or/dirserv.h | 2 | ||||
-rw-r--r-- | src/or/dnsserv.c | 4 | ||||
-rw-r--r-- | src/or/networkstatus.c | 3 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/rendservice.c | 15 | ||||
-rw-r--r-- | src/or/router.c | 15 | ||||
-rw-r--r-- | src/or/routerlist.c | 67 |
12 files changed, 171 insertions, 79 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 31003ea095..a4b580104f 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1674,7 +1674,11 @@ circuit_launch(uint8_t purpose, int flags) return circuit_launch_by_extend_info(purpose, NULL, flags); } -/* DOCDOC */ +/* Do we have enough descriptors to build paths? + * If need_exit is true, return 1 if we can build exit paths. + * (We need at least one Exit in the consensus to build exit paths.) + * If need_exit is false, return 1 if we can build internal paths. + */ static int have_enough_path_info(int need_exit) { diff --git a/src/or/control.c b/src/or/control.c index 655b4dd335..e06d7d28a2 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -2011,6 +2011,11 @@ getinfo_helper_dir(control_connection_t *control_conn, char *filename = get_datadir_fname("cached-consensus"); *answer = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL); tor_free(filename); + if (!*answer) { /* generate an error */ + *errmsg = "Could not open cached consensus. " + "Make sure FetchUselessDescriptors is set to 1."; + return -1; + } } } else if (!strcmp(question, "network-status")) { /* v1 */ routerlist_t *routerlist = router_get_routerlist(); diff --git a/src/or/directory.c b/src/or/directory.c index ab9f738e84..8dc018a662 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -630,7 +630,7 @@ directory_choose_address_routerstatus(const routerstatus_t *status, tor_assert(use_or_ap != NULL); tor_assert(use_dir_ap != NULL); - const int anonymized_connection = dirind_is_anon(indirection); + const or_options_t *options = get_options(); int have_or = 0, have_dir = 0; /* We expect status to have at least one reachable address if we're @@ -652,13 +652,16 @@ directory_choose_address_routerstatus(const routerstatus_t *status, tor_addr_make_null(&use_dir_ap->addr, AF_UNSPEC); use_dir_ap->port = 0; - if (anonymized_connection) { - /* Use the primary (IPv4) OR address if we're making an indirect - * connection. */ - tor_addr_from_ipv4h(&use_or_ap->addr, status->addr); - use_or_ap->port = status->or_port; - have_or = 1; - } else { + /* ORPort connections */ + if (indirection == DIRIND_ANONYMOUS) { + if (status->addr) { + /* Since we're going to build a 3-hop circuit and ask the 2nd relay + * to extend to this address, always use the primary (IPv4) OR address */ + tor_addr_from_ipv4h(&use_or_ap->addr, status->addr); + use_or_ap->port = status->or_port; + have_or = 1; + } + } else if (indirection == DIRIND_ONEHOP) { /* We use an IPv6 address if we have one and we prefer it. * Use the preferred address and port if they are reachable, otherwise, * use the alternate address and port (if any). @@ -668,9 +671,16 @@ directory_choose_address_routerstatus(const routerstatus_t *status, use_or_ap); } - have_dir = fascist_firewall_choose_address_rs(status, - FIREWALL_DIR_CONNECTION, 0, - use_dir_ap); + /* DirPort connections + * DIRIND_ONEHOP uses ORPort, but may fall back to the DirPort on relays */ + if (indirection == DIRIND_DIRECT_CONN || + indirection == DIRIND_ANON_DIRPORT || + (indirection == DIRIND_ONEHOP + && !directory_must_use_begindir(options))) { + have_dir = fascist_firewall_choose_address_rs(status, + FIREWALL_DIR_CONNECTION, 0, + use_dir_ap); + } /* We rejected all addresses in the relay's status. This means we can't * connect to it. */ @@ -956,6 +966,16 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status) update_certificate_downloads(time(NULL)); } +/* Should this tor instance only use begindir for all its directory requests? + */ +int +directory_must_use_begindir(const or_options_t *options) +{ + /* Clients, onion services, and bridges must use begindir, + * relays and authorities do not have to */ + return !public_server_mode(options); +} + /** Evaluate the situation and decide if we should use an encrypted * "begindir-style" connection for this directory request. * 1) If or_port is 0, or it's a direct conn and or_port is firewalled @@ -963,23 +983,48 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status) * 2) If we prefer to avoid begindir conns, and we're not fetching or * publishing a bridge relay descriptor, no. * 3) Else yes. + * If returning 0, return in *reason why we can't use begindir. + * reason must not be NULL. */ static int directory_command_should_use_begindir(const or_options_t *options, const tor_addr_t *addr, int or_port, uint8_t router_purpose, - dir_indirection_t indirection) + dir_indirection_t indirection, + const char **reason) { (void) router_purpose; - if (!or_port) + tor_assert(reason); + *reason = NULL; + + /* Reasons why we can't possibly use begindir */ + if (!or_port) { + *reason = "directory with unknown ORPort"; return 0; /* We don't know an ORPort -- no chance. */ - if (indirection == DIRIND_DIRECT_CONN || indirection == DIRIND_ANON_DIRPORT) + } + if (indirection == DIRIND_DIRECT_CONN || + indirection == DIRIND_ANON_DIRPORT) { + *reason = "DirPort connection"; return 0; - if (indirection == DIRIND_ONEHOP) + } + if (indirection == DIRIND_ONEHOP) { + /* We're firewalled and want a direct OR connection */ if (!fascist_firewall_allows_address_addr(addr, or_port, - FIREWALL_OR_CONNECTION, 0, 0) || - directory_fetches_from_authorities(options)) - return 0; /* We're firewalled or are acting like a relay -- also no. */ + FIREWALL_OR_CONNECTION, 0, 0)) { + *reason = "ORPort not reachable"; + return 0; + } + } + /* Reasons why we want to avoid using begindir */ + if (indirection == DIRIND_ONEHOP) { + if (!directory_must_use_begindir(options)) { + *reason = "in relay mode"; + return 0; + } + } + /* DIRIND_ONEHOP on a client, or DIRIND_ANONYMOUS + */ + *reason = "(using begindir)"; return 1; } @@ -1062,11 +1107,13 @@ directory_initiate_command_rend(const tor_addr_port_t *or_addr_port, dir_connection_t *conn; const or_options_t *options = get_options(); int socket_error = 0; + const char *begindir_reason = NULL; /* Should the connection be to a relay's OR port (and inside that we will * send our directory request)? */ const int use_begindir = directory_command_should_use_begindir(options, &or_addr_port->addr, or_addr_port->port, - router_purpose, indirection); + router_purpose, indirection, + &begindir_reason); /* Will the connection go via a three-hop Tor circuit? Note that this * is separate from whether it will use_begindir. */ const int anonymized_connection = dirind_is_anon(indirection); @@ -1092,6 +1139,14 @@ directory_initiate_command_rend(const tor_addr_port_t *or_addr_port, (void)is_sensitive_dir_purpose; #endif + /* use encrypted begindir connections for everything except relays + * this provides better protection for directory fetches */ + if (!use_begindir && directory_must_use_begindir(options)) { + log_warn(LD_BUG, "Client could not use begindir connection: %s", + begindir_reason ? begindir_reason : "(NULL)"); + return; + } + /* ensure that we don't make direct connections when a SOCKS server is * configured. */ if (!anonymized_connection && !use_begindir && !options->HTTPProxy && diff --git a/src/or/directory.h b/src/or/directory.h index 03c04c10c9..c4edbb5c0f 100644 --- a/src/or/directory.h +++ b/src/or/directory.h @@ -28,8 +28,8 @@ void directory_get_from_all_authorities(uint8_t dir_purpose, /** Enumeration of ways to connect to a directory server */ typedef enum { - /** Default: connect over a one-hop Tor circuit but fall back to direct - * connection */ + /** Default: connect over a one-hop Tor circuit. Relays fall back to direct + * DirPort connections, clients, onion services, and bridges do not */ DIRIND_ONEHOP=0, /** Connect over a multi-hop anonymizing Tor circuit */ DIRIND_ANONYMOUS=1, @@ -39,6 +39,8 @@ typedef enum { DIRIND_ANON_DIRPORT, } dir_indirection_t; +int directory_must_use_begindir(const or_options_t *options); + MOCK_DECL(void, directory_initiate_command_routerstatus, (const routerstatus_t *status, uint8_t dir_purpose, diff --git a/src/or/dirserv.c b/src/or/dirserv.c index a045f3ac55..3e1f48062c 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1424,13 +1424,13 @@ router_counts_toward_thresholds(const node_t *node, time_t now, * * Also, set the is_exit flag of each router appropriately. */ static void -dirserv_compute_performance_thresholds(const smartlist_t *routers, - digestmap_t *omit_as_sybil) +dirserv_compute_performance_thresholds(digestmap_t *omit_as_sybil) { int n_active, n_active_nonexit, n_familiar; uint32_t *uptimes, *bandwidths_kb, *bandwidths_excluding_exits_kb; long *tks; double *mtbfs, *wfus; + smartlist_t *nodelist; time_t now = time(NULL); const or_options_t *options = get_options(); @@ -1448,27 +1448,28 @@ dirserv_compute_performance_thresholds(const smartlist_t *routers, guard_tk = 0; guard_wfu = 0; + nodelist_assert_ok(); + nodelist = nodelist_get_list(); + /* Initialize arrays that will hold values for each router. We'll * sort them and use that to compute thresholds. */ n_active = n_active_nonexit = 0; /* Uptime for every active router. */ - uptimes = tor_calloc(smartlist_len(routers), sizeof(uint32_t)); + uptimes = tor_calloc(smartlist_len(nodelist), sizeof(uint32_t)); /* Bandwidth for every active router. */ - bandwidths_kb = tor_calloc(smartlist_len(routers), sizeof(uint32_t)); + bandwidths_kb = tor_calloc(smartlist_len(nodelist), sizeof(uint32_t)); /* Bandwidth for every active non-exit router. */ bandwidths_excluding_exits_kb = - tor_calloc(smartlist_len(routers), sizeof(uint32_t)); + tor_calloc(smartlist_len(nodelist), sizeof(uint32_t)); /* Weighted mean time between failure for each active router. */ - mtbfs = tor_calloc(smartlist_len(routers), sizeof(double)); + mtbfs = tor_calloc(smartlist_len(nodelist), sizeof(double)); /* Time-known for each active router. */ - tks = tor_calloc(smartlist_len(routers), sizeof(long)); + tks = tor_calloc(smartlist_len(nodelist), sizeof(long)); /* Weighted fractional uptime for each active router. */ - wfus = tor_calloc(smartlist_len(routers), sizeof(double)); - - nodelist_assert_ok(); + wfus = tor_calloc(smartlist_len(nodelist), sizeof(double)); /* Now, fill in the arrays. */ - SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) { + SMARTLIST_FOREACH_BEGIN(nodelist, node_t *, node) { if (options->BridgeAuthoritativeDir && node->ri && node->ri->purpose != ROUTER_PURPOSE_BRIDGE) @@ -1544,7 +1545,7 @@ dirserv_compute_performance_thresholds(const smartlist_t *routers, * fill wfus with the wfu of every such "familiar" router. */ n_familiar = 0; - SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) { + SMARTLIST_FOREACH_BEGIN(nodelist, node_t *, node) { if (router_counts_toward_thresholds(node, now, omit_as_sybil, require_mbw)) { routerinfo_t *ri = node->ri; @@ -1598,11 +1599,10 @@ dirserv_compute_performance_thresholds(const smartlist_t *routers, * networkstatus_getinfo_by_purpose(). */ void -dirserv_compute_bridge_flag_thresholds(const smartlist_t *routers) +dirserv_compute_bridge_flag_thresholds(void) { - digestmap_t *omit_as_sybil = digestmap_new(); - dirserv_compute_performance_thresholds(routers, omit_as_sybil); + dirserv_compute_performance_thresholds(omit_as_sybil); digestmap_free(omit_as_sybil, NULL); } @@ -2873,7 +2873,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, * this must come before dirserv_compute_performance_thresholds() */ dirserv_count_measured_bws(routers); - dirserv_compute_performance_thresholds(routers, omit_as_sybil); + dirserv_compute_performance_thresholds(omit_as_sybil); routerstatuses = smartlist_new(); microdescriptors = smartlist_new(); diff --git a/src/or/dirserv.h b/src/or/dirserv.h index 3e735db071..9a9725ad6f 100644 --- a/src/or/dirserv.h +++ b/src/or/dirserv.h @@ -50,7 +50,7 @@ int list_server_status_v1(smartlist_t *routers, char **router_status_out, int dirserv_dump_directory_to_string(char **dir_out, crypto_pk_t *private_key); char *dirserv_get_flag_thresholds_line(void); -void dirserv_compute_bridge_flag_thresholds(const smartlist_t *routers); +void dirserv_compute_bridge_flag_thresholds(void); int directory_fetches_from_authorities(const or_options_t *options); int directory_fetches_dir_info_early(const or_options_t *options); diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index 8ddb414fe5..74f17ce78c 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -88,8 +88,6 @@ evdns_server_callback(struct evdns_server_request *req, void *data_) for (i = 0; i < req->nquestions; ++i) { if (req->questions[i]->dns_question_class != EVDNS_CLASS_INET) continue; - if (! q) - q = req->questions[i]; switch (req->questions[i]->type) { case EVDNS_TYPE_A: case EVDNS_TYPE_AAAA: @@ -97,7 +95,7 @@ evdns_server_callback(struct evdns_server_request *req, void *data_) /* We always pick the first one of these questions, if there is one. */ if (! supported_q) - supported_q = q; + supported_q = req->questions[i]; break; default: break; diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 3967f56edd..185708a0c1 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -2043,11 +2043,10 @@ networkstatus_dump_bridge_status_to_file(time_t now) char *fname = NULL; char *thresholds = NULL; char *published_thresholds_and_status = NULL; - routerlist_t *rl = router_get_routerlist(); char published[ISO_TIME_LEN+1]; format_iso_time(published, now); - dirserv_compute_bridge_flag_thresholds(rl->routers); + dirserv_compute_bridge_flag_thresholds(); thresholds = dirserv_get_flag_thresholds_line(); tor_asprintf(&published_thresholds_and_status, "published %s\nflag-thresholds %s\n%s", diff --git a/src/or/or.h b/src/or/or.h index 592f29502e..6694bb4ece 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2215,7 +2215,7 @@ typedef struct routerstatus_t { /** Digest of the router's most recent descriptor or microdescriptor. * If it's a descriptor, we only use the first DIGEST_LEN bytes. */ char descriptor_digest[DIGEST256_LEN]; - uint32_t addr; /**< IPv4 address for this router. */ + uint32_t addr; /**< IPv4 address for this router, in host order. */ uint16_t or_port; /**< OR port for this router. */ uint16_t dir_port; /**< Directory port for this router. */ tor_addr_t ipv6_addr; /**< IPv6 address for this router. */ diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 39e5831589..6f41f3b968 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1445,6 +1445,7 @@ rend_service_receive_introduction(origin_circuit_t *circuit, int status = 0, result; const or_options_t *options = get_options(); char *err_msg = NULL; + int err_msg_severity = LOG_WARN; const char *stage_descr = NULL; int reason = END_CIRC_REASON_TORPROTOCOL; /* Service/circuit/key stuff we can learn before parsing */ @@ -1596,8 +1597,10 @@ rend_service_receive_introduction(origin_circuit_t *circuit, /* Find the rendezvous point */ rp = find_rp_for_intro(parsed_req, &err_msg); - if (!rp) + if (!rp) { + err_msg_severity = LOG_PROTOCOL_WARN; goto log_error; + } /* Check if we'd refuse to talk to this router */ if (options->StrictNodes && @@ -1735,7 +1738,7 @@ rend_service_receive_introduction(origin_circuit_t *circuit, } } - log_warn(LD_REND, "%s on circ %u", err_msg, + log_fn(err_msg_severity, LD_REND, "%s on circ %u", err_msg, (unsigned)circuit->base_.n_circ_id); err: status = -1; @@ -1797,7 +1800,7 @@ find_rp_for_intro(const rend_intro_cell_t *intro, if (!rp) { if (err_msg_out) { tor_asprintf(&err_msg, - "Could build extend_info_t for router %s named " + "Couldn't build extend_info_t for router %s named " "in INTRODUCE2 cell", escaped_safe_str_client(rp_nickname)); } @@ -1833,8 +1836,10 @@ find_rp_for_intro(const rend_intro_cell_t *intro, goto done; err: - if (err_msg_out) *err_msg_out = err_msg; - else tor_free(err_msg); + if (err_msg_out) + *err_msg_out = err_msg; + else + tor_free(err_msg); done: return rp; diff --git a/src/or/router.c b/src/or/router.c index 68bcf1326e..3f94703a26 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1549,8 +1549,10 @@ proxy_mode(const or_options_t *options) * and * - We have ORPort set * and - * - We believe both our ORPort and DirPort (if present) are reachable from + * - We believe our ORPort and DirPort (if present) are reachable from * the outside; or + * - We believe our ORPort is reachable from the outside, and we can't + * check our DirPort because the consensus has no exits; or * - We are an authoritative directory server. */ static int @@ -1568,8 +1570,15 @@ decide_if_publishable_server(void) return 1; if (!router_get_advertised_or_port(options)) return 0; - - return check_whether_orport_reachable() && check_whether_dirport_reachable(); + if (!check_whether_orport_reachable()) + return 0; + if (router_have_consensus_path() == CONSENSUS_PATH_INTERNAL) { + /* All set: there are no exits in the consensus (maybe this is a tiny + * test network), so we can't check our DirPort reachability. */ + return 1; + } else { + return check_whether_dirport_reachable(); + } } /** Initiate server descriptor upload as reasonable (if server is publishable, diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 3c9023e8f0..d40d704a1d 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -148,6 +148,22 @@ get_n_authorities(dirinfo_type_t type) return n; } +/** Initialise schedule, want_authority, and increment on in the download + * status dlstatus, then call download_status_reset() on it. + * It is safe to call this function or download_status_reset() multiple times + * on a new dlstatus. But it should *not* be called after a dlstatus has been + * used to count download attempts or failures. */ +static void +download_status_cert_init(download_status_t *dlstatus) +{ + dlstatus->schedule = DL_SCHED_CONSENSUS; + dlstatus->want_authority = DL_WANT_ANY_DIRSERVER; + dlstatus->increment_on = DL_SCHED_INCREMENT_FAILURE; + + /* Use the new schedule to set next_attempt_at */ + download_status_reset(dlstatus); +} + /** Reset the download status of a specified element in a dsmap */ static void download_status_reset_by_sk_in_cl(cert_list_t *cl, const char *digest) @@ -168,6 +184,7 @@ download_status_reset_by_sk_in_cl(cert_list_t *cl, const char *digest) /* Insert before we reset */ dlstatus = tor_malloc_zero(sizeof(*dlstatus)); dsmap_set(cl->dl_status_map, digest, dlstatus); + download_status_cert_init(dlstatus); } tor_assert(dlstatus); /* Go ahead and reset it */ @@ -206,7 +223,7 @@ download_status_is_ready_by_sk_in_cl(cert_list_t *cl, * too. */ dlstatus = tor_malloc_zero(sizeof(*dlstatus)); - download_status_reset(dlstatus); + download_status_cert_init(dlstatus); dsmap_set(cl->dl_status_map, digest, dlstatus); rv = 1; } @@ -225,7 +242,7 @@ get_cert_list(const char *id_digest) cl = digestmap_get(trusted_dir_certs, id_digest); if (!cl) { cl = tor_malloc_zero(sizeof(cert_list_t)); - cl->dl_status_by_id.schedule = DL_SCHED_CONSENSUS; + download_status_cert_init(&cl->dl_status_by_id); cl->certs = smartlist_new(); cl->dl_status_map = dsmap_new(); digestmap_set(trusted_dir_certs, id_digest, cl); @@ -896,7 +913,8 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now) if (smartlist_len(fps) > 1) { resource = smartlist_join_strings(fps, "", 0, NULL); - /* XXX - do we want certs from authorities or mirrors? - teor */ + /* We want certs from mirrors, because they will almost always succeed. + */ directory_get_from_dirserver(DIR_PURPOSE_FETCH_CERTIFICATE, 0, resource, PDS_RETRY_IF_NO_SERVERS, DL_WANT_ANY_DIRSERVER); @@ -942,7 +960,8 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now) if (smartlist_len(fp_pairs) > 1) { resource = smartlist_join_strings(fp_pairs, "", 0, NULL); - /* XXX - do we want certs from authorities or mirrors? - teor */ + /* We want certs from mirrors, because they will almost always succeed. + */ directory_get_from_dirserver(DIR_PURPOSE_FETCH_CERTIFICATE, 0, resource, PDS_RETRY_IF_NO_SERVERS, DL_WANT_ANY_DIRSERVER); @@ -1597,11 +1616,10 @@ router_picked_poor_directory_log(const routerstatus_t *rs) STMT_BEGIN \ if (result == NULL && try_ip_pref && options->ClientUseIPv4 \ && fascist_firewall_use_ipv6(options) && !server_mode(options) \ - && n_not_preferred && !n_busy) { \ + && !n_busy) { \ n_excluded = 0; \ n_busy = 0; \ try_ip_pref = 0; \ - n_not_preferred = 0; \ goto retry_label; \ } \ STMT_END \ @@ -1620,7 +1638,6 @@ router_picked_poor_directory_log(const routerstatus_t *rs) n_excluded = 0; \ n_busy = 0; \ try_ip_pref = 1; \ - n_not_preferred = 0; \ goto retry_label; \ } \ STMT_END @@ -1673,7 +1690,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags, const int no_microdesc_fetching = (flags & PDS_NO_EXISTING_MICRODESC_FETCH); const int for_guard = (flags & PDS_FOR_GUARD); int try_excluding = 1, n_excluded = 0, n_busy = 0; - int try_ip_pref = 1, n_not_preferred = 0; + int try_ip_pref = 1; if (!consensus) return NULL; @@ -1687,8 +1704,9 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags, overloaded_direct = smartlist_new(); overloaded_tunnel = smartlist_new(); - const int skip_or = router_skip_or_reachability(options, try_ip_pref); - const int skip_dir = router_skip_dir_reachability(options, try_ip_pref); + const int skip_or_fw = router_skip_or_reachability(options, try_ip_pref); + const int skip_dir_fw = router_skip_dir_reachability(options, try_ip_pref); + const int must_have_or = directory_must_use_begindir(options); /* Find all the running dirservers we know about. */ SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) { @@ -1740,18 +1758,16 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags, * address for each router (if any). (To ensure correct load-balancing * we try routers that only have one address both times.) */ - if (!fascistfirewall || skip_or || - fascist_firewall_allows_rs(status, FIREWALL_OR_CONNECTION, - try_ip_pref)) + if (!fascistfirewall || skip_or_fw || + fascist_firewall_allows_node(node, FIREWALL_OR_CONNECTION, + try_ip_pref)) smartlist_add(is_trusted ? trusted_tunnel : is_overloaded ? overloaded_tunnel : tunnel, (void*)node); - else if (skip_dir || - fascist_firewall_allows_rs(status, FIREWALL_DIR_CONNECTION, - try_ip_pref)) + else if (!must_have_or && (skip_dir_fw || + fascist_firewall_allows_node(node, FIREWALL_DIR_CONNECTION, + try_ip_pref))) smartlist_add(is_trusted ? trusted_direct : is_overloaded ? overloaded_direct : direct, (void*)node); - else if (!tor_addr_is_null(&status->ipv6_addr)) - ++n_not_preferred; } SMARTLIST_FOREACH_END(node); if (smartlist_len(tunnel)) { @@ -1839,7 +1855,7 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist, smartlist_t *pick_from; int n_busy = 0; int try_excluding = 1, n_excluded = 0; - int try_ip_pref = 1, n_not_preferred = 0; + int try_ip_pref = 1; if (!sourcelist) return NULL; @@ -1851,8 +1867,9 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist, overloaded_direct = smartlist_new(); overloaded_tunnel = smartlist_new(); - const int skip_or = router_skip_or_reachability(options, try_ip_pref); - const int skip_dir = router_skip_dir_reachability(options, try_ip_pref); + const int skip_or_fw = router_skip_or_reachability(options, try_ip_pref); + const int skip_dir_fw = router_skip_dir_reachability(options, try_ip_pref); + const int must_have_or = directory_must_use_begindir(options); SMARTLIST_FOREACH_BEGIN(sourcelist, const dir_server_t *, d) { @@ -1888,16 +1905,14 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist, * address for each router (if any). (To ensure correct load-balancing * we try routers that only have one address both times.) */ - if (!fascistfirewall || skip_or || + if (!fascistfirewall || skip_or_fw || fascist_firewall_allows_dir_server(d, FIREWALL_OR_CONNECTION, try_ip_pref)) smartlist_add(is_overloaded ? overloaded_tunnel : tunnel, (void*)d); - else if (skip_dir || + else if (!must_have_or && (skip_dir_fw || fascist_firewall_allows_dir_server(d, FIREWALL_DIR_CONNECTION, - try_ip_pref)) + try_ip_pref))) smartlist_add(is_overloaded ? overloaded_direct : direct, (void*)d); - else if (!tor_addr_is_null(&d->ipv6_addr)) - ++n_not_preferred; } SMARTLIST_FOREACH_END(d); |