diff options
author | Christopher Baines <cb15g11@soton.ac.uk> | 2014-03-17 21:15:09 +0000 |
---|---|---|
committer | Christopher Baines <cb15g11@soton.ac.uk> | 2014-03-17 21:15:09 +0000 |
commit | 78ecaeccb273754b4dfd9f026533b525535f4a84 (patch) | |
tree | ff44262a21da9ae3260272a42ddeef5807c29df7 | |
parent | 4f2f14df95f802e164aa22bb2131f80da127c84e (diff) | |
download | tor-78ecaeccb273754b4dfd9f026533b525535f4a84.tar tor-78ecaeccb273754b4dfd9f026533b525535f4a84.tar.gz |
Some more ip selection stuff
-rw-r--r-- | src/or/circuituse.c | 2 | ||||
-rw-r--r-- | src/or/rendservice.c | 259 | ||||
-rw-r--r-- | src/or/routerlist.c | 41 | ||||
-rw-r--r-- | src/or/routerlist.h | 5 |
4 files changed, 185 insertions, 122 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 8b82de0f9..54986749e 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1557,9 +1557,9 @@ circuit_launch_by_extend_info(uint8_t purpose, switch (purpose) { case CIRCUIT_PURPOSE_C_ESTABLISH_REND: - case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO: /* it's ready right now */ break; + case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO: case CIRCUIT_PURPOSE_C_INTRODUCING: case CIRCUIT_PURPOSE_S_CONNECT_REND: case CIRCUIT_PURPOSE_C_GENERAL: diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 3edb917c5..805b5da61 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -2342,11 +2342,10 @@ rend_service_launch_establish_intro(rend_service_t *service, base16_encode(orig, sizeof(orig), intro->extend_info->identity_digest, DIGEST_LEN); log_info(LD_REND, "The intro circuit %u we just cannibalized ends at $%s, " - "but we requested an intro circuit to $%s. Updating " - "our service.", (unsigned)launched->base_.n_circ_id, + "but we requested an intro circuit to $%s. Aborting", + (unsigned)launched->base_.n_circ_id, cann, orig); - extend_info_free(intro->extend_info); - intro->extend_info = extend_info_dup(launched->build_state->chosen_exit); + return -1; } launched->rend_data = tor_malloc_zero(sizeof(rend_data_t)); @@ -3017,7 +3016,7 @@ rend_services_introduce(void) unsigned int n_intro_points_to_open; smartlist_t *intro_nodes; time_t now; - const or_options_t *options = get_options(); + // const or_options_t *options = get_options(); unused intro_nodes = smartlist_new(); now = time(NULL); @@ -3141,148 +3140,166 @@ rend_services_introduce(void) * to. XXXX This is daft. */ prev_intro_nodes = smartlist_len(service->intro_nodes); - log_info(LD_REND, "Checking for existing descriptor"); - log_info(LD_REND, "pk_digest %s", safe_str_client(service->service_id)); + log_info(LD_REND, "n_intro_points_unexpired %i", n_intro_points_unexpired); + log_info(LD_REND, "prev_intro_nodes %i", prev_intro_nodes); rend_cache_entry_t *entry; int descriptor_available = (rend_cache_lookup_entry(service->service_id, -1, &entry) == 1); - if (descriptor_available) { + int establish_intros = 1; + + if (n_intro_points_unexpired == 0) { + log_info(LD_REND, "Currently no introduction points"); + + establish_intros = 0; + + if (descriptor_available) { // Need to think about connecting to these introduction points now log_info(LD_REND, "Descriptor available for %s, with %i introduction points", safe_str_client(service->service_id), smartlist_len(entry->parsed->intro_nodes)); SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *, intro, { - log_info(LD_REND, "Found router %s as an existing intro point for %s.", - safe_str_client(intro_describe(intro)), - safe_str_client(service->service_id)); - - int existing = 0; - - SMARTLIST_FOREACH(service->intro_nodes, rend_intro_point_t *, existing_intro, { - // Unsure if this is the correct way to check - if (strcasecmp(existing_intro->extend_info->identity_digest, intro->extend_info->identity_digest) == 0) { - existing = 1; - // break, unsure if works - } - }); - - if (existing == 0) { - log_info(LD_REND, "Also connecting to %s.", - safe_str_client(intro_describe(intro))); - - rend_intro_point_t *new_intro = tor_malloc_zero(sizeof(rend_intro_point_t)); - memcpy((void*) new_intro, intro, sizeof(rend_intro_point_t)); - - intro->intro_key = crypto_pk_new(); - tor_assert(!crypto_pk_generate_key(intro->intro_key)); - intro->time_published = -1; - intro->time_to_expire = -1; - intro->time_expiring = -1; - - smartlist_add(service->intro_nodes, intro); - - intro_point_set_changed = 1; - } else { - log_info(LD_REND, "Already connected to %s, ignoring.", - safe_str_client(intro_describe(intro))); + log_info(LD_REND, "Found router %s as an existing intro point for %s.", + safe_str_client(intro_describe(intro)), + safe_str_client(service->service_id)); + + int existing = 0; + + SMARTLIST_FOREACH(service->intro_nodes, rend_intro_point_t *, existing_intro, { + // Unsure if this is the correct way to check + if (strcasecmp(existing_intro->extend_info->identity_digest, intro->extend_info->identity_digest) == 0) { + existing = 1; + // break, unsure if works } + }); + + if (existing == 0) { + log_info(LD_REND, "Also connecting to %s.", + safe_str_client(intro_describe(intro))); + + rend_intro_point_t *new_intro = tor_malloc_zero(sizeof(rend_intro_point_t)); + memcpy((void*) new_intro, intro, sizeof(rend_intro_point_t)); + + intro->intro_key = crypto_pk_new(); + tor_assert(!crypto_pk_generate_key(intro->intro_key)); + intro->time_published = -1; + intro->time_to_expire = -1; + intro->time_expiring = -1; + + smartlist_add(service->intro_nodes, intro); + + intro_point_set_changed = 1; + } else { + log_info(LD_REND, "Already connected to %s, ignoring.", + safe_str_client(intro_describe(intro))); + } }); log_info(LD_REND, "Finished checking introduction points for %s", safe_str_client(service->service_id)); - } else { + } else { // If the descriptor has not been fetched recently if (now > service->descriptor_fetch_time+(60*5)) { - // Example from rendclient.c:168 + // Example from rendclient.c:168 - log_info(LD_REND, - "query %s didn't have valid rend desc in cache. " - "Fetching descriptor.", - safe_str_client(service->service_id)); + log_info(LD_REND, + "query %s didn't have valid rend desc in cache. " + "Fetching descriptor.", + safe_str_client(service->service_id)); - rend_data_t *rend_data = tor_malloc_zero(sizeof(rend_data_t)); // TODO: remember to free + rend_data_t *rend_data = tor_malloc_zero(sizeof(rend_data_t)); // TODO: remember to free - strlcpy(rend_data->onion_address, service->service_id, - sizeof(rend_data->onion_address)); + strlcpy(rend_data->onion_address, service->service_id, + sizeof(rend_data->onion_address)); - memcpy((void*) &rend_data->auth_type, - (void*) &service->auth_type, - sizeof(rend_auth_type_t)); + memcpy((void*) &rend_data->auth_type, + (void*) &service->auth_type, + sizeof(rend_auth_type_t)); - rend_client_refetch_v2_renddesc(rend_data); + rend_client_refetch_v2_renddesc(rend_data); - service->descriptor_fetch_time = now; + service->descriptor_fetch_time = now; - { // TODO: Unsure what this does? - connection_t *conn; + { // TODO: Unsure what this does? + connection_t *conn; - while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP, - AP_CONN_STATE_CIRCUIT_WAIT, // Waiting for a circuit - rend_data->onion_address))) { - conn->state = AP_CONN_STATE_RENDDESC_WAIT; // Change state to waiting to receive the descriptor - } - } - } else { // Descriptor has been recently fetched - if (now > service->descriptor_fetch_time+30) { - // Forget about trying to get the descriptor - - log_info(LD_REND, - "query %s didn't have valid rend desc in cache. " - "Connecting to random introduction points", - safe_str_client(service->service_id)); - - /* We have enough directory information to start establishing our - * intro points. We want to end up with n_intro_points_wanted - * intro points, but if we're just starting, we launch two extra - * circuits and use the first n_intro_points_wanted that complete. - * - * The ones after the first three will be converted to 'general' - * internal circuits in rend_service_intro_has_opened(), and then - * we'll drop them from the list of intro points next time we - * go through the above "find out which introduction points we have - * in progress" loop. */ - n_intro_points_to_open = (service->n_intro_points_wanted + - (prev_intro_nodes == 0 ? 2 : 0)); - for (j = (int)n_intro_points_unexpired; - j < (int)n_intro_points_to_open; - ++j) { /* XXXX remove casts */ - router_crn_flags_t flags = CRN_NEED_UPTIME|CRN_NEED_DESC; - if (get_options()->AllowInvalid_ & ALLOW_INVALID_INTRODUCTION) - flags |= CRN_ALLOW_INVALID; - node = router_choose_random_node(intro_nodes, - options->ExcludeNodes, flags); - if (!node) { - log_warn(LD_REND, - "Could only establish %d introduction points for %s; " - "wanted %u.", - smartlist_len(service->intro_nodes), service->service_id, - n_intro_points_to_open); - break; - } - intro_point_set_changed = 1; - smartlist_add(intro_nodes, (void*)node); - intro = tor_malloc_zero(sizeof(rend_intro_point_t)); - intro->extend_info = extend_info_from_node(node, 0); - intro->intro_key = crypto_pk_new(); - tor_assert(!crypto_pk_generate_key(intro->intro_key)); - intro->time_published = -1; - intro->time_to_expire = -1; - intro->time_expiring = -1; - smartlist_add(service->intro_nodes, intro); - log_info(LD_REND, "Picked router %s as an intro point for %s.", - safe_str_client(node_describe(node)), - safe_str_client(service->service_id)); - } - } else { - // Continue wating for the descriptor - log_info(LD_REND, - "query %s didn't have valid rend desc in cache. " - "Waiting for descriptor", - safe_str_client(service->service_id)); - continue; + while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP, + AP_CONN_STATE_CIRCUIT_WAIT, // Waiting for a circuit + rend_data->onion_address))) { + conn->state = AP_CONN_STATE_RENDDESC_WAIT; // Change state to waiting to receive the descriptor } + } + } else if (now < service->descriptor_fetch_time+30) { + // Continue wating for the descriptor + log_info(LD_REND, + "query %s didn't have valid rend desc in cache. " + "Waiting for descriptor", + safe_str_client(service->service_id)); + } else { + establish_intros = 1; } + } + } + + log_info(LD_REND, "establish_intros %i", establish_intros); + + if (establish_intros == 1) { + /* We have enough directory information to start establishing our + * intro points. We want to end up with n_intro_points_wanted + * intro points, but if we're just starting, we launch two extra + * circuits and use the first n_intro_points_wanted that complete. + * + * The ones after the first three will be converted to 'general' + * internal circuits in rend_service_intro_has_opened(), and then + * we'll drop them from the list of intro points next time we + * go through the above "find out which introduction points we have + * in progress" loop. */ + n_intro_points_to_open = service->n_intro_points_wanted - + n_intro_points_unexpired + + (prev_intro_nodes == 0 ? 2 : 0); + + log_info(LD_REND, "n_intro_points_to_open %i", n_intro_points_to_open); + + if (n_intro_points_to_open != 0) { + + log_info(LD_REND, + "query %s didn't have valid rend desc in cache. " + "Connecting to random introduction points", + safe_str_client(service->service_id)); + + smartlist_t *potential_introduction_points = smartlist_new(); + + if (hid_serv_get_introduction_points(potential_introduction_points, + n_intro_points_to_open, + intro_nodes, + service->service_id) < 0) { + log_warn(LD_REND, "Could not find any new introduction points"); + smartlist_free(potential_introduction_points); + return; + } + + const node_t *node; + for (j = 0; j < smartlist_len(potential_introduction_points); j++) { + log_info(LD_REND, + "looking at introduction point %i ", + j); + node = smartlist_get(potential_introduction_points, j); + + intro_point_set_changed = 1; + smartlist_add(intro_nodes, (void*)node); + intro = tor_malloc_zero(sizeof(rend_intro_point_t)); + intro->extend_info = extend_info_from_node(node, 0); + intro->intro_key = crypto_pk_new(); + tor_assert(!crypto_pk_generate_key(intro->intro_key)); + intro->time_published = -1; + intro->time_to_expire = -1; + intro->time_expiring = -1; + smartlist_add(service->intro_nodes, intro); + log_info(LD_REND, "Picked router %s as an intro point for %s.", + safe_str_client(node_describe(node)), + safe_str_client(service->service_id)); + } + } } /* If there's no need to launch new circuits, stop here. */ diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 2db72722d..6382248e4 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -5046,6 +5046,47 @@ hid_serv_get_responsible_directories(smartlist_t *responsible_dirs, return smartlist_len(responsible_dirs) ? 0 : -1; } +int +hid_serv_get_introduction_points(smartlist_t *introduction_points, + int number, + smartlist_t *excludedsmartlist, + const char *id) +{ + int start, found, i; + + networkstatus_t *c = networkstatus_get_latest_consensus(); + if (!c || !smartlist_len(c->routerstatus_list)) { + log_warn(LD_REND, "We don't have a consensus, so determine introduction " + "points"); + return -1; + } + tor_assert(id); + start = networkstatus_vote_find_entry_idx(c, id, &found); + if (start == smartlist_len(c->routerstatus_list)) start = 0; + i = start; + do { + routerstatus_t *r = smartlist_get(c->routerstatus_list, i); + + node_t *node = node_get_by_id(r->identity_digest); + + if (!excludedsmartlist || !smartlist_contains(excludedsmartlist, node)) { + smartlist_add(introduction_points, node); + if (--number <= 0) + return 0; + } else { + log_warn(LD_REND, "Ignoring node %s ", + safe_str_client(node_describe(node))); + } + + if (++i == smartlist_len(c->routerstatus_list)) + i = 0; + } while (i != start); + + /* Even though we don't have the desired number of hidden service + * directories, be happy if we got any. */ + return smartlist_len(introduction_points) ? 0 : -1; +} + /** Return true if this node is currently acting as hidden service * directory, false otherwise. */ int diff --git a/src/or/routerlist.h b/src/or/routerlist.h index cfa868386..2b1215353 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -181,6 +181,11 @@ void refresh_all_country_info(void); int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs, const char *id); +int hid_serv_get_introduction_points(smartlist_t *introduction_points, + int number, + smartlist_t *excludedsmartlist, + const char *id); + int hid_serv_acting_as_directory(void); int hid_serv_responsible_for_desc_id(const char *id); |