diff options
author | Roger Dingledine <arma@torproject.org> | 2005-01-12 04:58:23 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2005-01-12 04:58:23 +0000 |
commit | 84c81e07838f5966f7a949df9b8f7d5bbb72d62e (patch) | |
tree | 9c3f159d592f1a9615fb2608cd23e6921dd54d4f /src/or/circuitbuild.c | |
parent | 51f47d746e602b4043b054acb733e9e389361c30 (diff) | |
download | tor-84c81e07838f5966f7a949df9b8f7d5bbb72d62e.tar tor-84c81e07838f5966f7a949df9b8f7d5bbb72d62e.tar.gz |
Annotate circuits w/ whether they aim to contain high uptime nodes and/or
high capacity nodes. When building circuits, choose appropriate nodes.
New config option LongLivedPorts to indicate application streams
that will want high uptime circuits.
When attaching a stream to a circuit, pay attention to its requirements.
This means that every single node in an intro rend circuit, not just
the last one, will have a minimum uptime.
Boost the min uptime from an hour to 24 hours.
svn:r3339
Diffstat (limited to 'src/or/circuitbuild.c')
-rw-r--r-- | src/or/circuitbuild.c | 66 |
1 files changed, 46 insertions, 20 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; |