diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-02-24 13:05:25 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-02-24 13:05:25 -0500 |
commit | d21b24b3b6f4d8203c44cec7709a7f7a12a540df (patch) | |
tree | fb357cfbd27e281568b00a96fd31029ba659effa /src | |
parent | e616f5b51312fef55099f2a7cd93af58d2b08032 (diff) | |
parent | 1068e50aecefac8469991884afc08b6ecb24e740 (diff) | |
download | tor-d21b24b3b6f4d8203c44cec7709a7f7a12a540df.tar tor-d21b24b3b6f4d8203c44cec7709a7f7a12a540df.tar.gz |
Merge remote-tracking branch 'public/feature9777_024_squashed' into maint-0.2.4
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuitbuild.c | 77 | ||||
-rw-r--r-- | src/or/circuitlist.c | 10 | ||||
-rw-r--r-- | src/or/circuitlist.h | 1 |
3 files changed, 78 insertions, 10 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 43d2ffe4d..e47a2780a 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -72,6 +72,9 @@ static void pathbias_count_use_failed(origin_circuit_t *circ); static void pathbias_measure_use_rate(entry_guard_t *guard); static void pathbias_measure_close_rate(entry_guard_t *guard); static void pathbias_scale_use_rates(entry_guard_t *guard); +#ifdef CURVE25519_ENABLED +static int circuits_can_use_ntor(void); +#endif /** This function tries to get a channel to the specified endpoint, * and then calls command_setup_channel() to give it the right @@ -284,21 +287,74 @@ circuit_rep_hist_note_result(origin_circuit_t *circ) } while (hop!=circ->cpath); } +#ifdef CURVE25519_ENABLED +/** Return 1 iff at least one node in circ's cpath supports ntor. */ +static int +circuit_cpath_supports_ntor(const origin_circuit_t *circ) +{ + crypt_path_t *head = circ->cpath, *cpath = circ->cpath; + + cpath = head; + do { + if (cpath->extend_info && + !tor_mem_is_zero( + (const char*)cpath->extend_info->curve25519_onion_key.public_key, + CURVE25519_PUBKEY_LEN)) + return 1; + + cpath = cpath->next; + } while (cpath != head); + + return 0; +} +#else +#define circuit_cpath_supports_ntor(circ) 0 +#endif + /** Pick all the entries in our cpath. Stop and return 0 when we're * happy, or return -1 if an error occurs. */ static int onion_populate_cpath(origin_circuit_t *circ) { - int r; - again: - r = onion_extend_cpath(circ); - if (r < 0) { - log_info(LD_CIRC,"Generating cpath hop failed."); - return -1; + int n_tries = 0; +#ifdef CURVE25519_ENABLED + const int using_ntor = circuits_can_use_ntor(); +#else + const int using_ntor = 0; +#endif + +#define MAX_POPULATE_ATTEMPTS 32 + + while (1) { + int r = onion_extend_cpath(circ); + if (r < 0) { + log_info(LD_CIRC,"Generating cpath hop failed."); + return -1; + } + if (r == 1) { + /* This circuit doesn't need/shouldn't be forced to have an ntor hop */ + if (circ->build_state->desired_path_len <= 1 || ! using_ntor) + return 0; + + /* This circuit has an ntor hop. great! */ + if (circuit_cpath_supports_ntor(circ)) + return 0; + + /* No node in the circuit supports ntor. Have we already tried too many + * times? */ + if (++n_tries >= MAX_POPULATE_ATTEMPTS) + break; + + /* Clear the path and retry */ + circuit_clear_cpath(circ); + } } - if (r == 0) - goto again; - return 0; /* if r == 1 */ + log_warn(LD_CIRC, "I tried for %d times, but I couldn't build a %d-hop " + "circuit with at least one node that supports ntor.", + MAX_POPULATE_ATTEMPTS, + circ->build_state->desired_path_len); + + return -1; } /** Create and return a new origin circuit. Initialize its purpose and @@ -3475,6 +3531,9 @@ onion_next_hop_in_cpath(crypt_path_t *cpath) /** Choose a suitable next hop in the cpath <b>head_ptr</b>, * based on <b>state</b>. Append the hop info to head_ptr. + * + * Return 1 if the path is complete, 0 if we successfully added a hop, + * and -1 on error. */ static int onion_extend_cpath(origin_circuit_t *circ) diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index b0e24a5fe..c7b15e40b 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -709,7 +709,7 @@ circuit_free_cpath(crypt_path_t *cpath) if (!cpath) return; - /* it's a doubly linked list, so we have to notice when we've + /* it's a circular list, so we have to notice when we've * gone through it once. */ while (cpath->next && cpath->next != head) { victim = cpath; @@ -720,6 +720,14 @@ circuit_free_cpath(crypt_path_t *cpath) circuit_free_cpath_node(cpath); } +/** Remove all the items in the cpath on <b>circ</b>.*/ +void +circuit_clear_cpath(origin_circuit_t *circ) +{ + circuit_free_cpath(circ->cpath); + circ->cpath = NULL; +} + /** Release all storage held by circuits. */ void circuit_free_all(void) diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h index 874f68cd2..acc4b81fc 100644 --- a/src/or/circuitlist.h +++ b/src/or/circuitlist.h @@ -50,6 +50,7 @@ void circuit_mark_all_dirty_circs_as_unusable(void); void circuit_mark_for_close_(circuit_t *circ, int reason, int line, const char *file); int circuit_get_cpath_len(origin_circuit_t *circ); +void circuit_clear_cpath(origin_circuit_t *circ); crypt_path_t *circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum); void circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan); |