diff options
author | Roger Dingledine <arma@torproject.org> | 2007-12-21 09:28:22 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2007-12-21 09:28:22 +0000 |
commit | 90fcfade4ef7d290a1da4540187196ce873c71b0 (patch) | |
tree | 73afa52875affcc0bdb64ae0033b4ca3058dc7a6 /src/or/rendservice.c | |
parent | e710710e87e450d25c5729658ba711478d915cb1 (diff) | |
download | tor-90fcfade4ef7d290a1da4540187196ce873c71b0.tar.gz tor-90fcfade4ef7d290a1da4540187196ce873c71b0.zip |
revert r12841 and r12842, and commit karsten's "patch 13"
svn:r12900
Diffstat (limited to 'src/or/rendservice.c')
-rw-r--r-- | src/or/rendservice.c | 168 |
1 files changed, 62 insertions, 106 deletions
diff --git a/src/or/rendservice.c b/src/or/rendservice.c index e8764bc8e9..cd8af9f19a 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -12,8 +12,9 @@ const char rendservice_c_id[] = #include "or.h" -static origin_circuit_t *find_intro_circuit(routerinfo_t *router, - const char *pk_digest); +static origin_circuit_t *find_intro_circuit(rend_intro_point_t *intro, + const char *pk_digest, + int desc_version); /** Represents the mapping from a virtual port of a rendezvous service to * a real port on some IP. @@ -50,10 +51,8 @@ typedef struct rend_service_t { crypto_pk_env_t *private_key; char service_id[REND_SERVICE_ID_LEN_BASE32+1]; char pk_digest[DIGEST_LEN]; - smartlist_t *intro_nodes; /**< list of hexdigests for intro points we have, + smartlist_t *intro_nodes; /**< List of rend_intro_point_t's we have, * or are trying to establish. */ - strmap_t *intro_keys; /**< map from intro node hexdigest to key; only - * used for versioned hidden service descriptors. */ time_t intro_period_started; int n_intro_circuits_launched; /**< count of intro circuits we have * established in this period. */ @@ -78,15 +77,6 @@ num_rend_services(void) return smartlist_len(rend_service_list); } -/** Helper: Release the storage held by the intro key in <b>_ent</b>. - */ -static void -intro_key_free(void *_ent) -{ - crypto_pk_env_t *ent = _ent; - crypto_free_pk_env(ent); -} - /** Release the storage held by <b>service</b>. */ static void @@ -98,12 +88,13 @@ rend_service_free(rend_service_t *service) smartlist_free(service->ports); if (service->private_key) crypto_free_pk_env(service->private_key); - if (service->intro_keys) - strmap_free(service->intro_keys, intro_key_free); + if (service->intro_nodes) { + SMARTLIST_FOREACH(service->intro_nodes, rend_intro_point_t *, intro, + rend_intro_point_free(intro);); + smartlist_free(service->intro_nodes); + } tor_free(service->intro_prefer_nodes); tor_free(service->intro_exclude_nodes); - SMARTLIST_FOREACH(service->intro_nodes, void*, p, tor_free(p)); - smartlist_free(service->intro_nodes); if (service->desc) rend_service_descriptor_free(service->desc); tor_free(service); @@ -137,7 +128,6 @@ rend_add_service(rend_service_t *service) if (!service->intro_exclude_nodes) service->intro_exclude_nodes = tor_strdup(""); service->intro_nodes = smartlist_create(); - service->intro_keys = strmap_new(); /* If the service is configured to publish unversioned (v0) and versioned * descriptors (v2 or higher), split it up into two separate services. */ @@ -151,7 +141,6 @@ rend_add_service(rend_service_t *service) memcpy(copy, p, sizeof(rend_service_port_config_t)); smartlist_add(v0_service->ports, copy); }); - v0_service->intro_nodes = smartlist_create(); v0_service->intro_prefer_nodes = tor_strdup(service->intro_prefer_nodes); v0_service->intro_exclude_nodes = tor_strdup(service->intro_exclude_nodes); v0_service->intro_period_started = service->intro_period_started; @@ -273,7 +262,6 @@ rend_config_services(or_options_t *options, int validate_only) service = tor_malloc_zero(sizeof(rend_service_t)); service->directory = tor_strdup(line->value); service->ports = smartlist_create(); - service->intro_nodes = smartlist_create(); service->intro_period_started = time(NULL); service->descriptor_version = -1; /**< All descriptor versions. */ continue; @@ -349,8 +337,7 @@ rend_service_update_descriptor(rend_service_t *service) { rend_service_descriptor_t *d; origin_circuit_t *circ; - int i,n; - routerinfo_t *router; + int i; if (service->desc) { rend_service_descriptor_free(service->desc); service->desc = NULL; @@ -359,46 +346,24 @@ rend_service_update_descriptor(rend_service_t *service) d->pk = crypto_pk_dup_key(service->private_key); d->timestamp = time(NULL); d->version = service->descriptor_version; - n = smartlist_len(service->intro_nodes); - d->n_intro_points = 0; - d->intro_points = tor_malloc_zero(sizeof(char*)*n); - d->intro_point_extend_info = tor_malloc_zero(sizeof(extend_info_t*)*n); + d->intro_nodes = smartlist_create(); /* XXXX020 Why should we support the old intro protocol 0? Whoever * understands descriptor version 2 also understands intro protocol 2. */ d->protocols = 1 << 2; /*< We only support intro protocol 2. */ - if (service->intro_keys) { - /* We need to copy keys so that they're not deleted when we free the - * descriptor. */ - strmap_iter_t *iter; - d->intro_keys = strmap_new(); - for (iter = strmap_iter_init(service->intro_keys); !strmap_iter_done(iter); - iter = strmap_iter_next(service->intro_keys, iter)) { - const char *key; - void *val; - crypto_pk_env_t *k; - strmap_iter_get(iter, &key, &val); - k = val; - strmap_set(d->intro_keys, key, crypto_pk_dup_key(k)); - } - } - - for (i=0; i < n; ++i) { - const char *name = smartlist_get(service->intro_nodes, i); - router = router_get_by_nickname(name, 1); - if (!router) { - log_info(LD_REND,"Router '%s' not found for intro point %d. Skipping.", - safe_str(name), i); + for (i = 0; i < smartlist_len(service->intro_nodes); ++i) { + rend_intro_point_t *intro_svc = smartlist_get(service->intro_nodes, i); + rend_intro_point_t *intro_desc; + circ = find_intro_circuit(intro_svc, service->pk_digest, d->version); + if (!circ || circ->_base.purpose != CIRCUIT_PURPOSE_S_INTRO) continue; - } - circ = find_intro_circuit(router, service->pk_digest); - if (circ && circ->_base.purpose == CIRCUIT_PURPOSE_S_INTRO) { - /* We have an entirely established intro circuit. */ - d->intro_points[d->n_intro_points] = tor_strdup(name); - d->intro_point_extend_info[d->n_intro_points] = - extend_info_from_router(router); - d->n_intro_points++; - } + + /* We have an entirely established intro circuit. */ + intro_desc = tor_malloc_zero(sizeof(rend_intro_point_t)); + intro_desc->extend_info = extend_info_dup(intro_svc->extend_info); + if (intro_svc->intro_key) + intro_desc->intro_key = crypto_pk_dup_key(intro_svc->intro_key); + smartlist_add(d->intro_nodes, intro_desc); } } @@ -791,35 +756,32 @@ rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc) */ static int rend_service_launch_establish_intro(rend_service_t *service, - const char *nickname) + rend_intro_point_t *intro) { origin_circuit_t *launched; log_info(LD_REND, "Launching circuit to introduction point %s for service %s", - escaped_safe_str(nickname), service->service_id); + escaped_safe_str(intro->extend_info->nickname), + service->service_id); rep_hist_note_used_internal(time(NULL), 1, 0); ++service->n_intro_circuits_launched; - launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, 0, - nickname, 1, 0, 1); + launched = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, + 0, intro->extend_info, 1, 0, 1); if (!launched) { log_info(LD_REND, "Can't launch circuit to establish introduction at %s.", - escaped_safe_str(nickname)); + escaped_safe_str(intro->extend_info->nickname)); return -1; } strlcpy(launched->rend_query, service->service_id, sizeof(launched->rend_query)); memcpy(launched->rend_pk_digest, service->pk_digest, DIGEST_LEN); launched->rend_desc_version = service->descriptor_version; - if (service->descriptor_version == 2) { - launched->intro_key = crypto_new_pk_env(); - tor_assert(!crypto_pk_generate_key(launched->intro_key)); - strmap_set(service->intro_keys, nickname, - crypto_pk_dup_key(launched->intro_key)); - } + if (service->descriptor_version == 2) + launched->intro_key = crypto_pk_dup_key(intro->intro_key); if (launched->_base.state == CIRCUIT_STATE_OPEN) rend_service_intro_has_opened(launched); return 0; @@ -1024,19 +986,22 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) */ /** Return the (possibly non-open) introduction circuit ending at - * <b>router</b> for the service whose public key is <b>pk_digest</b>. Return + * <b>intro</b> for the service whose public key is <b>pk_digest</b> and + * which publishes descriptor of version <b>desc_version</b>. Return * NULL if no such service is found. */ static origin_circuit_t * -find_intro_circuit(routerinfo_t *router, const char *pk_digest) +find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest, + int desc_version) { origin_circuit_t *circ = NULL; - tor_assert(router); + tor_assert(intro); while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, CIRCUIT_PURPOSE_S_INTRO))) { - if (!strcasecmp(circ->build_state->chosen_exit->nickname, - router->nickname)) { + if (!strcasecmp(circ->build_state->chosen_exit->identity_digest, + intro->extend_info->identity_digest) && + circ->rend_desc_version == desc_version) { return circ; } } @@ -1044,8 +1009,9 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest) circ = NULL; while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) { - if (!strcasecmp(circ->build_state->chosen_exit->nickname, - router->nickname)) { + if (!strcasecmp(circ->build_state->chosen_exit->identity_digest, + intro->extend_info->identity_digest) && + circ->rend_desc_version == desc_version) { return circ; } } @@ -1168,7 +1134,7 @@ rend_services_introduce(void) int i,j,r; routerinfo_t *router; rend_service_t *service; - char *intro; + rend_intro_point_t *intro; int changed, prev_intro_nodes; smartlist_t *intro_routers, *exclude_routers; time_t now; @@ -1198,12 +1164,12 @@ rend_services_introduce(void) service. */ for (j=0; j < smartlist_len(service->intro_nodes); ++j) { intro = smartlist_get(service->intro_nodes, j); - router = router_get_by_nickname(intro, 0); - if (!router || !find_intro_circuit(router,service->pk_digest)) { + router = router_get_by_digest(intro->extend_info->identity_digest); + if (!router || !find_intro_circuit(intro, service->pk_digest, + service->descriptor_version)) { log_info(LD_REND,"Giving up on %s as intro point for %s.", - intro, service->service_id); - tor_free(intro); - /* XXXXX020 we could also remove the intro key here. */ + intro->extend_info->nickname, service->service_id); + rend_intro_point_free(intro); smartlist_del(service->intro_nodes,j--); changed = 1; service->desc_is_dirty = now; @@ -1228,7 +1194,6 @@ rend_services_introduce(void) smartlist_add_all(exclude_routers, intro_routers); /* The directory is now here. Pick three ORs as intro points. */ for (j=prev_intro_nodes; j < NUM_INTRO_POINTS; ++j) { - char *hex_digest; router = router_choose_random_node(service->intro_prefer_nodes, service->intro_exclude_nodes, exclude_routers, 1, 0, 0, get_options()->_AllowInvalid & ALLOW_INVALID_INTRODUCTION, @@ -1240,14 +1205,15 @@ rend_services_introduce(void) break; } changed = 1; - hex_digest = tor_malloc_zero(HEX_DIGEST_LEN+2); - hex_digest[0] = '$'; - base16_encode(hex_digest+1, HEX_DIGEST_LEN+1, - router->cache_info.identity_digest, - DIGEST_LEN); smartlist_add(intro_routers, router); smartlist_add(exclude_routers, router); - smartlist_add(service->intro_nodes, hex_digest); + intro = tor_malloc_zero(sizeof(rend_intro_point_t)); + intro->extend_info = extend_info_from_router(router); + if (service->descriptor_version == 2) { + intro->intro_key = crypto_new_pk_env(); + tor_assert(!crypto_pk_generate_key(intro->intro_key)); + } + smartlist_add(service->intro_nodes, intro); log_info(LD_REND, "Picked router %s as an intro point for %s.", router->nickname, service->service_id); } @@ -1265,7 +1231,7 @@ rend_services_introduce(void) r = rend_service_launch_establish_intro(service, intro); if (r<0) { log_warn(LD_REND, "Error launching circuit to node %s for service %s.", - intro, service->service_id); + intro->extend_info->nickname, service->service_id); } } } @@ -1315,10 +1281,9 @@ void rend_service_dump_stats(int severity) { int i,j; - routerinfo_t *router; rend_service_t *service; - const char *nickname, *safe_name; - char nn_buf[MAX_VERBOSE_NICKNAME_LEN]; + rend_intro_point_t *intro; + const char *safe_name; origin_circuit_t *circ; for (i=0; i < smartlist_len(rend_service_list); ++i) { @@ -1326,20 +1291,11 @@ rend_service_dump_stats(int severity) log(severity, LD_GENERAL, "Service configured in \"%s\":", service->directory); for (j=0; j < smartlist_len(service->intro_nodes); ++j) { - nickname = smartlist_get(service->intro_nodes, j); - router = router_get_by_nickname(nickname,1); - if (router) { - router_get_verbose_nickname(nn_buf, router); - nickname = nn_buf; - } - safe_name = safe_str(nickname); + intro = smartlist_get(service->intro_nodes, j); + safe_name = safe_str(intro->extend_info->nickname); - if (!router) { - log(severity, LD_GENERAL, - " Intro point %d at %s: unrecognized router", j, safe_name); - continue; - } - circ = find_intro_circuit(router, service->pk_digest); + circ = find_intro_circuit(intro, service->pk_digest, + service->descriptor_version); if (!circ) { log(severity, LD_GENERAL, " Intro point %d at %s: no circuit", j, safe_name); |