diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuitbuild.c | 66 | ||||
-rw-r--r-- | src/or/circuituse.c | 36 | ||||
-rw-r--r-- | src/or/config.c | 43 | ||||
-rw-r--r-- | src/or/directory.c | 6 | ||||
-rw-r--r-- | src/or/or.h | 32 | ||||
-rw-r--r-- | src/or/rendservice.c | 6 | ||||
-rw-r--r-- | src/or/routerlist.c | 41 |
7 files changed, 151 insertions, 79 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 103b5888b..d7e00581b 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -21,8 +21,9 @@ extern circuit_t *global_circuitlist; static int circuit_deliver_create_cell(circuit_t *circ, char *payload); -static cpath_build_state_t *onion_new_cpath_build_state(uint8_t purpose, - const char *exit_digest); +static cpath_build_state_t * +onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest, + int need_uptime, int need_capacity); static int onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t *state, routerinfo_t **router_out); static int count_acceptable_routers(smartlist_t *routers); @@ -233,15 +234,17 @@ void circuit_dump_by_conn(connection_t *conn, int severity) { * Also launch a connection to the first OR in the chosen path, if * it's not open already. */ -circuit_t *circuit_establish_circuit(uint8_t purpose, - const char *exit_digest) { +circuit_t * +circuit_establish_circuit(uint8_t purpose, const char *exit_digest, + int need_uptime, int need_capacity) { routerinfo_t *firsthop; connection_t *n_conn; circuit_t *circ; circ = circuit_new(0, NULL); /* sets circ->p_circ_id and circ->p_conn */ circ->state = CIRCUIT_STATE_OR_WAIT; - circ->build_state = onion_new_cpath_build_state(purpose, exit_digest); + circ->build_state = onion_new_cpath_build_state(purpose, exit_digest, + need_uptime, need_capacity); circ->purpose = purpose; if (! circ->build_state) { @@ -811,13 +814,24 @@ circuit_get_unhandled_ports(time_t now) { /** Return 1 if we already have circuits present or on the way for * all anticipated ports. Return 0 if we should make more. + * + * If we're returning 0, set need_uptime and need_capacity to + * indicate any requirements that the unhandled ports have. */ int -circuit_all_predicted_ports_handled(time_t now) { - int enough; +circuit_all_predicted_ports_handled(time_t now, int *need_uptime, + int *need_capacity) { + int i, enough; + uint16_t *port; smartlist_t *sl = circuit_get_unhandled_ports(now); + smartlist_t *LongLivedServices = get_options()->LongLivedPorts; enough = (smartlist_len(sl) == 0); - SMARTLIST_FOREACH(sl, uint16_t *, cp, tor_free(cp)); + for (i = 0; i < smartlist_len(sl); ++i) { + port = smartlist_get(sl, i); + if (smartlist_string_num_isin(LongLivedServices, *port)) + *need_uptime = 1; + tor_free(port); + } smartlist_free(sl); return enough; } @@ -853,7 +867,9 @@ router_handles_some_port(routerinfo_t *router, smartlist_t *needed_ports) { * * Return NULL if we can't find any suitable routers. */ -static routerinfo_t *choose_good_exit_server_general(routerlist_t *dir) +static routerinfo_t * +choose_good_exit_server_general(routerlist_t *dir, int need_uptime, + int need_capacity) { int *n_supported; int i, j; @@ -905,9 +921,13 @@ static routerinfo_t *choose_good_exit_server_general(routerlist_t *dir) // router->nickname, i); continue; /* skip routers that are known to be down */ } + if (router_is_unreliable(router, need_uptime, need_capacity)) { + n_supported[i] = -1; + continue; /* skip routers that are not suitable */ + } if (!router->is_verified && (!(options->_AllowUnverified & ALLOW_UNVERIFIED_EXIT) || - router_is_unreliable_router(router, 1, 1))) { + router_is_unreliable(router, 1, 1))) { /* 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.", @@ -1035,16 +1055,19 @@ static routerinfo_t *choose_good_exit_server_general(routerlist_t *dir) * For client-side rendezvous circuits, choose a random node, weighted * toward the preferences in 'options'. */ -static routerinfo_t *choose_good_exit_server(uint8_t purpose, routerlist_t *dir) +static routerinfo_t * +choose_good_exit_server(uint8_t purpose, routerlist_t *dir, + int need_uptime, int need_capacity) { routerinfo_t *r; or_options_t *options = get_options(); switch (purpose) { case CIRCUIT_PURPOSE_C_GENERAL: - return choose_good_exit_server_general(dir); + return choose_good_exit_server_general(dir, need_uptime, need_capacity); case CIRCUIT_PURPOSE_C_ESTABLISH_REND: r = router_choose_random_node(options->RendNodes, options->RendExcludeNodes, - NULL, 0, 1, options->_AllowUnverified & ALLOW_UNVERIFIED_RENDEZVOUS, 0); + NULL, need_uptime, need_capacity, + options->_AllowUnverified & ALLOW_UNVERIFIED_RENDEZVOUS, 0); return r; } log_fn(LOG_WARN,"Bug: unhandled purpose %d", purpose); @@ -1056,7 +1079,8 @@ static routerinfo_t *choose_good_exit_server(uint8_t purpose, routerlist_t *dir) * return it. */ static cpath_build_state_t * -onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest) +onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest, + int need_uptime, int need_capacity) { routerlist_t *rl; int r; @@ -1071,6 +1095,8 @@ onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest) return NULL; info = tor_malloc_zero(sizeof(cpath_build_state_t)); info->desired_path_len = r; + info->need_uptime = need_uptime; + info->need_capacity = need_capacity; if (exit_digest) { /* the circuit-builder pre-requested one */ memcpy(info->chosen_exit_digest, exit_digest, DIGEST_LEN); exit = router_get_by_digest(exit_digest); @@ -1083,7 +1109,7 @@ onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest) } log_fn(LOG_INFO,"Using requested exit node '%s'", info->chosen_exit_name); } else { /* we have to decide one */ - exit = choose_good_exit_server(purpose, rl); + exit = choose_good_exit_server(purpose, rl, need_uptime, need_capacity); if (!exit) { log_fn(LOG_WARN,"failed to choose an exit server"); tor_free(info); @@ -1169,7 +1195,8 @@ static routerinfo_t *choose_good_middle_server(cpath_build_state_t *state, } } choice = router_choose_random_node(NULL, get_options()->ExcludeNodes, excluded, - 0, 1, get_options()->_AllowUnverified & ALLOW_UNVERIFIED_MIDDLE, 0); + state->need_uptime, state->need_capacity, + get_options()->_AllowUnverified & ALLOW_UNVERIFIED_MIDDLE, 0); smartlist_free(excluded); return choice; } @@ -1179,7 +1206,6 @@ static routerinfo_t *choose_good_entry_server(cpath_build_state_t *state) routerinfo_t *r, *choice; smartlist_t *excluded = smartlist_create(); or_options_t *options = get_options(); - char buf[16]; if ((r = router_get_by_digest(state->chosen_exit_digest))) { smartlist_add(excluded, r); @@ -1200,13 +1226,13 @@ static routerinfo_t *choose_good_entry_server(cpath_build_state_t *state) for (i=0; i < smartlist_len(rl->routers); i++) { r = smartlist_get(rl->routers, i); - tor_snprintf(buf, sizeof(buf), "%d", r->or_port); - if (!smartlist_string_isin(options->FirewallPorts, buf)) + if (!smartlist_string_num_isin(options->FirewallPorts, r->or_port)) smartlist_add(excluded, r); } } choice = router_choose_random_node(options->EntryNodes, options->ExcludeNodes, - excluded, 0, 1, options->_AllowUnverified & ALLOW_UNVERIFIED_ENTRY, + excluded, state->need_uptime, state->need_capacity, + options->_AllowUnverified & ALLOW_UNVERIFIED_ENTRY, options->StrictEntryNodes); smartlist_free(excluded); return choice; diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 2e7169b7c..783fc20ad 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -78,6 +78,11 @@ static int circuit_is_acceptable(circuit_t *circ, return 0; /* this circuit is screwed and doesn't know it yet */ } + if (!circ->build_state->need_uptime && + smartlist_string_num_isin(get_options()->LongLivedPorts, + conn->socks_request->port)) + return 0; + if (conn->socks_request && conn->socks_request->command == SOCKS_COMMAND_RESOLVE) { /* 0.0.8 servers have buggy resolve support. */ @@ -311,6 +316,7 @@ int circuit_stream_is_being_handled(connection_t *conn, uint16_t port, int min) void circuit_build_needed_circs(time_t now) { static long time_to_new_circuit = 0; circuit_t *circ; + int need_uptime=0, need_capacity=1; /* launch a new circ for any pending streams that need one */ connection_ap_attach_pending(); @@ -332,7 +338,7 @@ void circuit_build_needed_circs(time_t now) { circ && circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) { log_fn(LOG_INFO,"Creating a new testing circuit."); - circuit_launch_by_identity(CIRCUIT_PURPOSE_C_GENERAL, NULL); + circuit_launch_by_identity(CIRCUIT_PURPOSE_C_GENERAL, NULL, 0, 0); } } @@ -353,8 +359,9 @@ void circuit_build_needed_circs(time_t now) { /* if we know of a port that's been requested recently and no * circuit is currently available that can handle it, start one * for that too. */ - if (!circuit_all_predicted_ports_handled(now)) { - circuit_launch_by_identity(CIRCUIT_PURPOSE_C_GENERAL, NULL); + if (!circuit_all_predicted_ports_handled(now, &need_uptime, &need_capacity)) { + circuit_launch_by_identity(CIRCUIT_PURPOSE_C_GENERAL, NULL, + need_uptime, need_capacity); } /* XXX count idle rendezvous circs and build more */ @@ -637,7 +644,9 @@ static int did_circs_fail_last_period = 0; * success. */ #define MAX_CIRCUIT_FAILURES 5 -circuit_t *circuit_launch_by_identity(uint8_t purpose, const char *exit_digest) +circuit_t * +circuit_launch_by_identity(uint8_t purpose, const char *exit_digest, + int need_uptime, int need_capacity) { if (!has_fetched_directory) { log_fn(LOG_DEBUG,"Haven't fetched directory yet; canceling circuit launch."); @@ -652,11 +661,14 @@ circuit_t *circuit_launch_by_identity(uint8_t purpose, const char *exit_digest) } /* try a circ. if it fails, circuit_mark_for_close will increment n_circuit_failures */ - return circuit_establish_circuit(purpose, exit_digest); + return circuit_establish_circuit(purpose, exit_digest, + need_uptime, need_capacity); } /** Launch a new circuit and return a pointer to it. Return NULL if you failed. */ -circuit_t *circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname) +circuit_t * +circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname, + int need_uptime, int need_capacity) { const char *digest = NULL; @@ -668,7 +680,8 @@ circuit_t *circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname } digest = r->identity_digest; } - return circuit_launch_by_identity(purpose, digest); + return circuit_launch_by_identity(purpose, digest, + need_uptime, need_capacity); } /** Record another failure at opening a general circuit. When we have @@ -704,6 +717,7 @@ circuit_get_open_circ_or_launch(connection_t *conn, circuit_t *circ; uint32_t addr; int is_resolve; + int need_uptime; tor_assert(conn); tor_assert(circp); @@ -729,10 +743,14 @@ circuit_get_open_circ_or_launch(connection_t *conn, return 0; } + need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts, + conn->socks_request->port); + /* Do we need to check exit policy? */ if (!is_resolve && !connection_edge_is_rendezvous_stream(conn)) { addr = client_dns_lookup_entry(conn->socks_request->address); - if (router_exit_policy_all_routers_reject(addr, conn->socks_request->port)) { + if (router_exit_policy_all_routers_reject(addr, conn->socks_request->port, + need_uptime)) { log_fn(LOG_NOTICE,"No Tor server exists that allows exit to %s:%d. Rejecting.", conn->socks_request->address, conn->socks_request->port); return -1; @@ -783,7 +801,7 @@ circuit_get_open_circ_or_launch(connection_t *conn, else new_circ_purpose = desired_circuit_purpose; - circ = circuit_launch_by_nickname(new_circ_purpose, exitname); + circ = circuit_launch_by_nickname(new_circ_purpose, exitname, need_uptime, 1); tor_free(exitname); if (circ && diff --git a/src/or/config.c b/src/or/config.c index 4a0e8f4fb..f1fab0e32 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -53,6 +53,7 @@ static config_abbrev_t config_abbrevs[] = { PLURAL(EntryNode), PLURAL(ExcludeNode), PLURAL(FirewallPort), + PLURAL(LongLivedPort), PLURAL(HiddenServiceNode), PLURAL(HiddenServiceExcludeNode), PLURAL(RendNode), @@ -149,6 +150,7 @@ static config_var_t config_vars[] = { VAR("ORBindAddress", LINELIST, ORBindAddress, NULL), VAR("OutboundBindAddress", STRING, OutboundBindAddress, NULL), VAR("PidFile", STRING, PidFile, NULL), + VAR("LongLivedPorts", CSV, LongLivedPorts, "22,6667"), VAR("PathlenCoinWeight", DOUBLE, PathlenCoinWeight, "0.3"), VAR("RedirectExit", LINELIST, RedirectExit, NULL), OBSOLETE("RouterFile"), @@ -1137,13 +1139,32 @@ config_dump_options(or_options_t *options, int minimal) return result; } +static int +validate_ports_csv(smartlist_t *sl, char *name) { + int i; + int result = 0; + tor_assert(name); + + if(!sl) + return 0; + + SMARTLIST_FOREACH(sl, const char *, cp, + { + i = atoi(cp); + if (i < 1 || i > 65535) { + log(LOG_WARN, "Port '%s' out of range in %s", cp, name); + result=-1; + } + }); + return result; +} + /** Return 0 if every setting in <b>options</b> is reasonable. Else * warn and return -1. Should have no side effects, except for * normalizing the contents of <b>options</b>. */ static int options_validate(or_options_t *options) { - int i; int result = 0; struct config_line_t *cl; addr_policy_t *addr_policy=NULL; @@ -1261,16 +1282,14 @@ options_validate(or_options_t *options) options->_AccountingMaxKB = 0; } - if (options->FirewallPorts) { - SMARTLIST_FOREACH(options->FirewallPorts, const char *, cp, - { - i = atoi(cp); - if (i < 1 || i > 65535) { - log(LOG_WARN, "Port '%s' out of range in FirewallPorts", cp); - result=-1; - } - }); - } + if (validate_ports_csv(options->FirewallPorts, + "FirewallPorts") < 0) + result = -1; + + if (validate_ports_csv(options->LongLivedPorts, + "LongLivedPorts") < 0) + result = -1; + options->_AllowUnverified = 0; if (options->AllowUnverifiedNodes) { SMARTLIST_FOREACH(options->AllowUnverifiedNodes, const char *, cp, { @@ -1287,7 +1306,7 @@ options_validate(or_options_t *options) else { log(LOG_WARN, "Unrecognized value '%s' in AllowUnverifiedNodes", cp); - result=-1; + result = -1; } }); } diff --git a/src/or/directory.c b/src/or/directory.c index 05e354ac7..1b6550591 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -116,7 +116,6 @@ directory_post_to_dirservers(uint8_t purpose, const char *payload, size_t payload_len) { smartlist_t *dirservers; - char buf[16]; router_get_trusted_dir_servers(&dirservers); tor_assert(dirservers); @@ -130,8 +129,7 @@ directory_post_to_dirservers(uint8_t purpose, const char *payload, * descriptor -- those use Tor. */ if (get_options()->FascistFirewall && purpose == DIR_PURPOSE_UPLOAD_DIR && !get_options()->HttpProxy) { - tor_snprintf(buf,sizeof(buf),"%d",ds->dir_port); - if (!smartlist_string_isin(get_options()->FirewallPorts, buf)) + if (!smartlist_string_num_isin(get_options()->FirewallPorts, ds->dir_port)) continue; } directory_initiate_command_trusted_dir(ds, purpose, NULL, @@ -244,7 +242,7 @@ connection_dir_connect_failed(connection_t *conn) } } -/** Helper for directory_initiate_command(router|trusted_dir): send the +/** Helper for directory_initiate_command_(router|trusted_dir): send the * command to a server whose address is <b>address</b>, whose IP is * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version is * <b>platform</b>, and whose identity key digest is <b>digest</b>. The diff --git a/src/or/or.h b/src/or/or.h index e5fe36966..bde4c2cf4 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -722,6 +722,10 @@ typedef struct { char *chosen_exit_name; /** Identity of planned exit node. */ char chosen_exit_digest[DIGEST_LEN]; + /** Whether every node in the circ must have adequate uptime. */ + int need_uptime; + /** Whether every node in the circ must have adequate capacity. */ + int need_capacity; /** The crypt_path_t to append after rendezvous: used for rendezvous. */ struct crypt_path_t *pending_final_cpath; /** How many times has building a circuit for this task failed? */ @@ -930,7 +934,9 @@ typedef struct { * directory recommends. */ int RunAsDaemon; /**< If true, run in the background. (Unix only) */ int FascistFirewall; /**< Whether to prefer ORs reachable on open ports. */ - smartlist_t *FirewallPorts; /** Which ports our firewall allows. */ + smartlist_t *FirewallPorts; /**< Which ports our firewall allows (strings). */ + /** Application ports that require all nodes in circ to have sufficient uptime. */ + smartlist_t *LongLivedPorts; int DirFetchPeriod; /**< How often do we fetch new directories? */ int DirPostPeriod; /**< How often do we post our server descriptor to the * authoritative directory servers? */ @@ -1040,8 +1046,8 @@ char *circuit_list_path(circuit_t *circ, int verbose); void circuit_log_path(int severity, circuit_t *circ); void circuit_rep_hist_note_result(circuit_t *circ); void circuit_dump_by_conn(connection_t *conn, int severity); -circuit_t *circuit_establish_circuit(uint8_t purpose, - const char *exit_digest); +circuit_t *circuit_establish_circuit(uint8_t purpose, const char *exit_digest, + int need_uptime, int need_capacity); void circuit_n_conn_done(connection_t *or_conn, int status); int circuit_send_next_onion_skin(circuit_t *circ); int circuit_extend(cell_t *cell, circuit_t *circ); @@ -1049,7 +1055,9 @@ int circuit_init_cpath_crypto(crypt_path_t *cpath, char *key_data, int reverse); int circuit_finish_handshake(circuit_t *circ, char *reply); int circuit_truncated(circuit_t *circ, crypt_path_t *layer); int onionskin_answer(circuit_t *circ, unsigned char *payload, unsigned char *keys); -int circuit_all_predicted_ports_handled(time_t now); +int circuit_all_predicted_ports_handled(time_t now, int *need_uptime, + int *need_capacity); + void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop); /********************************* circuitlist.c ***********************/ @@ -1092,8 +1100,10 @@ void circuit_detach_stream(circuit_t *circ, connection_t *conn); void circuit_about_to_close_connection(connection_t *conn); void circuit_has_opened(circuit_t *circ); void circuit_build_failed(circuit_t *circ); -circuit_t *circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname); -circuit_t *circuit_launch_by_identity(uint8_t purpose, const char *exit_digest); +circuit_t *circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname, + int need_uptime, int need_capacity); +circuit_t *circuit_launch_by_identity(uint8_t purpose, const char *exit_digest, + int need_uptime, int need_capacity); void circuit_reset_failure_count(int timeout); int connection_ap_handshake_attach_circuit(connection_t *conn); @@ -1592,15 +1602,15 @@ int router_nickname_matches(routerinfo_t *router, const char *nickname); /** How many seconds a router must be up before we'll use it for * reliability-critical node positions. */ -#define ROUTER_REQUIRED_MIN_UPTIME 3600 /* an hour */ +#define ROUTER_REQUIRED_MIN_UPTIME (24*3600) /* a day */ #define ROUTER_REQUIRED_MIN_BANDWIDTH 10000 -int router_is_unreliable_router(routerinfo_t *router, int need_uptime, int need_bw); +int router_is_unreliable(routerinfo_t *router, int need_uptime, int need_capacity); routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl); routerinfo_t *router_choose_random_node(const char *preferred, const char *excluded, struct smartlist_t *excludedsmartlist, - int preferuptime, int preferbandwidth, + int need_uptime, int need_bandwidth, int allow_unverified, int strict); routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port); routerinfo_t *router_get_by_nickname(const char *nickname); @@ -1621,7 +1631,9 @@ int router_compare_addr_to_addr_policy(uint32_t addr, uint16_t port, #define ADDR_POLICY_ACCEPTED 0 #define ADDR_POLICY_REJECTED -1 #define ADDR_POLICY_UNKNOWN 1 -int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port); +int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port, + int need_uptime); + int router_exit_policy_rejects_all(routerinfo_t *router); void running_routers_free(running_routers_t *rr); void routerlist_update_from_runningrouters(routerlist_t *list, diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 019614b60..023ebd4ab 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -459,7 +459,7 @@ rend_service_introduce(circuit_t *circuit, const char *request, size_t request_l /* Launch a circuit to alice's chosen rendezvous point. */ for (i=0;i<MAX_REND_FAILURES;i++) { - launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_CONNECT_REND, rp_nickname); + launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_CONNECT_REND, rp_nickname, 0, 1); if (launched) break; } @@ -524,7 +524,7 @@ rend_service_relaunch_rendezvous(circuit_t *oldcirc) oldstate->chosen_exit_name); newcirc = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_CONNECT_REND, - oldstate->chosen_exit_name); + oldstate->chosen_exit_name, 0, 1); if (!newcirc) { log_fn(LOG_WARN,"Couldn't relaunch rendezvous circuit to %s", oldstate->chosen_exit_name); @@ -553,7 +553,7 @@ rend_service_launch_establish_intro(rend_service_t *service, const char *nicknam nickname, service->service_id); ++service->n_intro_circuits_launched; - launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, nickname); + launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, nickname, 1, 0); if (!launched) { log_fn(LOG_WARN, "Can't launch circuit to establish introduction at '%s'", nickname); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index c25eeaab0..b78828bc4 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -166,7 +166,6 @@ router_pick_directory_server_impl(int requireothers, int fascistfirewall, int i; routerinfo_t *router; smartlist_t *sl; - char buf[16]; if (!routerlist) return NULL; @@ -183,8 +182,7 @@ router_pick_directory_server_impl(int requireothers, int fascistfirewall, if (requireothers && router_is_me(router)) continue; if (fascistfirewall) { - tor_snprintf(buf,sizeof(buf),"%d",router->dir_port); - if (!smartlist_string_isin(get_options()->FirewallPorts, buf)) + if (!smartlist_string_num_isin(get_options()->FirewallPorts, router->dir_port)) continue; } /* before 0.0.9rc5-cvs, only trusted dirservers served status info. */ @@ -205,7 +203,6 @@ router_pick_trusteddirserver_impl(int requireother, int fascistfirewall) { smartlist_t *sl; routerinfo_t *me; - char buf[16]; trusted_dir_server_t *ds; sl = smartlist_create(); me = router_get_my_routerinfo(); @@ -223,8 +220,7 @@ router_pick_trusteddirserver_impl(int requireother, int fascistfirewall) !memcmp(me->identity_digest, d->digest, DIGEST_LEN)) continue; if (fascistfirewall) { - tor_snprintf(buf,sizeof(buf),"%d",d->dir_port); - if (!smartlist_string_isin(get_options()->FirewallPorts, buf)) + if (!smartlist_string_num_isin(get_options()->FirewallPorts, d->dir_port)) continue; } smartlist_add(sl, d); @@ -360,7 +356,7 @@ 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 preferuptime, int preferbandwidth) + int need_uptime, int need_capacity) { routerinfo_t *router; int i; @@ -373,7 +369,7 @@ 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(router, preferuptime, preferbandwidth)))) { + !router_is_unreliable(router, need_uptime, need_capacity)))) { /* If it's running, and either it's verified or we're ok picking * unverified routers and this one is suitable. */ @@ -399,11 +395,11 @@ routerlist_find_my_routerinfo(void) { } int -router_is_unreliable_router(routerinfo_t *router, int need_uptime, int need_bw) +router_is_unreliable(routerinfo_t *router, int need_uptime, int need_capacity) { if (need_uptime && router->uptime < ROUTER_REQUIRED_MIN_UPTIME) return 1; - if (need_bw && router->bandwidthcapacity < ROUTER_REQUIRED_MIN_BANDWIDTH) + if (need_capacity && router->bandwidthcapacity < ROUTER_REQUIRED_MIN_BANDWIDTH) return 1; return 0; } @@ -416,7 +412,7 @@ routerlist_sl_remove_unreliable_routers(smartlist_t *sl) for (i = 0; i < smartlist_len(sl); ++i) { router = smartlist_get(sl, i); - if (router_is_unreliable_router(router, 1, 0)) { + if (router_is_unreliable(router, 1, 0)) { log(LOG_DEBUG, "Router '%s' has insufficient uptime; deleting.", router->nickname); smartlist_del(sl, i--); @@ -480,7 +476,7 @@ routerlist_sl_choose_by_bandwidth(smartlist_t *sl) routerinfo_t *router_choose_random_node(const char *preferred, const char *excluded, smartlist_t *excludedsmartlist, - int preferuptime, int preferbandwidth, + int need_uptime, int need_capacity, int allow_unverified, int strict) { smartlist_t *sl, *excludednodes; @@ -495,9 +491,9 @@ routerinfo_t *router_choose_random_node(const char *preferred, smartlist_subtract(sl,excludednodes); if (excludedsmartlist) smartlist_subtract(sl,excludedsmartlist); - if (preferuptime) + if (need_uptime) routerlist_sl_remove_unreliable_routers(sl); - if (preferbandwidth) + if (need_capacity) choice = routerlist_sl_choose_by_bandwidth(sl); else choice = smartlist_choose(sl); @@ -505,13 +501,13 @@ routerinfo_t *router_choose_random_node(const char *preferred, if (!choice && !strict) { sl = smartlist_create(); router_add_running_routers_to_smartlist(sl, allow_unverified, - preferuptime, preferbandwidth); + need_uptime, need_capacity); smartlist_subtract(sl,excludednodes); if (excludedsmartlist) smartlist_subtract(sl,excludedsmartlist); - if (preferuptime) + if (need_uptime) routerlist_sl_remove_unreliable_routers(sl); - if (preferbandwidth) + if (need_capacity) choice = routerlist_sl_choose_by_bandwidth(sl); else choice = smartlist_choose(sl); @@ -1007,16 +1003,19 @@ int router_compare_addr_to_addr_policy(uint32_t addr, uint16_t port, return maybe_reject ? ADDR_POLICY_UNKNOWN : ADDR_POLICY_ACCEPTED; } -/** Return 1 if all running routers will reject addr:port, return 0 if - * any might accept it. */ -int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port) { +/** Return 1 if all running sufficiently-stable routers will reject + * addr:port, return 0 if any might accept it. */ +int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port, + int need_uptime) { int i; routerinfo_t *router; if (!routerlist) return 1; for (i=0;i<smartlist_len(routerlist->routers);i++) { router = smartlist_get(routerlist->routers, i); - if (router->is_running && router_compare_addr_to_addr_policy( + if (router->is_running && + !router_is_unreliable(router, need_uptime, 0) && + router_compare_addr_to_addr_policy( addr, port, router->exit_policy) != ADDR_POLICY_REJECTED) return 0; /* this one could be ok. good enough. */ } |