diff options
author | Roger Dingledine <arma@torproject.org> | 2005-01-17 18:13:09 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2005-01-17 18:13:09 +0000 |
commit | d2400a5afd70b009b632b307205273fc25c8cd92 (patch) | |
tree | 5a25d9d3a30fb61f43c53387397e8529544775c2 /src/or/circuitbuild.c | |
parent | 9c8c90ec2f2ae0d83effbaa3a13077dfc9dd975c (diff) | |
download | tor-d2400a5afd70b009b632b307205273fc25c8cd92.tar.gz tor-d2400a5afd70b009b632b307205273fc25c8cd92.zip |
Introduce a notion of 'internal' circs, which are chosen without regard
to the exit policy of the last hop. Intro and rendezvous circs must
be internal circs, to avoid leaking information. Resolve and connect
streams can use internal circs if they want.
New circuit pooling algorithm: make sure to have enough circs around
to satisfy any predicted ports, and also make sure to have 2 internal
circs around if we've required internal circs lately (with high uptime
if we've seen that lately).
Split NewCircuitPeriod config option into NewCircuitPeriod (30 secs),
which describes how often we retry making new circuits if current ones
are dirty, and MaxCircuitDirtiness (10 mins), which describes how long
we're willing to make use of an already-dirty circuit.
Once rendezvous circuits are established, keep using the same circuit as
long as you attach a new stream to it at least every 10 minutes. (So web
browsing doesn't require you to build new rend circs every 30 seconds.)
Cannibalize GENERAL circs to be C_REND, C_INTRO, S_INTRO, and S_REND
circ as necessary, if there are any completed ones lying around when
we try to launch one.
Re-instate the ifdef's to use version-0 style introduce cells, since
there was yet another bug in handling version-1 style. We'll try switching
over again after 0.0.9 is obsolete.
Bugfix: when choosing an exit node for a new non-internal circ, don't take
into account whether it'll be useful for any pending x.onion addresses --
it won't.
Bugfix: we weren't actually publishing the hidden service descriptor when
it became dirty. So we only published it every 20 minutes or so, which
means when you first start your Tor, the hidden service will seem broken.
svn:r3360
Diffstat (limited to 'src/or/circuitbuild.c')
-rw-r--r-- | src/or/circuitbuild.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index d7e00581b9..868740fe0a 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -23,7 +23,7 @@ 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, - int need_uptime, int need_capacity); + int need_uptime, int need_capacity, int internal); 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); @@ -82,7 +82,9 @@ circuit_list_path(circuit_t *circ, int verbose) elements = smartlist_create(); if (verbose) { - tor_snprintf(buf, sizeof(buf)-1, "circ (length %d, exit %s):", + tor_snprintf(buf, sizeof(buf)-1, "%s%s circ (length %d, exit %s):", + circ->build_state->is_internal ? "internal" : "exit", + circ->build_state->need_uptime ? " (high-uptime)" : "", circ->build_state->desired_path_len, circ->build_state->chosen_exit_name); smartlist_add(elements, tor_strdup(buf)); @@ -236,7 +238,7 @@ void circuit_dump_by_conn(connection_t *conn, int severity) { */ circuit_t * circuit_establish_circuit(uint8_t purpose, const char *exit_digest, - int need_uptime, int need_capacity) { + int need_uptime, int need_capacity, int internal) { routerinfo_t *firsthop; connection_t *n_conn; circuit_t *circ; @@ -244,7 +246,7 @@ circuit_establish_circuit(uint8_t purpose, const char *exit_digest, 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, - need_uptime, need_capacity); + need_uptime, need_capacity, internal); circ->purpose = purpose; if (! circ->build_state) { @@ -951,6 +953,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime, if (carray[j]->type != CONN_TYPE_AP || carray[j]->state != AP_CONN_STATE_CIRCUIT_WAIT || carray[j]->marked_for_close || + connection_edge_is_rendezvous_stream(carray[j]) || circuit_stream_is_being_handled(carray[j], 0, MIN_CIRCUITS_HANDLING_STREAM)) continue; /* Skip everything but APs in CIRCUIT_WAIT */ if (connection_ap_can_use_exit(carray[j], router)) { @@ -1080,7 +1083,7 @@ choose_good_exit_server(uint8_t purpose, routerlist_t *dir, */ static cpath_build_state_t * onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest, - int need_uptime, int need_capacity) + int need_uptime, int need_capacity, int internal) { routerlist_t *rl; int r; @@ -1097,6 +1100,7 @@ onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest, info->desired_path_len = r; info->need_uptime = need_uptime; info->need_capacity = need_capacity; + info->is_internal = internal; 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); @@ -1121,6 +1125,35 @@ onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest, return info; } +/** Take the open circ originating here, give it a new exit destination + * to exit_digest (use nickname directly if it's provided, else strdup + * out of router->nickname), and get it to send the next extend cell. + */ +int +circuit_append_new_hop(circuit_t *circ, char *nickname, const char *exit_digest) { + routerinfo_t *exit = router_get_by_digest(exit_digest); + tor_assert(CIRCUIT_IS_ORIGIN(circ)); + circ->state = CIRCUIT_STATE_BUILDING; + tor_free(circ->build_state->chosen_exit_name); + if (nickname) { + circ->build_state->chosen_exit_name = nickname; + } else if (exit) { + circ->build_state->chosen_exit_name = tor_strdup(exit->nickname); + } else { + circ->build_state->chosen_exit_name = tor_malloc(HEX_DIGEST_LEN+1); + base16_encode(circ->build_state->chosen_exit_name, HEX_DIGEST_LEN+1, + exit_digest, DIGEST_LEN); + } + memcpy(circ->build_state->chosen_exit_digest, exit_digest, DIGEST_LEN); + ++circ->build_state->desired_path_len; + if (circuit_send_next_onion_skin(circ)<0) { + log_fn(LOG_WARN, "Couldn't extend circuit to new point '%s'.", circ->build_state->chosen_exit_name); + circuit_mark_for_close(circ); + return -1; + } + return 0; +} + /** Return the number of routers in <b>routers</b> that are currently up * and available for building circuits through. */ |