[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r12051: Client-side implementation for proposal 122. (in tor/trunk: . doc doc/spec/proposals src/or)
Author: nickm
Date: 2007-10-19 14:56:24 -0400 (Fri, 19 Oct 2007)
New Revision: 12051
Modified:
tor/trunk/
tor/trunk/ChangeLog
tor/trunk/doc/TODO
tor/trunk/doc/spec/proposals/122-unnamed-flag.txt
tor/trunk/src/or/networkstatus.c
tor/trunk/src/or/or.h
tor/trunk/src/or/routerlist.c
tor/trunk/src/or/routerparse.c
Log:
r15965@catbus: nickm | 2007-10-19 13:32:11 -0400
Client-side implementation for proposal 122.
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/trunk [r15965] on 8246c3cf-6607-4228-993b-4d95d33730f1
Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog 2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/ChangeLog 2007-10-19 18:56:24 UTC (rev 12051)
@@ -16,6 +16,9 @@
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
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):
- Allow tor-gencert to generate a new certificate without replacing the
Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO 2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/doc/TODO 2007-10-19 18:56:24 UTC (rev 12051)
@@ -93,11 +93,11 @@
- 105: Version negotiation for the Tor protocol
. 111: Prioritize local traffic over relayed.
- 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
- Implement voting side
- Implement consensus side
- - Implement client side
+ o Implement client side
- Refactoring:
. Make cells get buffered on circuit, not on the or_conn.
Modified: tor/trunk/doc/spec/proposals/122-unnamed-flag.txt
===================================================================
--- tor/trunk/doc/spec/proposals/122-unnamed-flag.txt 2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/doc/spec/proposals/122-unnamed-flag.txt 2007-10-19 18:56:24 UTC (rev 12051)
@@ -4,7 +4,7 @@
Last-Modified: $Date$
Author: Roger Dingledine
Created: 04-Oct-2007
-Status: Open
+Status: Accepted
1. Overview:
Modified: tor/trunk/src/or/networkstatus.c
===================================================================
--- tor/trunk/src/or/networkstatus.c 2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/src/or/networkstatus.c 2007-10-19 18:56:24 UTC (rev 12051)
@@ -25,8 +25,11 @@
* time we called download_status_map_update_from_v2_networkstatus() */
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;
+/** 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. */
static networkstatus_vote_t *current_consensus = NULL;
@@ -579,6 +582,7 @@
routerstatus_t *best=NULL;
smartlist_t *matches=NULL;
const char *named_id=NULL;
+ int any_unnamed=0;
if (!current_consensus || !nickname)
return NULL;
@@ -597,6 +601,10 @@
if (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? */
matches = smartlist_create();
SMARTLIST_FOREACH(current_consensus->routerstatus_list,
@@ -604,16 +612,22 @@
{
if (!strcasecmp(lrs->nickname, nickname)) {
if (lrs->is_named) {
+ /* XXXX020 this should never happen. */
smartlist_free(matches);
return lrs;
} else {
+ if (lrs->is_unnamed)
+ smartlist_free(matches); /* nor should this. */
smartlist_add(matches, 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;
SMARTLIST_FOREACH(matches, routerstatus_t *, lrs,
{
@@ -654,6 +668,13 @@
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
* documents? */
#define AUTHORITY_NS_CACHE_INTERVAL (5*60)
@@ -1061,6 +1082,11 @@
log_info(LD_GENERAL, "The latest consensus does not list us."
"Are you misconfigured?");
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) {
/*XXXX020 this isn't a correct warning. */
log_info(LD_GENERAL, "The directory authorities do not recognize "
@@ -1150,12 +1176,18 @@
if (named_server_map)
strmap_free(named_server_map, _tor_free);
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,
{
if (rs->is_named) {
- strmap_set(named_server_map, rs->nickname,
- tor_memdup(rs->identity_digest, DIGEST_LEN));
+ strmap_set_lc(named_server_map, rs->nickname,
+ 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 @@
if (named_server_map) {
strmap_free(named_server_map, _tor_free);
}
+ if (unnamed_server_map) {
+ strmap_free(unnamed_server_map, NULL);
+ }
}
Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h 2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/src/or/or.h 2007-10-19 18:56:24 UTC (rev 12051)
@@ -1221,6 +1221,8 @@
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_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_v2_dir:1; /**< True iff this router can serve directory
* information with v2 of the directory
@@ -1349,6 +1351,11 @@
time_t valid_until; /**< Time after which this vote or consensus should not
* 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
* distribute their votes to one another? */
int vote_seconds;
@@ -3091,6 +3098,7 @@
routerstatus_t *router_get_consensus_status_by_nickname(const char *nickname,
int warn_if_unnamed);
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);
int should_delay_dir_fetches(or_options_t *options);
void update_networkstatus_downloads(time_t now);
Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c 2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/src/or/routerlist.c 2007-10-19 18:56:24 UTC (rev 12051)
@@ -1701,6 +1701,8 @@
if ((named_digest = networkstatus_get_router_digest_by_nickname(nickname))) {
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. */
Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c 2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/src/or/routerparse.c 2007-10-19 18:56:24 UTC (rev 12051)
@@ -1534,12 +1534,17 @@
* 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
- * 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 *
routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens,
networkstatus_vote_t *vote,
- vote_routerstatus_t *vote_rs)
+ vote_routerstatus_t *vote_rs,
+ int consensus_method)
{
const char *eos;
routerstatus_t *rs = NULL;
@@ -1645,6 +1650,11 @@
rs->is_bad_directory = 1;
else if (!strcmp(tok->args[i], "Authority"))
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))) {
@@ -1830,7 +1840,7 @@
smartlist_clear(tokens);
while (!strcmpstart(s, "r ")) {
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_sort(ns->entries, _compare_routerstatus_entries);
@@ -1936,6 +1946,26 @@
tok = find_first_by_keyword(tokens, K_PUBLISHED);
if (parse_iso_time(tok->args[0], &ns->published))
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);
@@ -2086,7 +2116,7 @@
while (!strcmpstart(s, "r ")) {
if (is_vote) {
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);
else {
tor_free(rs->version);
@@ -2094,7 +2124,8 @@
}
} else {
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);
}
}