diff options
author | Roger Dingledine <arma@torproject.org> | 2007-01-27 19:29:16 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2007-01-27 19:29:16 +0000 |
commit | add7d7af195109a06c46c6072b3a4faf4f6ce363 (patch) | |
tree | 33e15ddf3f3fcf3e9797a913e0571ae5da13f518 | |
parent | 0e01dda145d372840011ad168d61b30b2b6cde32 (diff) | |
download | tor-add7d7af195109a06c46c6072b3a4faf4f6ce363.tar.gz tor-add7d7af195109a06c46c6072b3a4faf4f6ce363.zip |
Bring us one step closer to being able to establish an encrypted
directory tunnel without knowing a descriptor first. Still not
ready yet. As part of the change, now assume we can use a
create_fast cell if we don't know anything about a router.
svn:r9440
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 57 | ||||
-rw-r--r-- | src/or/circuituse.c | 40 | ||||
-rw-r--r-- | src/or/or.h | 7 |
4 files changed, 84 insertions, 24 deletions
@@ -75,6 +75,10 @@ Changes in version 0.1.2.7-alpha - 2007-??-?? - Inform the server operator when we decide not to advertise a DirPort due to AccountingMax enabled or a low BandwidthRate. It was confusing Zax, so now we're hopefully more helpful. + - Bring us one step closer to being able to establish an encrypted + directory tunnel without knowing a descriptor first. Still not + ready yet. As part of the change, now assume we can use a + create_fast cell if we don't know anything about a router. o Minor features (controller): - Track reasons for OR connection failure; make these reasons diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 74096300b0..416017ccb4 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -519,20 +519,28 @@ inform_testing_reachability(void) } /** Return true iff we should send a create_fast cell to build a circuit - * starting at <b>router</b>. (If <b>router</b> is NULL, we don't have - * information on the router, so return false.) */ + * starting at <b>router</b>. (If <b>router</b> is NULL, we don't have + * information on the router, so assume true.) */ static INLINE int -should_use_create_fast_for_router(routerinfo_t *router) +should_use_create_fast_for_router(routerinfo_t *router, + origin_circuit_t *circ) { or_options_t *options = get_options(); - if (!options->FastFirstHopPK || server_mode(options)) + if (!options->FastFirstHopPK) /* create_fast is disabled */ return 0; - else if (!router || !router->platform || - !tor_version_as_new_as(router->platform, "0.1.0.6-rc")) + if (router && router->platform && + !tor_version_as_new_as(router->platform, "0.1.0.6-rc")) { + /* known not to work */ return 0; - else - return 1; + } + if (server_mode(options) && circ->cpath->extend_info->onion_key) { + /* We're a server, and we know an onion key. We can choose. + * Prefer to blend in. */ + return 0; + } + + return 1; } /** This is the backbone function for building circuits. @@ -562,8 +570,13 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) log_debug(LD_CIRC,"First skin; sending create cell."); router = router_get_by_digest(circ->_base.n_conn->identity_digest); - fast = should_use_create_fast_for_router(router); - if (! fast) { + fast = should_use_create_fast_for_router(router, circ); + if (!fast && !circ->cpath->extend_info->onion_key) { + log_warn(LD_CIRC, + "Can't send create_fast, but have no onion key. Failing."); + return - END_CIRC_REASON_INTERNAL; + } + if (!fast) { /* We are an OR, or we are connecting to an old Tor: we should * send an old slow create cell. */ @@ -1722,12 +1735,29 @@ extend_info_from_router(routerinfo_t *r) return info; } +/** Allocate and return a new extend_info_t that can be used to build a + * circuit to or through the router <b>r</b>. */ +extend_info_t * +extend_info_from_routerstatus(routerstatus_t *s) +{ + extend_info_t *info; + tor_assert(s); + info = tor_malloc_zero(sizeof(extend_info_t)); + strlcpy(info->nickname, s->nickname, sizeof(info->nickname)); + memcpy(info->identity_digest, s->identity_digest, DIGEST_LEN); + info->onion_key = NULL; /* routerstatus doesn't include this! */ + info->addr = s->addr; + info->port = s->or_port; + return info; +} + /** Release storage held by an extend_info_t struct. */ void extend_info_free(extend_info_t *info) { tor_assert(info); - crypto_free_pk_env(info->onion_key); + if (info->onion_key) + crypto_free_pk_env(info->onion_key); tor_free(info); } @@ -1740,7 +1770,10 @@ extend_info_dup(extend_info_t *info) tor_assert(info); newinfo = tor_malloc(sizeof(extend_info_t)); memcpy(newinfo, info, sizeof(extend_info_t)); - newinfo->onion_key = crypto_pk_dup_key(info->onion_key); + if (info->onion_key) + newinfo->onion_key = crypto_pk_dup_key(info->onion_key); + else + newinfo->onion_key = NULL; return newinfo; } diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 4114d12959..36c7a0ac1e 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1011,18 +1011,38 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, if (conn->chosen_exit_name) { routerinfo_t *r; int opt = conn->_base.chosen_exit_optional; - if (!(r = router_get_by_nickname(conn->chosen_exit_name, 1))) { - log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP, - "Requested exit point '%s' is not known. %s.", - conn->chosen_exit_name, opt ? "Trying others" : "Closing"); - if (opt) { - conn->_base.chosen_exit_optional = 0; - tor_free(conn->chosen_exit_name); - return 0; + r = router_get_by_nickname(conn->chosen_exit_name, 1); + if (r) { + extend_info = extend_info_from_router(r); + } else { + if (want_onehop && conn->chosen_exit_name[0] == '$') { + /* We're asking for a one-hop circuit to a router that + * we don't have a routerinfo about. Hope we have a + * routerstatus or equivalent. */ + routerstatus_t *s = + routerstatus_get_by_hexdigest(conn->chosen_exit_name+1); + if (s) { + extend_info = extend_info_from_routerstatus(s); + } else { + log_warn(LD_APP, + "Requested router '%s' is not known. Closing.", + conn->chosen_exit_name); + return -1; + } + } else { + /* We will need an onion key for the router, and we + * don't have one. Refuse or relax requirements. */ + log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP, + "Requested exit point '%s' is not known. %s.", + conn->chosen_exit_name, opt ? "Trying others" : "Closing"); + if (opt) { + conn->_base.chosen_exit_optional = 0; + tor_free(conn->chosen_exit_name); + return 0; + } + return -1; } - return -1; } - extend_info = extend_info_from_router(r); } } diff --git a/src/or/or.h b/src/or/or.h index 44542048d2..74a09df353 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1176,9 +1176,10 @@ typedef struct { tor_mmap_t *mmap_descriptors; } routerlist_t; -/** Information on router used when extending a circuit. (We don't need a +/** Information on router used when extending a circuit. We don't need a * full routerinfo_t to extend: we only need addr:port:keyid to build an OR - * connection, and onion_key to create the onionskin.) */ + * connection, and onion_key to create the onionskin. Note that for onehop + * general-purpose tunnels, the onion_key is NULL. */ typedef struct extend_info_t { char nickname[MAX_HEX_NICKNAME_LEN+1]; /**< This router's nickname for * display. */ @@ -1905,6 +1906,7 @@ int circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *info); int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info); void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop); extend_info_t *extend_info_from_router(routerinfo_t *r); +extend_info_t *extend_info_from_routerstatus(routerstatus_t *s); extend_info_t *extend_info_dup(extend_info_t *info); void extend_info_free(extend_info_t *info); routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state); @@ -2894,6 +2896,7 @@ void clear_trusted_dir_servers(void); int any_trusted_dir_is_v1_authority(void); networkstatus_t *networkstatus_get_by_digest(const char *digest); local_routerstatus_t *router_get_combined_status_by_digest(const char *digest); +routerstatus_t *routerstatus_get_by_hexdigest(const char *hexdigest); void update_networkstatus_downloads(time_t now); void update_router_descriptor_downloads(time_t now); void routers_update_all_from_networkstatus(void); |