mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
More digest/nickname fixes
svn:r2000
This commit is contained in:
parent
d58d4c0db6
commit
7d8de8cd10
3
doc/TODO
3
doc/TODO
@ -54,8 +54,9 @@ NICK pre1:
|
|||||||
o extend cells need ip:port:identitykeyhash.
|
o extend cells need ip:port:identitykeyhash.
|
||||||
. Lookup routers and connections by key digest; accept hex
|
. Lookup routers and connections by key digest; accept hex
|
||||||
key digest in place of nicknames.
|
key digest in place of nicknames.
|
||||||
- Audit all uses of lookup-by-hostname and lookup-by-addr-port
|
. Audit all uses of lookup-by-hostname and lookup-by-addr-port
|
||||||
to search by digest when appropriate.
|
to search by digest when appropriate.
|
||||||
|
- Rep-hist functions
|
||||||
- also use this in intro points and rendezvous points, and
|
- also use this in intro points and rendezvous points, and
|
||||||
hidserv descs. [XXXX This isn't enough.]
|
hidserv descs. [XXXX This isn't enough.]
|
||||||
- figure out what to do about ip:port:differentkey
|
- figure out what to do about ip:port:differentkey
|
||||||
|
@ -1448,7 +1448,7 @@ int base16_encode(char *dest, int destlen, const char *src, int srclen)
|
|||||||
++src;
|
++src;
|
||||||
cp += 2;
|
cp += 2;
|
||||||
}
|
}
|
||||||
*dest = '\0';
|
*cp = '\0';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1484,6 +1484,7 @@ int base16_decode(char *dest, int destlen, const char *src, int srclen)
|
|||||||
return -1;
|
return -1;
|
||||||
*(uint8_t*)dest = (v1<<4)|v2;
|
*(uint8_t*)dest = (v1<<4)|v2;
|
||||||
++dest;
|
++dest;
|
||||||
|
src+=2;
|
||||||
}
|
}
|
||||||
*dest = '\0';
|
*dest = '\0';
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -21,7 +21,7 @@ extern circuit_t *global_circuitlist;
|
|||||||
static int
|
static int
|
||||||
circuit_deliver_create_cell(circuit_t *circ, char *payload);
|
circuit_deliver_create_cell(circuit_t *circ, char *payload);
|
||||||
static cpath_build_state_t *
|
static cpath_build_state_t *
|
||||||
onion_new_cpath_build_state(uint8_t purpose, const char *exit_nickname);
|
onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest);
|
||||||
static int
|
static int
|
||||||
onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t
|
onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t
|
||||||
*state, routerinfo_t **router_out);
|
*state, routerinfo_t **router_out);
|
||||||
@ -75,7 +75,7 @@ void circuit_log_path(int severity, circuit_t *circ) {
|
|||||||
tor_assert(CIRCUIT_IS_ORIGIN(circ) && circ->cpath);
|
tor_assert(CIRCUIT_IS_ORIGIN(circ) && circ->cpath);
|
||||||
|
|
||||||
snprintf(s, sizeof(buf)-1, "circ (length %d, exit %s): ",
|
snprintf(s, sizeof(buf)-1, "circ (length %d, exit %s): ",
|
||||||
circ->build_state->desired_path_len, circ->build_state->chosen_exit);
|
circ->build_state->desired_path_len, circ->build_state->chosen_exit_name);
|
||||||
hop=circ->cpath;
|
hop=circ->cpath;
|
||||||
do {
|
do {
|
||||||
s = buf + strlen(buf);
|
s = buf + strlen(buf);
|
||||||
@ -148,7 +148,7 @@ circuit_dump_details(int severity, circuit_t *circ, int poll_index,
|
|||||||
if(CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */
|
if(CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */
|
||||||
if(circ->state == CIRCUIT_STATE_BUILDING)
|
if(circ->state == CIRCUIT_STATE_BUILDING)
|
||||||
log(severity,"Building: desired len %d, planned exit node %s.",
|
log(severity,"Building: desired len %d, planned exit node %s.",
|
||||||
circ->build_state->desired_path_len, circ->build_state->chosen_exit);
|
circ->build_state->desired_path_len, circ->build_state->chosen_exit_name);
|
||||||
for(hop=circ->cpath;hop->next != circ->cpath; hop=hop->next)
|
for(hop=circ->cpath;hop->next != circ->cpath; hop=hop->next)
|
||||||
log(severity,"hop: state %d, addr 0x%.8x, port %d", hop->state,
|
log(severity,"hop: state %d, addr 0x%.8x, port %d", hop->state,
|
||||||
(unsigned int)hop->addr,
|
(unsigned int)hop->addr,
|
||||||
@ -185,7 +185,7 @@ void circuit_dump_by_conn(connection_t *conn, int severity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Build a new circuit for <b>purpose</b>. If <b>exit_nickname</b>
|
/** Build a new circuit for <b>purpose</b>. If <b>exit_digest</b>
|
||||||
* is defined, then use that as your exit router, else choose a suitable
|
* is defined, then use that as your exit router, else choose a suitable
|
||||||
* exit node.
|
* exit node.
|
||||||
*
|
*
|
||||||
@ -193,14 +193,14 @@ void circuit_dump_by_conn(connection_t *conn, int severity) {
|
|||||||
* it's not open already.
|
* it's not open already.
|
||||||
*/
|
*/
|
||||||
circuit_t *circuit_establish_circuit(uint8_t purpose,
|
circuit_t *circuit_establish_circuit(uint8_t purpose,
|
||||||
const char *exit_nickname) {
|
const char *exit_digest) {
|
||||||
routerinfo_t *firsthop;
|
routerinfo_t *firsthop;
|
||||||
connection_t *n_conn;
|
connection_t *n_conn;
|
||||||
circuit_t *circ;
|
circuit_t *circ;
|
||||||
|
|
||||||
circ = circuit_new(0, NULL); /* sets circ->p_circ_id and circ->p_conn */
|
circ = circuit_new(0, NULL); /* sets circ->p_circ_id and circ->p_conn */
|
||||||
circ->state = CIRCUIT_STATE_OR_WAIT;
|
circ->state = CIRCUIT_STATE_OR_WAIT;
|
||||||
circ->build_state = onion_new_cpath_build_state(purpose, exit_nickname);
|
circ->build_state = onion_new_cpath_build_state(purpose, exit_digest);
|
||||||
circ->purpose = purpose;
|
circ->purpose = purpose;
|
||||||
|
|
||||||
if (! circ->build_state) {
|
if (! circ->build_state) {
|
||||||
@ -302,6 +302,10 @@ circuit_deliver_create_cell(circuit_t *circ, char *payload) {
|
|||||||
tor_assert(circ && circ->n_conn && circ->n_conn->type == CONN_TYPE_OR);
|
tor_assert(circ && circ->n_conn && circ->n_conn->type == CONN_TYPE_OR);
|
||||||
tor_assert(payload);
|
tor_assert(payload);
|
||||||
|
|
||||||
|
/* XXXX008 How can we keep a good upgrade path here? We should
|
||||||
|
* compare keys, not nicknames...but older servers will compare nicknames.
|
||||||
|
* Should we check server version from the most recent directory? Hm.
|
||||||
|
*/
|
||||||
circ_id_type = decide_circ_id_type(options.Nickname,
|
circ_id_type = decide_circ_id_type(options.Nickname,
|
||||||
circ->n_conn->nickname);
|
circ->n_conn->nickname);
|
||||||
circ->n_circ_id = get_unique_circ_id_by_conn(circ->n_conn, circ_id_type);
|
circ->n_circ_id = get_unique_circ_id_by_conn(circ->n_conn, circ_id_type);
|
||||||
@ -345,7 +349,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
|
|||||||
if(circ->cpath->state == CPATH_STATE_CLOSED) {
|
if(circ->cpath->state == CPATH_STATE_CLOSED) {
|
||||||
log_fn(LOG_DEBUG,"First skin; sending create cell.");
|
log_fn(LOG_DEBUG,"First skin; sending create cell.");
|
||||||
|
|
||||||
router = router_get_by_nickname(circ->n_conn->nickname);
|
router = router_get_by_digest(circ->n_conn->identity_digest);
|
||||||
if (!router) {
|
if (!router) {
|
||||||
log_fn(LOG_WARN,"Couldn't find routerinfo for %s",
|
log_fn(LOG_WARN,"Couldn't find routerinfo for %s",
|
||||||
circ->n_conn->nickname);
|
circ->n_conn->nickname);
|
||||||
@ -945,22 +949,29 @@ static routerinfo_t *choose_good_exit_server(uint8_t purpose, routerlist_t *dir)
|
|||||||
* return it.
|
* return it.
|
||||||
*/
|
*/
|
||||||
static cpath_build_state_t *
|
static cpath_build_state_t *
|
||||||
onion_new_cpath_build_state(uint8_t purpose, const char *exit_nickname)
|
onion_new_cpath_build_state(uint8_t purpose, const char *exit_digest)
|
||||||
{
|
{
|
||||||
routerlist_t *rl;
|
routerlist_t *rl;
|
||||||
int r;
|
int r;
|
||||||
cpath_build_state_t *info;
|
cpath_build_state_t *info;
|
||||||
routerinfo_t *exit;
|
routerinfo_t *exit;
|
||||||
|
|
||||||
router_get_routerlist(&rl);
|
router_get_routerlist(&rl);
|
||||||
r = new_route_len(options.PathlenCoinWeight, purpose, rl->routers);
|
r = new_route_len(options.PathlenCoinWeight, purpose, rl->routers);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
info = tor_malloc_zero(sizeof(cpath_build_state_t));
|
info = tor_malloc_zero(sizeof(cpath_build_state_t));
|
||||||
info->desired_path_len = r;
|
info->desired_path_len = r;
|
||||||
if(exit_nickname) { /* the circuit-builder pre-requested one */
|
if(exit_digest) { /* the circuit-builder pre-requested one */
|
||||||
log_fn(LOG_INFO,"Using requested exit node '%s'", exit_nickname);
|
memcpy(info->chosen_exit_digest, exit_digest, DIGEST_LEN);
|
||||||
info->chosen_exit = tor_strdup(exit_nickname);
|
exit = router_get_by_digest(exit_digest);
|
||||||
|
if (exit) {
|
||||||
|
info->chosen_exit_name = tor_strdup(exit->nickname);
|
||||||
|
} else {
|
||||||
|
info->chosen_exit_name = tor_malloc(HEX_DIGEST_LEN+1);
|
||||||
|
base16_encode(info->chosen_exit_name, HEX_DIGEST_LEN+1,
|
||||||
|
exit_digest, DIGEST_LEN);
|
||||||
|
}
|
||||||
|
log_fn(LOG_INFO,"Using requested exit node '%s'", info->chosen_exit_name);
|
||||||
} else { /* we have to decide one */
|
} else { /* we have to decide one */
|
||||||
exit = choose_good_exit_server(purpose, rl);
|
exit = choose_good_exit_server(purpose, rl);
|
||||||
if(!exit) {
|
if(!exit) {
|
||||||
@ -968,7 +979,8 @@ onion_new_cpath_build_state(uint8_t purpose, const char *exit_nickname)
|
|||||||
tor_free(info);
|
tor_free(info);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
info->chosen_exit = tor_strdup(exit->nickname);
|
memcpy(info->chosen_exit_digest, exit->identity_digest, DIGEST_LEN);
|
||||||
|
info->chosen_exit_name = tor_strdup(exit->nickname);
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -1091,12 +1103,12 @@ onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t
|
|||||||
|
|
||||||
if(cur_len == state->desired_path_len - 1) { /* Picking last node */
|
if(cur_len == state->desired_path_len - 1) { /* Picking last node */
|
||||||
log_fn(LOG_DEBUG, "Contemplating last hop: choice already made: %s",
|
log_fn(LOG_DEBUG, "Contemplating last hop: choice already made: %s",
|
||||||
state->chosen_exit);
|
state->chosen_exit_name);
|
||||||
choice = router_get_by_nickname(state->chosen_exit);
|
choice = router_get_by_digest(state->chosen_exit_digest);
|
||||||
smartlist_free(excludednodes);
|
smartlist_free(excludednodes);
|
||||||
if(!choice) {
|
if(!choice) {
|
||||||
log_fn(LOG_WARN,"Our chosen exit %s is no longer in the directory? Discarding this circuit.",
|
log_fn(LOG_WARN,"Our chosen exit %s is no longer in the directory? Discarding this circuit.",
|
||||||
state->chosen_exit);
|
state->chosen_exit_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if(cur_len == 0) { /* picking first node */
|
} else if(cur_len == 0) { /* picking first node */
|
||||||
@ -1104,7 +1116,7 @@ onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t
|
|||||||
sl = smartlist_create();
|
sl = smartlist_create();
|
||||||
add_nickname_list_to_smartlist(sl,options.EntryNodes);
|
add_nickname_list_to_smartlist(sl,options.EntryNodes);
|
||||||
/* XXX one day, consider picking chosen_exit knowing what's in EntryNodes */
|
/* XXX one day, consider picking chosen_exit knowing what's in EntryNodes */
|
||||||
remove_twins_from_smartlist(sl,router_get_by_nickname(state->chosen_exit));
|
remove_twins_from_smartlist(sl,router_get_by_digest(state->chosen_exit_digest));
|
||||||
remove_twins_from_smartlist(sl,router_get_my_routerinfo());
|
remove_twins_from_smartlist(sl,router_get_my_routerinfo());
|
||||||
smartlist_subtract(sl,excludednodes);
|
smartlist_subtract(sl,excludednodes);
|
||||||
choice = smartlist_choose(sl);
|
choice = smartlist_choose(sl);
|
||||||
@ -1112,7 +1124,7 @@ onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t
|
|||||||
if(!choice) {
|
if(!choice) {
|
||||||
sl = smartlist_create();
|
sl = smartlist_create();
|
||||||
router_add_running_routers_to_smartlist(sl);
|
router_add_running_routers_to_smartlist(sl);
|
||||||
remove_twins_from_smartlist(sl,router_get_by_nickname(state->chosen_exit));
|
remove_twins_from_smartlist(sl,router_get_by_digest(state->chosen_exit_digest));
|
||||||
remove_twins_from_smartlist(sl,router_get_my_routerinfo());
|
remove_twins_from_smartlist(sl,router_get_my_routerinfo());
|
||||||
smartlist_subtract(sl,excludednodes);
|
smartlist_subtract(sl,excludednodes);
|
||||||
choice = smartlist_choose(sl);
|
choice = smartlist_choose(sl);
|
||||||
@ -1127,7 +1139,7 @@ onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t
|
|||||||
log_fn(LOG_DEBUG, "Contemplating intermediate hop: random choice.");
|
log_fn(LOG_DEBUG, "Contemplating intermediate hop: random choice.");
|
||||||
sl = smartlist_create();
|
sl = smartlist_create();
|
||||||
router_add_running_routers_to_smartlist(sl);
|
router_add_running_routers_to_smartlist(sl);
|
||||||
remove_twins_from_smartlist(sl,router_get_by_nickname(state->chosen_exit));
|
remove_twins_from_smartlist(sl,router_get_by_digest(state->chosen_exit_digest));
|
||||||
remove_twins_from_smartlist(sl,router_get_my_routerinfo());
|
remove_twins_from_smartlist(sl,router_get_my_routerinfo());
|
||||||
for (i = 0, cpath = *head_ptr; i < cur_len; ++i, cpath=cpath->next) {
|
for (i = 0, cpath = *head_ptr; i < cur_len; ++i, cpath=cpath->next) {
|
||||||
r = router_get_by_digest(cpath->identity_digest);
|
r = router_get_by_digest(cpath->identity_digest);
|
||||||
@ -1145,7 +1157,7 @@ onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
log_fn(LOG_DEBUG,"Chose router %s for hop %d (exit is %s)",
|
log_fn(LOG_DEBUG,"Chose router %s for hop %d (exit is %s)",
|
||||||
choice->nickname, cur_len, state->chosen_exit);
|
choice->nickname, cur_len, state->chosen_exit_name);
|
||||||
|
|
||||||
hop = tor_malloc_zero(sizeof(crypt_path_t));
|
hop = tor_malloc_zero(sizeof(crypt_path_t));
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ static void circuit_free(circuit_t *circ) {
|
|||||||
if (circ->p_digest)
|
if (circ->p_digest)
|
||||||
crypto_free_digest_env(circ->p_digest);
|
crypto_free_digest_env(circ->p_digest);
|
||||||
if(circ->build_state) {
|
if(circ->build_state) {
|
||||||
tor_free(circ->build_state->chosen_exit);
|
tor_free(circ->build_state->chosen_exit_name);
|
||||||
if (circ->build_state->pending_final_cpath)
|
if (circ->build_state->pending_final_cpath)
|
||||||
circuit_free_cpath_node(circ->build_state->pending_final_cpath);
|
circuit_free_cpath_node(circ->build_state->pending_final_cpath);
|
||||||
}
|
}
|
||||||
@ -361,8 +361,8 @@ int _circuit_mark_for_close(circuit_t *circ) {
|
|||||||
tor_assert(circ->state == CIRCUIT_STATE_OPEN);
|
tor_assert(circ->state == CIRCUIT_STATE_OPEN);
|
||||||
/* treat this like getting a nack from it */
|
/* treat this like getting a nack from it */
|
||||||
log_fn(LOG_INFO,"Failed intro circ %s to %s (awaiting ack). Removing from descriptor.",
|
log_fn(LOG_INFO,"Failed intro circ %s to %s (awaiting ack). Removing from descriptor.",
|
||||||
circ->rend_query, circ->build_state->chosen_exit);
|
circ->rend_query, circ->build_state->chosen_exit_name);
|
||||||
rend_client_remove_intro_point(circ->build_state->chosen_exit, circ->rend_query);
|
rend_client_remove_intro_point(circ->build_state->chosen_exit_name, circ->rend_query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(circ->n_conn)
|
if(circ->n_conn)
|
||||||
|
@ -66,7 +66,7 @@ static int circuit_is_acceptable(circuit_t *circ,
|
|||||||
* circuit, it's the magical extra bob hop. so just check the nickname
|
* circuit, it's the magical extra bob hop. so just check the nickname
|
||||||
* of the one we meant to finish at.
|
* of the one we meant to finish at.
|
||||||
*/
|
*/
|
||||||
exitrouter = router_get_by_nickname(circ->build_state->chosen_exit);
|
exitrouter = router_get_by_digest(circ->build_state->chosen_exit_digest);
|
||||||
|
|
||||||
if(!exitrouter) {
|
if(!exitrouter) {
|
||||||
log_fn(LOG_INFO,"Skipping broken circ (exit router vanished)");
|
log_fn(LOG_INFO,"Skipping broken circ (exit router vanished)");
|
||||||
@ -201,12 +201,12 @@ void circuit_expire_building(time_t now) {
|
|||||||
if(!victim->timestamp_dirty)
|
if(!victim->timestamp_dirty)
|
||||||
log_fn(LOG_DEBUG,"Considering %sopen purp %d to %s (circid %d). (clean).",
|
log_fn(LOG_DEBUG,"Considering %sopen purp %d to %s (circid %d). (clean).",
|
||||||
victim->state == CIRCUIT_STATE_OPEN ? "" : "non",
|
victim->state == CIRCUIT_STATE_OPEN ? "" : "non",
|
||||||
victim->purpose, victim->build_state->chosen_exit,
|
victim->purpose, victim->build_state->chosen_exit_name,
|
||||||
victim->n_circ_id);
|
victim->n_circ_id);
|
||||||
else
|
else
|
||||||
log_fn(LOG_DEBUG,"Considering %sopen purp %d to %s (circid %d). %d secs since dirty.",
|
log_fn(LOG_DEBUG,"Considering %sopen purp %d to %s (circid %d). %d secs since dirty.",
|
||||||
victim->state == CIRCUIT_STATE_OPEN ? "" : "non",
|
victim->state == CIRCUIT_STATE_OPEN ? "" : "non",
|
||||||
victim->purpose, victim->build_state->chosen_exit,
|
victim->purpose, victim->build_state->chosen_exit_name,
|
||||||
victim->n_circ_id,
|
victim->n_circ_id,
|
||||||
(int)(now - victim->timestamp_dirty));
|
(int)(now - victim->timestamp_dirty));
|
||||||
}
|
}
|
||||||
@ -266,7 +266,7 @@ int circuit_stream_is_being_handled(connection_t *conn) {
|
|||||||
!circ->marked_for_close && circ->purpose == CIRCUIT_PURPOSE_C_GENERAL &&
|
!circ->marked_for_close && circ->purpose == CIRCUIT_PURPOSE_C_GENERAL &&
|
||||||
(!circ->timestamp_dirty ||
|
(!circ->timestamp_dirty ||
|
||||||
circ->timestamp_dirty + options.NewCircuitPeriod < now)) {
|
circ->timestamp_dirty + options.NewCircuitPeriod < now)) {
|
||||||
exitrouter = router_get_by_nickname(circ->build_state->chosen_exit);
|
exitrouter = router_get_by_digest(circ->build_state->chosen_exit_digest);
|
||||||
if(exitrouter && connection_ap_can_use_exit(conn, exitrouter) != ADDR_POLICY_REJECTED)
|
if(exitrouter && connection_ap_can_use_exit(conn, exitrouter) != ADDR_POLICY_REJECTED)
|
||||||
if(++num >= MIN_CIRCUITS_HANDLING_STREAM)
|
if(++num >= MIN_CIRCUITS_HANDLING_STREAM)
|
||||||
return 1;
|
return 1;
|
||||||
@ -305,7 +305,7 @@ void circuit_build_needed_circs(time_t now) {
|
|||||||
if(options.RunTesting && circ &&
|
if(options.RunTesting && circ &&
|
||||||
circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
|
circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
|
||||||
log_fn(LOG_INFO,"Creating a new testing circuit.");
|
log_fn(LOG_INFO,"Creating a new testing circuit.");
|
||||||
circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
|
circuit_launch_by_identity(CIRCUIT_PURPOSE_C_GENERAL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +318,7 @@ void circuit_build_needed_circs(time_t now) {
|
|||||||
* go ahead and try another. */
|
* go ahead and try another. */
|
||||||
if(!circ && circuit_count_building(CIRCUIT_PURPOSE_C_GENERAL)
|
if(!circ && circuit_count_building(CIRCUIT_PURPOSE_C_GENERAL)
|
||||||
< CIRCUIT_MIN_BUILDING_GENERAL) {
|
< CIRCUIT_MIN_BUILDING_GENERAL) {
|
||||||
circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
|
circuit_launch_by_identity(CIRCUIT_PURPOSE_C_GENERAL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX count idle rendezvous circs and build more */
|
/* XXX count idle rendezvous circs and build more */
|
||||||
@ -565,10 +565,10 @@ void circuit_build_failed(circuit_t *circ) {
|
|||||||
/* Don't increment failure count, since Alice may have picked
|
/* Don't increment failure count, since Alice may have picked
|
||||||
* the rendezvous point maliciously */
|
* the rendezvous point maliciously */
|
||||||
if (failed_at_last_hop) {
|
if (failed_at_last_hop) {
|
||||||
log_fn(LOG_INFO,"Couldn't connect to Alice's chosen rend point %s. Sucks to be Alice.", circ->build_state->chosen_exit);
|
log_fn(LOG_INFO,"Couldn't connect to Alice's chosen rend point %s. Sucks to be Alice.", circ->build_state->chosen_exit_name);
|
||||||
} else {
|
} else {
|
||||||
log_fn(LOG_INFO,"Couldn't connect to Alice's chosen rend point %s, because an earlier node failed.",
|
log_fn(LOG_INFO,"Couldn't connect to Alice's chosen rend point %s, because an earlier node failed.",
|
||||||
circ->build_state->chosen_exit);
|
circ->build_state->chosen_exit_name);
|
||||||
rend_service_relaunch_rendezvous(circ);
|
rend_service_relaunch_rendezvous(circ);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -588,9 +588,8 @@ static int n_circuit_failures = 0;
|
|||||||
* success. */
|
* success. */
|
||||||
#define MAX_CIRCUIT_FAILURES 5
|
#define MAX_CIRCUIT_FAILURES 5
|
||||||
|
|
||||||
/** Launch a new circuit and return a pointer to it. Return NULL if you failed. */
|
circuit_t *circuit_launch_by_identity(uint8_t purpose, const char *exit_digest)
|
||||||
circuit_t *circuit_launch_new(uint8_t purpose, const char *exit_nickname) {
|
{
|
||||||
|
|
||||||
if (n_circuit_failures > MAX_CIRCUIT_FAILURES) {
|
if (n_circuit_failures > MAX_CIRCUIT_FAILURES) {
|
||||||
/* too many failed circs in a row. don't try. */
|
/* too many failed circs in a row. don't try. */
|
||||||
// log_fn(LOG_INFO,"%d failures so far, not trying.",n_circuit_failures);
|
// log_fn(LOG_INFO,"%d failures so far, not trying.",n_circuit_failures);
|
||||||
@ -598,7 +597,23 @@ circuit_t *circuit_launch_new(uint8_t purpose, const char *exit_nickname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* try a circ. if it fails, circuit_mark_for_close will increment n_circuit_failures */
|
/* try a circ. if it fails, circuit_mark_for_close will increment n_circuit_failures */
|
||||||
return circuit_establish_circuit(purpose, exit_nickname);
|
return circuit_establish_circuit(purpose, exit_digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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)
|
||||||
|
{
|
||||||
|
const char *digest = NULL;
|
||||||
|
|
||||||
|
if (exit_nickname) {
|
||||||
|
routerinfo_t *r = router_get_by_nickname(exit_nickname);
|
||||||
|
if (!r) {
|
||||||
|
log_fn(LOG_WARN, "No such OR as '%s'", exit_nickname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
digest = r->identity_digest;
|
||||||
|
}
|
||||||
|
return circuit_launch_by_identity(purpose, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Record another failure at opening a general circuit. When we have
|
/** Record another failure at opening a general circuit. When we have
|
||||||
@ -682,7 +697,7 @@ circuit_get_open_circ_or_launch(connection_t *conn,
|
|||||||
else
|
else
|
||||||
new_circ_purpose = desired_circuit_purpose;
|
new_circ_purpose = desired_circuit_purpose;
|
||||||
|
|
||||||
circ = circuit_launch_new(new_circ_purpose, exitname);
|
circ = circuit_launch_by_nickname(new_circ_purpose, exitname);
|
||||||
tor_free(exitname);
|
tor_free(exitname);
|
||||||
|
|
||||||
if(circ &&
|
if(circ &&
|
||||||
|
@ -712,7 +712,7 @@ int connection_handle_read(connection_t *conn) {
|
|||||||
conn->state == DIR_CONN_STATE_CONNECTING) {
|
conn->state == DIR_CONN_STATE_CONNECTING) {
|
||||||
/* it's a directory server and connecting failed: forget about this router */
|
/* it's a directory server and connecting failed: forget about this router */
|
||||||
/* XXX I suspect pollerr may make Windows not get to this point. :( */
|
/* XXX I suspect pollerr may make Windows not get to this point. :( */
|
||||||
router_mark_as_down(conn->nickname);
|
router_mark_as_down(conn->identity_digest);
|
||||||
}
|
}
|
||||||
/* There's a read error; kill the connection.*/
|
/* There's a read error; kill the connection.*/
|
||||||
connection_close_immediate(conn); /* Don't flush; connection is dead. */
|
connection_close_immediate(conn); /* Don't flush; connection is dead. */
|
||||||
@ -828,8 +828,9 @@ int connection_handle_write(connection_t *conn) {
|
|||||||
log_fn(LOG_DEBUG,"in-progress connect failed. Removing.");
|
log_fn(LOG_DEBUG,"in-progress connect failed. Removing.");
|
||||||
connection_close_immediate(conn);
|
connection_close_immediate(conn);
|
||||||
connection_mark_for_close(conn);
|
connection_mark_for_close(conn);
|
||||||
if (conn->nickname)
|
/* Previously we tested conn->nickname; is this right? */
|
||||||
router_mark_as_down(conn->nickname);
|
if (conn->type == CONN_TYPE_OR)
|
||||||
|
router_mark_as_down(conn->identity_digest);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return 0; /* no change, see if next time is better */
|
return 0; /* no change, see if next time is better */
|
||||||
|
@ -304,6 +304,8 @@ connection_tls_finish_handshake(connection_t *conn) {
|
|||||||
}
|
}
|
||||||
log_fn(LOG_DEBUG,"The router's cert is valid.");
|
log_fn(LOG_DEBUG,"The router's cert is valid.");
|
||||||
|
|
||||||
|
/* XXXX008 This isn't right; fix this one we launch by identity digest
|
||||||
|
* XXXX008 rather than by nickname */
|
||||||
if (conn->nickname) {
|
if (conn->nickname) {
|
||||||
/* I initiated this connection. */
|
/* I initiated this connection. */
|
||||||
if (strcasecmp(conn->nickname, nickname)) {
|
if (strcasecmp(conn->nickname, nickname)) {
|
||||||
|
@ -149,7 +149,7 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose,
|
|||||||
/* then we want to connect directly */
|
/* then we want to connect directly */
|
||||||
switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
|
switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
|
||||||
case -1:
|
case -1:
|
||||||
router_mark_as_down(conn->nickname); /* don't try him again */
|
router_mark_as_down(conn->identity_digest); /* don't try him again */
|
||||||
connection_free(conn);
|
connection_free(conn);
|
||||||
return;
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
|
12
src/or/or.h
12
src/or/or.h
@ -674,7 +674,9 @@ typedef struct {
|
|||||||
/** Intended length of the final circuit. */
|
/** Intended length of the final circuit. */
|
||||||
int desired_path_len;
|
int desired_path_len;
|
||||||
/** Nickname of planned exit node. */
|
/** Nickname of planned exit node. */
|
||||||
char *chosen_exit;
|
char *chosen_exit_name;
|
||||||
|
/** Identity of planned exit node. */
|
||||||
|
char chosen_exit_digest[DIGEST_LEN];
|
||||||
/** The crypt_path_t to append after rendezvous: used for rendezvous. */
|
/** The crypt_path_t to append after rendezvous: used for rendezvous. */
|
||||||
struct crypt_path_t *pending_final_cpath;
|
struct crypt_path_t *pending_final_cpath;
|
||||||
/** How many times has building a circuit for this task failed? */
|
/** How many times has building a circuit for this task failed? */
|
||||||
@ -919,7 +921,7 @@ void circuit_log_path(int severity, circuit_t *circ);
|
|||||||
void circuit_rep_hist_note_result(circuit_t *circ);
|
void circuit_rep_hist_note_result(circuit_t *circ);
|
||||||
void circuit_dump_by_conn(connection_t *conn, int severity);
|
void circuit_dump_by_conn(connection_t *conn, int severity);
|
||||||
circuit_t *circuit_establish_circuit(uint8_t purpose,
|
circuit_t *circuit_establish_circuit(uint8_t purpose,
|
||||||
const char *exit_nickname);
|
const char *exit_digest);
|
||||||
void circuit_n_conn_done(connection_t *or_conn, int success);
|
void circuit_n_conn_done(connection_t *or_conn, int success);
|
||||||
int circuit_send_next_onion_skin(circuit_t *circ);
|
int circuit_send_next_onion_skin(circuit_t *circ);
|
||||||
int circuit_extend(cell_t *cell, circuit_t *circ);
|
int circuit_extend(cell_t *cell, circuit_t *circ);
|
||||||
@ -968,7 +970,8 @@ void circuit_detach_stream(circuit_t *circ, connection_t *conn);
|
|||||||
void circuit_about_to_close_connection(connection_t *conn);
|
void circuit_about_to_close_connection(connection_t *conn);
|
||||||
void circuit_has_opened(circuit_t *circ);
|
void circuit_has_opened(circuit_t *circ);
|
||||||
void circuit_build_failed(circuit_t *circ);
|
void circuit_build_failed(circuit_t *circ);
|
||||||
circuit_t *circuit_launch_new(uint8_t purpose, const char *exit_nickname);
|
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);
|
||||||
void circuit_reset_failure_count(void);
|
void circuit_reset_failure_count(void);
|
||||||
int connection_ap_handshake_attach_circuit(connection_t *conn);
|
int connection_ap_handshake_attach_circuit(connection_t *conn);
|
||||||
|
|
||||||
@ -1346,6 +1349,7 @@ routerinfo_t *router_pick_directory_server(void);
|
|||||||
struct smartlist_t;
|
struct smartlist_t;
|
||||||
void add_nickname_list_to_smartlist(struct smartlist_t *sl, const char *list);
|
void add_nickname_list_to_smartlist(struct smartlist_t *sl, const char *list);
|
||||||
void router_add_running_routers_to_smartlist(struct smartlist_t *sl);
|
void router_add_running_routers_to_smartlist(struct smartlist_t *sl);
|
||||||
|
int router_nickname_matches(routerinfo_t *router, const char *nickname);
|
||||||
routerinfo_t *router_choose_random_node(char *preferred, char *excluded,
|
routerinfo_t *router_choose_random_node(char *preferred, char *excluded,
|
||||||
struct smartlist_t *excludedsmartlist);
|
struct smartlist_t *excludedsmartlist);
|
||||||
routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
|
routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
|
||||||
@ -1357,7 +1361,7 @@ void routerlist_free(routerlist_t *routerlist);
|
|||||||
void routerlist_clear_trusted_directories(void);
|
void routerlist_clear_trusted_directories(void);
|
||||||
void routerinfo_free(routerinfo_t *router);
|
void routerinfo_free(routerinfo_t *router);
|
||||||
routerinfo_t *routerinfo_copy(const routerinfo_t *router);
|
routerinfo_t *routerinfo_copy(const routerinfo_t *router);
|
||||||
void router_mark_as_down(char *nickname);
|
void router_mark_as_down(const char *digest);
|
||||||
void routerlist_remove_old_routers(void);
|
void routerlist_remove_old_routers(void);
|
||||||
int router_load_routerlist_from_file(char *routerfile, int trusted);
|
int router_load_routerlist_from_file(char *routerfile, int trusted);
|
||||||
int router_load_routerlist_from_string(const char *s, int trusted);
|
int router_load_routerlist_from_string(const char *s, int trusted);
|
||||||
|
@ -90,7 +90,7 @@ rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write the remaining items into tmp */
|
/* write the remaining items into tmp */
|
||||||
strncpy(tmp, rendcirc->build_state->chosen_exit, (MAX_NICKNAME_LEN+1)); /* nul pads */
|
strncpy(tmp, rendcirc->build_state->chosen_exit_name, (MAX_NICKNAME_LEN+1)); /* nul pads */
|
||||||
memcpy(tmp+MAX_NICKNAME_LEN+1, rendcirc->rend_cookie, REND_COOKIE_LEN);
|
memcpy(tmp+MAX_NICKNAME_LEN+1, rendcirc->rend_cookie, REND_COOKIE_LEN);
|
||||||
if (crypto_dh_get_public(cpath->handshake_state,
|
if (crypto_dh_get_public(cpath->handshake_state,
|
||||||
tmp+MAX_NICKNAME_LEN+1+REND_COOKIE_LEN,
|
tmp+MAX_NICKNAME_LEN+1+REND_COOKIE_LEN,
|
||||||
@ -164,7 +164,7 @@ rend_client_introduction_acked(circuit_t *circ,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tor_assert(circ->build_state->chosen_exit);
|
tor_assert(circ->build_state->chosen_exit_name);
|
||||||
|
|
||||||
if (request_len == 0) {
|
if (request_len == 0) {
|
||||||
/* It's an ACK; the introduction point relayed our introduction request. */
|
/* It's an ACK; the introduction point relayed our introduction request. */
|
||||||
@ -187,14 +187,15 @@ rend_client_introduction_acked(circuit_t *circ,
|
|||||||
* points. If any remain, extend to a new one and try again.
|
* points. If any remain, extend to a new one and try again.
|
||||||
* If none remain, refetch the service descriptor.
|
* If none remain, refetch the service descriptor.
|
||||||
*/
|
*/
|
||||||
if(rend_client_remove_intro_point(circ->build_state->chosen_exit,
|
if(rend_client_remove_intro_point(circ->build_state->chosen_exit_name,
|
||||||
circ->rend_query) > 0) {
|
circ->rend_query) > 0) {
|
||||||
/* There are introduction points left. re-extend the circuit to
|
/* There are introduction points left. re-extend the circuit to
|
||||||
* another intro point and try again. */
|
* another intro point and try again. */
|
||||||
|
routerinfo_t *r;
|
||||||
nickname = rend_client_get_random_intro(circ->rend_query);
|
nickname = rend_client_get_random_intro(circ->rend_query);
|
||||||
tor_assert(nickname);
|
tor_assert(nickname);
|
||||||
log_fn(LOG_INFO,"Got nack for %s from %s, extending to %s.", circ->rend_query, circ->build_state->chosen_exit, nickname);
|
log_fn(LOG_INFO,"Got nack for %s from %s, extending to %s.", circ->rend_query, circ->build_state->chosen_exit_name, nickname);
|
||||||
if (!router_get_by_nickname(nickname)) {
|
if (!(r = router_get_by_nickname(nickname))) {
|
||||||
log_fn(LOG_WARN, "Advertised intro point '%s' for %s is not known. Closing.",
|
log_fn(LOG_WARN, "Advertised intro point '%s' for %s is not known. Closing.",
|
||||||
nickname, circ->rend_query);
|
nickname, circ->rend_query);
|
||||||
circuit_mark_for_close(circ);
|
circuit_mark_for_close(circ);
|
||||||
@ -203,8 +204,9 @@ rend_client_introduction_acked(circuit_t *circ,
|
|||||||
log_fn(LOG_INFO, "Chose new intro point %s for %s (circ %d)",
|
log_fn(LOG_INFO, "Chose new intro point %s for %s (circ %d)",
|
||||||
nickname, circ->rend_query, circ->n_circ_id);
|
nickname, circ->rend_query, circ->n_circ_id);
|
||||||
circ->state = CIRCUIT_STATE_BUILDING;
|
circ->state = CIRCUIT_STATE_BUILDING;
|
||||||
tor_free(circ->build_state->chosen_exit);
|
tor_free(circ->build_state->chosen_exit_name);
|
||||||
circ->build_state->chosen_exit = tor_strdup(nickname);
|
circ->build_state->chosen_exit_name = tor_strdup(nickname);
|
||||||
|
memcpy(circ->build_state->chosen_exit_digest, r->identity_digest, DIGEST_LEN);
|
||||||
++circ->build_state->desired_path_len;
|
++circ->build_state->desired_path_len;
|
||||||
if (circuit_send_next_onion_skin(circ)<0) {
|
if (circuit_send_next_onion_skin(circ)<0) {
|
||||||
log_fn(LOG_WARN, "Couldn't extend circuit to new intro point.");
|
log_fn(LOG_WARN, "Couldn't extend circuit to new intro point.");
|
||||||
|
@ -437,7 +437,7 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len)
|
|||||||
|
|
||||||
/* Launch a circuit to alice's chosen rendezvous point.
|
/* Launch a circuit to alice's chosen rendezvous point.
|
||||||
*/
|
*/
|
||||||
launched = circuit_launch_new(CIRCUIT_PURPOSE_S_CONNECT_REND, rp_nickname);
|
launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_CONNECT_REND, rp_nickname);
|
||||||
log_fn(LOG_INFO,
|
log_fn(LOG_INFO,
|
||||||
"Accepted intro; launching circuit to '%s' (cookie %s) for service %s",
|
"Accepted intro; launching circuit to '%s' (cookie %s) for service %s",
|
||||||
rp_nickname, hexcookie, serviceid);
|
rp_nickname, hexcookie, serviceid);
|
||||||
@ -487,18 +487,18 @@ rend_service_relaunch_rendezvous(circuit_t *oldcirc)
|
|||||||
if (!oldcirc->build_state ||
|
if (!oldcirc->build_state ||
|
||||||
oldcirc->build_state->failure_count > MAX_REND_FAILURES) {
|
oldcirc->build_state->failure_count > MAX_REND_FAILURES) {
|
||||||
log_fn(LOG_INFO,"Attempt to build circuit to %s for rendezvous has failed too many times; giving up.",
|
log_fn(LOG_INFO,"Attempt to build circuit to %s for rendezvous has failed too many times; giving up.",
|
||||||
oldcirc->build_state->chosen_exit);
|
oldcirc->build_state->chosen_exit_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_fn(LOG_INFO,"Reattempting rendezvous circuit to %s",
|
log_fn(LOG_INFO,"Reattempting rendezvous circuit to %s",
|
||||||
oldcirc->build_state->chosen_exit);
|
oldcirc->build_state->chosen_exit_name);
|
||||||
|
|
||||||
newcirc = circuit_launch_new(CIRCUIT_PURPOSE_S_CONNECT_REND,
|
newcirc = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_CONNECT_REND,
|
||||||
oldcirc->build_state->chosen_exit);
|
oldcirc->build_state->chosen_exit_name);
|
||||||
if (!newcirc) {
|
if (!newcirc) {
|
||||||
log_fn(LOG_WARN,"Couldn't relaunch rendezvous circuit to %s",
|
log_fn(LOG_WARN,"Couldn't relaunch rendezvous circuit to %s",
|
||||||
oldcirc->build_state->chosen_exit);
|
oldcirc->build_state->chosen_exit_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
oldstate = oldcirc->build_state;
|
oldstate = oldcirc->build_state;
|
||||||
@ -525,7 +525,7 @@ rend_service_launch_establish_intro(rend_service_t *service, const char *nicknam
|
|||||||
nickname, service->service_id);
|
nickname, service->service_id);
|
||||||
|
|
||||||
++service->n_intro_circuits_launched;
|
++service->n_intro_circuits_launched;
|
||||||
launched = circuit_launch_new(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, nickname);
|
launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, nickname);
|
||||||
if (!launched) {
|
if (!launched) {
|
||||||
log_fn(LOG_WARN, "Can't launch circuit to establish introduction at '%s'",
|
log_fn(LOG_WARN, "Can't launch circuit to establish introduction at '%s'",
|
||||||
nickname);
|
nickname);
|
||||||
@ -715,8 +715,8 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
|
|||||||
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
|
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
|
||||||
CIRCUIT_PURPOSE_S_INTRO))) {
|
CIRCUIT_PURPOSE_S_INTRO))) {
|
||||||
tor_assert(circ->cpath);
|
tor_assert(circ->cpath);
|
||||||
if (circ->build_state->chosen_exit &&
|
if (circ->build_state->chosen_exit_name &&
|
||||||
!strcasecmp(circ->build_state->chosen_exit, router->nickname)) {
|
!strcasecmp(circ->build_state->chosen_exit_name, router->nickname)) {
|
||||||
return circ;
|
return circ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -725,8 +725,8 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
|
|||||||
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
|
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
|
||||||
CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
|
CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
|
||||||
tor_assert(circ->cpath);
|
tor_assert(circ->cpath);
|
||||||
if (circ->build_state->chosen_exit &&
|
if (circ->build_state->chosen_exit_name &&
|
||||||
!strcasecmp(circ->build_state->chosen_exit, router->nickname)) {
|
!strcasecmp(circ->build_state->chosen_exit_name, router->nickname)) {
|
||||||
return circ;
|
return circ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,6 +394,7 @@ int router_compare_to_my_exit_policy(connection_t *conn)
|
|||||||
int router_is_me(routerinfo_t *router)
|
int router_is_me(routerinfo_t *router)
|
||||||
{
|
{
|
||||||
tor_assert(router);
|
tor_assert(router);
|
||||||
|
/* XXXX008 should compare identity instead? */
|
||||||
return options.Nickname && !strcasecmp(router->nickname, options.Nickname);
|
return options.Nickname && !strcasecmp(router->nickname, options.Nickname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,19 +207,46 @@ routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DOCDOC */
|
||||||
|
static INLINE int router_hex_digest_matches(routerinfo_t *router,
|
||||||
|
const char *hexdigest)
|
||||||
|
{
|
||||||
|
char digest[DIGEST_LEN];
|
||||||
|
tor_assert(hexdigest);
|
||||||
|
if (hexdigest[0] == '$')
|
||||||
|
++hexdigest;
|
||||||
|
|
||||||
|
if (base16_decode(digest, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return (!memcmp(digest, router->identity_digest, DIGEST_LEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DOCDOC */
|
||||||
|
int router_nickname_matches(routerinfo_t *router, const char *nickname)
|
||||||
|
{
|
||||||
|
if (nickname[0]!='$' && !strcasecmp(router->nickname, nickname))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return router_hex_digest_matches(router, nickname);
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the router in our routerlist whose (case-insensitive)
|
/** Return the router in our routerlist whose (case-insensitive)
|
||||||
* nickname or (case-sensitive) hexadecimal key digest is
|
* nickname or (case-sensitive) hexadecimal key digest is
|
||||||
* <b>nickname</b>. Return NULL if no such router is known.
|
* <b>nickname</b>. Return NULL if no such router is known.
|
||||||
*/
|
*/
|
||||||
routerinfo_t *router_get_by_nickname(const char *nickname)
|
routerinfo_t *router_get_by_nickname(const char *nickname)
|
||||||
{
|
{
|
||||||
int i, maybedigest;
|
int i, maybedigest, mustbedigest;
|
||||||
routerinfo_t *router;
|
routerinfo_t *router;
|
||||||
char digest[DIGEST_LEN];
|
char digest[DIGEST_LEN];
|
||||||
|
|
||||||
tor_assert(nickname);
|
tor_assert(nickname);
|
||||||
if (!routerlist)
|
if (!routerlist)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (nickname[0] == '$')
|
||||||
|
return router_get_by_hexdigest(nickname);
|
||||||
|
|
||||||
maybedigest = (strlen(nickname) == HEX_DIGEST_LEN) &&
|
maybedigest = (strlen(nickname) == HEX_DIGEST_LEN) &&
|
||||||
(base16_decode(digest,DIGEST_LEN,nickname,HEX_DIGEST_LEN) == 0);
|
(base16_decode(digest,DIGEST_LEN,nickname,HEX_DIGEST_LEN) == 0);
|
||||||
|
|
||||||
@ -242,6 +269,8 @@ routerinfo_t *router_get_by_hexdigest(const char *hexdigest) {
|
|||||||
tor_assert(hexdigest);
|
tor_assert(hexdigest);
|
||||||
if (!routerlist)
|
if (!routerlist)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (hexdigest[0]=='$')
|
||||||
|
++hexdigest;
|
||||||
if (strlen(hexdigest) != HEX_DIGEST_LEN ||
|
if (strlen(hexdigest) != HEX_DIGEST_LEN ||
|
||||||
base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN) < 0)
|
base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -326,10 +355,10 @@ void routerlist_free(routerlist_t *rl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Mark the router named <b>nickname</b> as non-running in our routerlist. */
|
/** Mark the router named <b>nickname</b> as non-running in our routerlist. */
|
||||||
void router_mark_as_down(char *nickname) {
|
void router_mark_as_down(const char *digest) {
|
||||||
routerinfo_t *router;
|
routerinfo_t *router;
|
||||||
tor_assert(nickname);
|
tor_assert(digest);
|
||||||
router = router_get_by_nickname(nickname);
|
router = router_get_by_digest(digest);
|
||||||
if(!router) /* we don't seem to know about him in the first place */
|
if(!router) /* we don't seem to know about him in the first place */
|
||||||
return;
|
return;
|
||||||
log_fn(LOG_DEBUG,"Marking %s as down.",router->nickname);
|
log_fn(LOG_DEBUG,"Marking %s as down.",router->nickname);
|
||||||
@ -350,6 +379,7 @@ int router_add_to_routerlist(routerinfo_t *router) {
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
|
for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
|
||||||
r = smartlist_get(routerlist->routers, i);
|
r = smartlist_get(routerlist->routers, i);
|
||||||
|
/* XXXX008 should just compare digests instead. */
|
||||||
if (!strcasecmp(router->nickname, r->nickname)) {
|
if (!strcasecmp(router->nickname, r->nickname)) {
|
||||||
if (!crypto_pk_cmp_keys(router->identity_pkey, r->identity_pkey)) {
|
if (!crypto_pk_cmp_keys(router->identity_pkey, r->identity_pkey)) {
|
||||||
if (router->published_on > r->published_on) {
|
if (router->published_on > r->published_on) {
|
||||||
@ -377,6 +407,8 @@ int router_add_to_routerlist(routerinfo_t *router) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* XXXX008 It's okay to have two keys for a nickname as soon as
|
||||||
|
* all the 007 clients are dead. */
|
||||||
log_fn(LOG_WARN, "Identity key mismatch for router '%s'",
|
log_fn(LOG_WARN, "Identity key mismatch for router '%s'",
|
||||||
router->nickname);
|
router->nickname);
|
||||||
routerinfo_free(router);
|
routerinfo_free(router);
|
||||||
@ -698,16 +730,19 @@ void routerlist_update_from_runningrouters(routerlist_t *list,
|
|||||||
router = smartlist_get(list->routers, i);
|
router = smartlist_get(list->routers, i);
|
||||||
for (j=0; j<n_names; ++j) {
|
for (j=0; j<n_names; ++j) {
|
||||||
name = smartlist_get(rr->running_routers, j);
|
name = smartlist_get(rr->running_routers, j);
|
||||||
if (!strcasecmp(name, router->nickname)) {
|
if (*name != '!') {
|
||||||
|
if (router_nickname_matches(router, name)) {
|
||||||
router->is_running = 1;
|
router->is_running = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*name == '!' && strcasecmp(name+1, router->nickname)) {
|
} else { /* *name == '!' */
|
||||||
|
if (router_nickname_matches(router, name)) {
|
||||||
router->is_running = 0;
|
router->is_running = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
list->running_routers_updated_on = rr->published_on;
|
list->running_routers_updated_on = rr->published_on;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +539,7 @@ static int check_directory_signature(const char *digest,
|
|||||||
int
|
int
|
||||||
router_parse_list_from_string(const char **s, routerlist_t **dest,
|
router_parse_list_from_string(const char **s, routerlist_t **dest,
|
||||||
int n_good_nicknames,
|
int n_good_nicknames,
|
||||||
const char **good_nickname_lst)
|
const char **good_nickname_list)
|
||||||
{
|
{
|
||||||
routerinfo_t *router;
|
routerinfo_t *router;
|
||||||
smartlist_t *routers;
|
smartlist_t *routers;
|
||||||
@ -574,7 +574,7 @@ router_parse_list_from_string(const char **s, routerlist_t **dest,
|
|||||||
if (n_good_nicknames>=0) {
|
if (n_good_nicknames>=0) {
|
||||||
router->is_running = 0;
|
router->is_running = 0;
|
||||||
for (i = 0; i < n_good_nicknames; ++i) {
|
for (i = 0; i < n_good_nicknames; ++i) {
|
||||||
if (0==strcasecmp(good_nickname_lst[i], router->nickname)) {
|
if (router_nickname_matches(router, good_nickname_list[i])) {
|
||||||
router->is_running = 1;
|
router->is_running = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -420,6 +420,17 @@ test_crypto()
|
|||||||
test_eq(i,0);
|
test_eq(i,0);
|
||||||
test_streq(data2, "772w2rfobvomsywe");
|
test_streq(data2, "772w2rfobvomsywe");
|
||||||
|
|
||||||
|
/* Base16 tests */
|
||||||
|
strcpy(data1, "6chrs\xff");
|
||||||
|
i = base16_encode(data2, 13, data1, 6);
|
||||||
|
test_eq(i,0);
|
||||||
|
test_streq(data2, "3663687273FF");
|
||||||
|
|
||||||
|
strcpy(data1, "f0d678affc000100");
|
||||||
|
i = base16_decode(data2, 8, data1, 16);
|
||||||
|
test_eq(i,0);
|
||||||
|
test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);
|
||||||
|
|
||||||
free(data1);
|
free(data1);
|
||||||
free(data2);
|
free(data2);
|
||||||
free(data3);
|
free(data3);
|
||||||
|
Loading…
Reference in New Issue
Block a user