mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
r15965@catbus: nickm | 2007-10-19 13:32:11 -0400
Client-side implementation for proposal 122. svn:r12051
This commit is contained in:
parent
ee2b770dee
commit
7bb202fd19
@ -16,6 +16,9 @@ Changes in version 0.2.0.9-alpha - 2007-10-??
|
|||||||
that it shouldn't be considered to exist at all anymore. Now we
|
that it shouldn't be considered to exist at all anymore. Now we
|
||||||
clear all the flags for routers that fall out of the networkstatus
|
clear all the flags for routers that fall out of the networkstatus
|
||||||
consensus. Fixes bug 529.
|
consensus. Fixes bug 529.
|
||||||
|
- If the consensus list a router as "Unnamed", the name is assigned
|
||||||
|
to a different router: do not identify the router by that name.
|
||||||
|
(Partially implements proposal 122.)
|
||||||
|
|
||||||
o Minor features (v3 directory protocol):
|
o Minor features (v3 directory protocol):
|
||||||
- Allow tor-gencert to generate a new certificate without replacing the
|
- Allow tor-gencert to generate a new certificate without replacing the
|
||||||
|
4
doc/TODO
4
doc/TODO
@ -93,11 +93,11 @@ Things we'd like to do in 0.2.0.x:
|
|||||||
- 105: Version negotiation for the Tor protocol
|
- 105: Version negotiation for the Tor protocol
|
||||||
. 111: Prioritize local traffic over relayed.
|
. 111: Prioritize local traffic over relayed.
|
||||||
- Merge into tor-spec.txt.
|
- Merge into tor-spec.txt.
|
||||||
- 122: Network status entries need an Unnamed flag
|
. 122: Network status entries need an Unnamed flag
|
||||||
- Merge into dir-spec.txt
|
- Merge into dir-spec.txt
|
||||||
- Implement voting side
|
- Implement voting side
|
||||||
- Implement consensus side
|
- Implement consensus side
|
||||||
- Implement client side
|
o Implement client side
|
||||||
|
|
||||||
- Refactoring:
|
- Refactoring:
|
||||||
. Make cells get buffered on circuit, not on the or_conn.
|
. Make cells get buffered on circuit, not on the or_conn.
|
||||||
|
@ -4,7 +4,7 @@ Version: $Revision$
|
|||||||
Last-Modified: $Date$
|
Last-Modified: $Date$
|
||||||
Author: Roger Dingledine
|
Author: Roger Dingledine
|
||||||
Created: 04-Oct-2007
|
Created: 04-Oct-2007
|
||||||
Status: Open
|
Status: Accepted
|
||||||
|
|
||||||
1. Overview:
|
1. Overview:
|
||||||
|
|
||||||
|
@ -25,8 +25,11 @@ static smartlist_t *networkstatus_v2_list = NULL;
|
|||||||
* time we called download_status_map_update_from_v2_networkstatus() */
|
* time we called download_status_map_update_from_v2_networkstatus() */
|
||||||
static int networkstatus_v2_list_has_changed = 0;
|
static int networkstatus_v2_list_has_changed = 0;
|
||||||
|
|
||||||
/** Map from lowercase nickname to digest of named server, if any. */
|
/** Map from lowercase nickname to identity digest of named server, if any. */
|
||||||
static strmap_t *named_server_map = NULL;
|
static strmap_t *named_server_map = NULL;
|
||||||
|
/** Map from lowercase nickname to (void*)1 for all names that are listed
|
||||||
|
* as unnamed for some server in the consensus. */
|
||||||
|
static strmap_t *unnamed_server_map = NULL;
|
||||||
|
|
||||||
/** Most recently received and validated v3 consensus network status. */
|
/** Most recently received and validated v3 consensus network status. */
|
||||||
static networkstatus_vote_t *current_consensus = NULL;
|
static networkstatus_vote_t *current_consensus = NULL;
|
||||||
@ -579,6 +582,7 @@ router_get_consensus_status_by_nickname(const char *nickname,
|
|||||||
routerstatus_t *best=NULL;
|
routerstatus_t *best=NULL;
|
||||||
smartlist_t *matches=NULL;
|
smartlist_t *matches=NULL;
|
||||||
const char *named_id=NULL;
|
const char *named_id=NULL;
|
||||||
|
int any_unnamed=0;
|
||||||
|
|
||||||
if (!current_consensus || !nickname)
|
if (!current_consensus || !nickname)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -597,6 +601,10 @@ router_get_consensus_status_by_nickname(const char *nickname,
|
|||||||
if (named_id)
|
if (named_id)
|
||||||
return networkstatus_vote_find_entry(current_consensus, named_id);
|
return networkstatus_vote_find_entry(current_consensus, named_id);
|
||||||
|
|
||||||
|
if (unnamed_server_map &&
|
||||||
|
strmap_get_lc(named_server_map, nickname))
|
||||||
|
return NULL; /* XXXX020 should we warn? */
|
||||||
|
|
||||||
/*XXXX020 is this behavior really what we want? */
|
/*XXXX020 is this behavior really what we want? */
|
||||||
matches = smartlist_create();
|
matches = smartlist_create();
|
||||||
SMARTLIST_FOREACH(current_consensus->routerstatus_list,
|
SMARTLIST_FOREACH(current_consensus->routerstatus_list,
|
||||||
@ -604,16 +612,22 @@ router_get_consensus_status_by_nickname(const char *nickname,
|
|||||||
{
|
{
|
||||||
if (!strcasecmp(lrs->nickname, nickname)) {
|
if (!strcasecmp(lrs->nickname, nickname)) {
|
||||||
if (lrs->is_named) {
|
if (lrs->is_named) {
|
||||||
|
/* XXXX020 this should never happen. */
|
||||||
smartlist_free(matches);
|
smartlist_free(matches);
|
||||||
return lrs;
|
return lrs;
|
||||||
} else {
|
} else {
|
||||||
|
if (lrs->is_unnamed)
|
||||||
|
smartlist_free(matches); /* nor should this. */
|
||||||
smartlist_add(matches, lrs);
|
smartlist_add(matches, lrs);
|
||||||
best = lrs;
|
best = lrs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (smartlist_len(matches)>1 && warn_if_unnamed) {
|
if (any_unnamed) {
|
||||||
|
/* XXXX020 should we warn? */
|
||||||
|
return NULL;
|
||||||
|
} else if (smartlist_len(matches)>1 && warn_if_unnamed) {
|
||||||
int any_unwarned=0;
|
int any_unwarned=0;
|
||||||
SMARTLIST_FOREACH(matches, routerstatus_t *, lrs,
|
SMARTLIST_FOREACH(matches, routerstatus_t *, lrs,
|
||||||
{
|
{
|
||||||
@ -654,6 +668,13 @@ networkstatus_get_router_digest_by_nickname(const char *nickname)
|
|||||||
return strmap_get_lc(named_server_map, nickname);
|
return strmap_get_lc(named_server_map, nickname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
networkstatus_nickname_is_unnamed(const char *nickname)
|
||||||
|
{
|
||||||
|
return strmap_get_lc(named_server_map, nickname) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/** How frequently do directory authorities re-download fresh networkstatus
|
/** How frequently do directory authorities re-download fresh networkstatus
|
||||||
* documents? */
|
* documents? */
|
||||||
#define AUTHORITY_NS_CACHE_INTERVAL (5*60)
|
#define AUTHORITY_NS_CACHE_INTERVAL (5*60)
|
||||||
@ -1061,6 +1082,11 @@ routers_update_all_from_networkstatus(time_t now)
|
|||||||
log_info(LD_GENERAL, "The latest consensus does not list us."
|
log_info(LD_GENERAL, "The latest consensus does not list us."
|
||||||
"Are you misconfigured?");
|
"Are you misconfigured?");
|
||||||
have_warned_about_invalid_status = 1;
|
have_warned_about_invalid_status = 1;
|
||||||
|
} else if (rs->is_unnamed) {
|
||||||
|
/* XXXX020 this isn't a useful warning. */
|
||||||
|
log_info(LD_GENERAL, "The directory have assigned the nickname "
|
||||||
|
"you're using to a different identity.");
|
||||||
|
have_warned_about_invalid_status = 1;
|
||||||
} else if (!rs->is_named) {
|
} else if (!rs->is_named) {
|
||||||
/*XXXX020 this isn't a correct warning. */
|
/*XXXX020 this isn't a correct warning. */
|
||||||
log_info(LD_GENERAL, "The directory authorities do not recognize "
|
log_info(LD_GENERAL, "The directory authorities do not recognize "
|
||||||
@ -1150,11 +1176,17 @@ routerstatus_list_update_named_server_map(void)
|
|||||||
if (named_server_map)
|
if (named_server_map)
|
||||||
strmap_free(named_server_map, _tor_free);
|
strmap_free(named_server_map, _tor_free);
|
||||||
named_server_map = strmap_new();
|
named_server_map = strmap_new();
|
||||||
|
if (unnamed_server_map)
|
||||||
|
strmap_free(unnamed_server_map, NULL);
|
||||||
|
named_server_map = strmap_new();
|
||||||
SMARTLIST_FOREACH(current_consensus->routerstatus_list, routerstatus_t *, rs,
|
SMARTLIST_FOREACH(current_consensus->routerstatus_list, routerstatus_t *, rs,
|
||||||
{
|
{
|
||||||
if (rs->is_named) {
|
if (rs->is_named) {
|
||||||
strmap_set(named_server_map, rs->nickname,
|
strmap_set_lc(named_server_map, rs->nickname,
|
||||||
tor_memdup(rs->identity_digest, DIGEST_LEN));
|
tor_memdup(rs->identity_digest, DIGEST_LEN));
|
||||||
|
}
|
||||||
|
if (rs->is_unnamed) {
|
||||||
|
strmap_set_lc(unnamed_server_map, rs->nickname, (void*)1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1348,5 +1380,8 @@ networkstatus_free_all(void)
|
|||||||
if (named_server_map) {
|
if (named_server_map) {
|
||||||
strmap_free(named_server_map, _tor_free);
|
strmap_free(named_server_map, _tor_free);
|
||||||
}
|
}
|
||||||
|
if (unnamed_server_map) {
|
||||||
|
strmap_free(unnamed_server_map, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1221,6 +1221,8 @@ typedef struct routerstatus_t {
|
|||||||
unsigned int is_fast:1; /**< True iff this router has good bandwidth. */
|
unsigned int is_fast:1; /**< True iff this router has good bandwidth. */
|
||||||
unsigned int is_running:1; /**< True iff this router is up. */
|
unsigned int is_running:1; /**< True iff this router is up. */
|
||||||
unsigned int is_named:1; /**< True iff "nickname" belongs to this router. */
|
unsigned int is_named:1; /**< True iff "nickname" belongs to this router. */
|
||||||
|
unsigned int is_unnamed:1; /**< True iff "nickname" belongs to another
|
||||||
|
* router. */
|
||||||
unsigned int is_valid:1; /**< True iff this router is validated. */
|
unsigned int is_valid:1; /**< True iff this router is validated. */
|
||||||
unsigned int is_v2_dir:1; /**< True iff this router can serve directory
|
unsigned int is_v2_dir:1; /**< True iff this router can serve directory
|
||||||
* information with v2 of the directory
|
* information with v2 of the directory
|
||||||
@ -1349,6 +1351,11 @@ typedef struct networkstatus_vote_t {
|
|||||||
time_t valid_until; /**< Time after which this vote or consensus should not
|
time_t valid_until; /**< Time after which this vote or consensus should not
|
||||||
* be used. */
|
* be used. */
|
||||||
|
|
||||||
|
/** Consensus only: what method was used to produce this consensus? */
|
||||||
|
int consensus_method;
|
||||||
|
/** Vote only: what methods is this voter willing to use? */
|
||||||
|
smartlist_t *supported_methods;
|
||||||
|
|
||||||
/** How long does this vote/consensus claim that authorities take to
|
/** How long does this vote/consensus claim that authorities take to
|
||||||
* distribute their votes to one another? */
|
* distribute their votes to one another? */
|
||||||
int vote_seconds;
|
int vote_seconds;
|
||||||
@ -3091,6 +3098,7 @@ routerstatus_t *router_get_consensus_status_by_descriptor_digest(
|
|||||||
routerstatus_t *router_get_consensus_status_by_nickname(const char *nickname,
|
routerstatus_t *router_get_consensus_status_by_nickname(const char *nickname,
|
||||||
int warn_if_unnamed);
|
int warn_if_unnamed);
|
||||||
const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
|
const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
|
||||||
|
int networkstatus_nickname_is_unnamed(const char *nickname);
|
||||||
void networkstatus_consensus_download_failed(int status_code);
|
void networkstatus_consensus_download_failed(int status_code);
|
||||||
int should_delay_dir_fetches(or_options_t *options);
|
int should_delay_dir_fetches(or_options_t *options);
|
||||||
void update_networkstatus_downloads(time_t now);
|
void update_networkstatus_downloads(time_t now);
|
||||||
|
@ -1701,6 +1701,8 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
|
|||||||
if ((named_digest = networkstatus_get_router_digest_by_nickname(nickname))) {
|
if ((named_digest = networkstatus_get_router_digest_by_nickname(nickname))) {
|
||||||
return rimap_get(routerlist->identity_map, named_digest);
|
return rimap_get(routerlist->identity_map, named_digest);
|
||||||
}
|
}
|
||||||
|
if (networkstatus_nickname_is_unnamed(nickname))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* If we reach this point, there's no canonical value for the nickname. */
|
/* If we reach this point, there's no canonical value for the nickname. */
|
||||||
|
|
||||||
|
@ -1534,12 +1534,17 @@ find_start_of_next_routerstatus(const char *s)
|
|||||||
* router status. Return NULL and advance *<b>s</b> on error.
|
* router status. Return NULL and advance *<b>s</b> on error.
|
||||||
*
|
*
|
||||||
* If <b>vote</b> and <b>vote_rs</b> are provided, don't allocate a fresh
|
* If <b>vote</b> and <b>vote_rs</b> are provided, don't allocate a fresh
|
||||||
* routerstatus but use <b>vote_rs</b> instead
|
* routerstatus but use <b>vote_rs</b> instead.
|
||||||
|
*
|
||||||
|
* If <b>consensus_method</b> is nonzero, this routerstatus is part of a
|
||||||
|
* consensus, and we should parse it according to the method used to
|
||||||
|
* make that consensus.
|
||||||
**/
|
**/
|
||||||
static routerstatus_t *
|
static routerstatus_t *
|
||||||
routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens,
|
routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens,
|
||||||
networkstatus_vote_t *vote,
|
networkstatus_vote_t *vote,
|
||||||
vote_routerstatus_t *vote_rs)
|
vote_routerstatus_t *vote_rs,
|
||||||
|
int consensus_method)
|
||||||
{
|
{
|
||||||
const char *eos;
|
const char *eos;
|
||||||
routerstatus_t *rs = NULL;
|
routerstatus_t *rs = NULL;
|
||||||
@ -1645,6 +1650,11 @@ routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens,
|
|||||||
rs->is_bad_directory = 1;
|
rs->is_bad_directory = 1;
|
||||||
else if (!strcmp(tok->args[i], "Authority"))
|
else if (!strcmp(tok->args[i], "Authority"))
|
||||||
rs->is_authority = 1;
|
rs->is_authority = 1;
|
||||||
|
else if (!strcmp(tok->args[i], "Unnamed") &&
|
||||||
|
consensus_method >= 2) {
|
||||||
|
/* Unnamed is computed right by consensus method 2 and later. */
|
||||||
|
rs->is_unnamed = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((tok = find_first_by_keyword(tokens, K_V))) {
|
if ((tok = find_first_by_keyword(tokens, K_V))) {
|
||||||
@ -1830,7 +1840,7 @@ networkstatus_v2_parse_from_string(const char *s)
|
|||||||
smartlist_clear(tokens);
|
smartlist_clear(tokens);
|
||||||
while (!strcmpstart(s, "r ")) {
|
while (!strcmpstart(s, "r ")) {
|
||||||
routerstatus_t *rs;
|
routerstatus_t *rs;
|
||||||
if ((rs = routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL)))
|
if ((rs = routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL, 0)))
|
||||||
smartlist_add(ns->entries, rs);
|
smartlist_add(ns->entries, rs);
|
||||||
}
|
}
|
||||||
smartlist_sort(ns->entries, _compare_routerstatus_entries);
|
smartlist_sort(ns->entries, _compare_routerstatus_entries);
|
||||||
@ -1936,6 +1946,26 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
|
|||||||
tok = find_first_by_keyword(tokens, K_PUBLISHED);
|
tok = find_first_by_keyword(tokens, K_PUBLISHED);
|
||||||
if (parse_iso_time(tok->args[0], &ns->published))
|
if (parse_iso_time(tok->args[0], &ns->published))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
ns->supported_methods = smartlist_create();
|
||||||
|
tok = find_first_by_keyword(tokens, K_CONSENSUS_METHODS);
|
||||||
|
if (tok) {
|
||||||
|
for (i=0; i < tok->n_args; ++i)
|
||||||
|
smartlist_add(ns->supported_methods, tok->args[i]);
|
||||||
|
tok->n_args = 0; /* Prevent double free. */
|
||||||
|
} else {
|
||||||
|
smartlist_add(ns->supported_methods, tor_strdup("1"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tok = find_first_by_keyword(tokens, K_CONSENSUS_METHOD);
|
||||||
|
if (tok) {
|
||||||
|
ns->consensus_method = (int)tor_parse_long(tok->args[0], 10, 1, INT_MAX,
|
||||||
|
&ok, NULL);
|
||||||
|
if (!ok)
|
||||||
|
goto err;
|
||||||
|
} else {
|
||||||
|
ns->consensus_method = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tok = find_first_by_keyword(tokens, K_VALID_AFTER);
|
tok = find_first_by_keyword(tokens, K_VALID_AFTER);
|
||||||
@ -2086,7 +2116,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
|
|||||||
while (!strcmpstart(s, "r ")) {
|
while (!strcmpstart(s, "r ")) {
|
||||||
if (is_vote) {
|
if (is_vote) {
|
||||||
vote_routerstatus_t *rs = tor_malloc_zero(sizeof(vote_routerstatus_t));
|
vote_routerstatus_t *rs = tor_malloc_zero(sizeof(vote_routerstatus_t));
|
||||||
if (routerstatus_parse_entry_from_string(&s, tokens, ns, rs))
|
if (routerstatus_parse_entry_from_string(&s, tokens, ns, rs, 0))
|
||||||
smartlist_add(ns->routerstatus_list, rs);
|
smartlist_add(ns->routerstatus_list, rs);
|
||||||
else {
|
else {
|
||||||
tor_free(rs->version);
|
tor_free(rs->version);
|
||||||
@ -2094,7 +2124,8 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
routerstatus_t *rs;
|
routerstatus_t *rs;
|
||||||
if ((rs =routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL)))
|
if ((rs = routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL,
|
||||||
|
ns->consensus_method)))
|
||||||
smartlist_add(ns->routerstatus_list, rs);
|
smartlist_add(ns->routerstatus_list, rs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user