aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Baines <cb15g11@soton.ac.uk>2014-03-17 21:15:09 +0000
committerChristopher Baines <cb15g11@soton.ac.uk>2014-03-17 21:15:09 +0000
commit78ecaeccb273754b4dfd9f026533b525535f4a84 (patch)
treeff44262a21da9ae3260272a42ddeef5807c29df7
parent4f2f14df95f802e164aa22bb2131f80da127c84e (diff)
downloadtor-78ecaeccb273754b4dfd9f026533b525535f4a84.tar
tor-78ecaeccb273754b4dfd9f026533b525535f4a84.tar.gz
Some more ip selection stuff
-rw-r--r--src/or/circuituse.c2
-rw-r--r--src/or/rendservice.c259
-rw-r--r--src/or/routerlist.c41
-rw-r--r--src/or/routerlist.h5
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);