mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
Merge remote-tracking branch 'public/feature9777_024_squashed' into maint-0.2.4
This commit is contained in:
commit
d21b24b3b6
3
changes/feature9777
Normal file
3
changes/feature9777
Normal file
@ -0,0 +1,3 @@
|
||||
o Minor features:
|
||||
- Avoid using circuit paths if no node in the path supports the ntor
|
||||
circuit extension handshake. Implements ticket 9777.
|
@ -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);
|
||||
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 == 0)
|
||||
goto again;
|
||||
return 0; /* if r == 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);
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user