summaryrefslogtreecommitdiff
path: root/src/or/rendservice.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2007-12-21 09:28:22 +0000
committerRoger Dingledine <arma@torproject.org>2007-12-21 09:28:22 +0000
commit90fcfade4ef7d290a1da4540187196ce873c71b0 (patch)
tree73afa52875affcc0bdb64ae0033b4ca3058dc7a6 /src/or/rendservice.c
parente710710e87e450d25c5729658ba711478d915cb1 (diff)
downloadtor-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.c168
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);