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
This commit is contained in:
Roger Dingledine 2007-01-27 19:29:16 +00:00
parent 0e01dda145
commit add7d7af19
4 changed files with 84 additions and 24 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);