r15510@catbus: nickm | 2007-10-02 16:14:42 -0400

Add support for more vote URLs that weasel wanted.  Weasel: please test this before I inflict it on anybody else. :)


svn:r11749
This commit is contained in:
Nick Mathewson 2007-10-02 20:19:43 +00:00
parent 439fe55c6b
commit f4f780b526
5 changed files with 102 additions and 30 deletions

View File

@ -12,6 +12,10 @@ Changes in version 0.2.0.8-alpha - 2007-??-??
- Use annotations to record the source for each descriptor. - Use annotations to record the source for each descriptor.
- Use annotations to record the purpose of each descriptor. - Use annotations to record the purpose of each descriptor.
o Minor features (v3 authority system):
- Add more ways for tools to download the votes that lead to the current
consensus.
o Major bugfixes (performance): o Major bugfixes (performance):
- Fix really bad O(n^2) performance when parsing a long list of routers: - Fix really bad O(n^2) performance when parsing a long list of routers:
Instead of searching the entire list for an "extra-info " string which Instead of searching the entire list for an "extra-info " string which

View File

@ -1152,6 +1152,9 @@ $Id$
at at
http://<hostname>/tor/status-vote/next/<fp>.z http://<hostname>/tor/status-vote/next/<fp>.z
where <fp> is the fingerprint of the other authority's identity key. where <fp> is the fingerprint of the other authority's identity key.
And at
http://<hostname>/tor/status-vote/next/d/<d>.z
where <d> is the digest of the vote document.
The consensus status, along with as many signatures as the server The consensus status, along with as many signatures as the server
currently knows, should be available at currently knows, should be available at
@ -1166,6 +1169,12 @@ $Id$
and and
http://<hostname>/tor/status-vote/current/consensus-signatures.z http://<hostname>/tor/status-vote/current/consensus-signatures.z
The other vote documents are analogously made available under
http://<hostname>/tor/status-vote/current/authority.z
http://<hostname>/tor/status-vote/current/<fp>.z
http://<hostname>/tor/status-vote/current/d/<d>.z
once the consensus is complete.
Once an authority has computed and signed a consensus network status, it Once an authority has computed and signed a consensus network status, it
should send its detached signature to each other authority in an HTTP POST should send its detached signature to each other authority in an HTTP POST
request to the URL: request to the URL:

View File

@ -2124,16 +2124,27 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
const char *item; const char *item;
if ((item=dirvote_get_pending_detached_signatures())) if ((item=dirvote_get_pending_detached_signatures()))
smartlist_add(items, (char*)item); smartlist_add(items, (char*)item);
} else if (!current && !strcmp(url, "authority")) { } else if (!strcmp(url, "authority")) {
const cached_dir_t *d; const cached_dir_t *d;
if ((d=dirvote_get_vote(NULL))) if ((d=dirvote_get_vote(NULL, 1, current, !current)))
smartlist_add(dir_items, (cached_dir_t*)d); smartlist_add(dir_items, (cached_dir_t*)d);
} else if (!current) { } else {
const cached_dir_t *d; const cached_dir_t *d;
smartlist_t *fps = smartlist_create(); smartlist_t *fps = smartlist_create();
int by_id, include_pending, include_previous;
if (!strcmpstart(url, "d/")) {
url += 2;
by_id = 0;
include_pending = include_previous = 1;
} else {
by_id = 1;
include_pending = current;
include_previous = !current;
}
dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1); dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
SMARTLIST_FOREACH(fps, char *, fp, { SMARTLIST_FOREACH(fps, char *, fp, {
if ((d = dirvote_get_vote(fp))) if ((d = dirvote_get_vote(fp, by_id,
include_pending, include_previous)))
smartlist_add(dir_items, (cached_dir_t*)d); smartlist_add(dir_items, (cached_dir_t*)d);
tor_free(fp); tor_free(fp);
}); });

View File

@ -1133,8 +1133,7 @@ dirvote_recalculate_timing(time_t now)
voting_schedule.fetch_missing_votes = start - dist_delay - (vote_delay/2); voting_schedule.fetch_missing_votes = start - dist_delay - (vote_delay/2);
voting_schedule.voting_starts = start - dist_delay - vote_delay; voting_schedule.voting_starts = start - dist_delay - vote_delay;
voting_schedule.discard_old_votes = start + voting_schedule.discard_old_votes = start;
((end-start) - vote_delay - dist_delay)/2 ;
} }
/** Entry point: Take whatever voting actions are pending as of <b>now</b>. */ /** Entry point: Take whatever voting actions are pending as of <b>now</b>. */
@ -1185,7 +1184,7 @@ dirvote_act(time_t now)
} }
if (voting_schedule.discard_old_votes < now) { if (voting_schedule.discard_old_votes < now) {
log_notice(LD_DIR, "Time to discard old votes."); log_notice(LD_DIR, "Time to discard old votes.");
dirvote_clear_pending_votes(); dirvote_clear_votes(0);
dirvote_recalculate_timing(now); dirvote_recalculate_timing(now);
} }
} }
@ -1198,8 +1197,12 @@ typedef struct pending_vote_t {
networkstatus_vote_t *vote; networkstatus_vote_t *vote;
} pending_vote_t; } pending_vote_t;
/** List of pending_vote_t for the current vote. */ /** List of pending_vote_t for the current vote. Before we've used them to
* build a consensus, the votes go here. */
static smartlist_t *pending_vote_list = NULL; static smartlist_t *pending_vote_list = NULL;
/** List of pending_vote_t for the previous vote. After we've used them to
* build a consensus, the votes go here for the next period. */
static smartlist_t *previous_vote_list = NULL;
/** The body of the consensus that we're currently building. Once we /** The body of the consensus that we're currently building. Once we
* have it built, it goes into dirserv.c */ * have it built, it goes into dirserv.c */
static char *pending_consensus_body = NULL; static char *pending_consensus_body = NULL;
@ -1251,7 +1254,7 @@ dirvote_fetch_missing_votes(void)
{ {
if (!(ds->type & V3_AUTHORITY)) if (!(ds->type & V3_AUTHORITY))
continue; continue;
if (!dirvote_get_vote(ds->v3_identity_digest)) { if (!dirvote_get_vote(ds->v3_identity_digest, 1, 1, 0)) {
char *cp = tor_malloc(HEX_DIGEST_LEN+1); char *cp = tor_malloc(HEX_DIGEST_LEN+1);
base16_encode(cp, HEX_DIGEST_LEN+1, ds->v3_identity_digest, base16_encode(cp, HEX_DIGEST_LEN+1, ds->v3_identity_digest,
DIGEST_LEN); DIGEST_LEN);
@ -1288,17 +1291,36 @@ dirvote_fetch_missing_signatures(void)
/** Drop all currently pending votes, consensus, and detached signatures. */ /** Drop all currently pending votes, consensus, and detached signatures. */
void void
dirvote_clear_pending_votes(void) dirvote_clear_votes(int all_votes)
{ {
if (pending_vote_list) { if (!previous_vote_list)
previous_vote_list = smartlist_create();
if (!pending_vote_list)
pending_vote_list = smartlist_create();
/* All "previous" votes are now junk. */
SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, v, {
cached_dir_decref(v->vote_body);
v->vote_body = NULL;
networkstatus_vote_free(v->vote);
tor_free(v);
});
smartlist_clear(previous_vote_list);
if (all_votes) {
/* If we're dumping all the votes, we delete the pending ones. */
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, { SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
cached_dir_decref(v->vote_body); cached_dir_decref(v->vote_body);
v->vote_body = NULL; v->vote_body = NULL;
networkstatus_vote_free(v->vote); networkstatus_vote_free(v->vote);
tor_free(v); tor_free(v);
}); });
smartlist_clear(pending_vote_list); } else {
/* Otherwise, we move them into "previous". */
smartlist_add_all(previous_vote_list, pending_vote_list);
} }
smartlist_clear(pending_vote_list);
if (pending_consensus_signature_list) { if (pending_consensus_signature_list) {
SMARTLIST_FOREACH(pending_consensus_signature_list, char *, cp, SMARTLIST_FOREACH(pending_consensus_signature_list, char *, cp,
tor_free(cp)); tor_free(cp));
@ -1685,12 +1707,13 @@ dirvote_publish_consensus(void)
void void
dirvote_free_all(void) dirvote_free_all(void)
{ {
dirvote_clear_pending_votes(); dirvote_clear_votes(1);
if (pending_vote_list) { /* now empty as a result of clear_pending_votes. */
/* now empty as a result of clear_pending_votes. */ smartlist_free(pending_vote_list);
smartlist_free(pending_vote_list); pending_vote_list = NULL;
pending_vote_list = NULL; smartlist_free(previous_vote_list);
} previous_vote_list = NULL;
tor_free(pending_consensus_body); tor_free(pending_consensus_body);
tor_free(pending_consensus_signatures); tor_free(pending_consensus_signatures);
if (pending_consensus) { if (pending_consensus) {
@ -1725,22 +1748,45 @@ dirvote_get_pending_detached_signatures(void)
/** Return the vote for the authority with the v3 authority identity key /** Return the vote for the authority with the v3 authority identity key
* digest <b>id</b>. If <b>id</b> is NULL, return our own vote. May return * digest <b>id</b>. If <b>id</b> is NULL, return our own vote. May return
* NULL if we have no vote for the authority in question. */ * NULL if we have no vote for the authority in question.
* DOCDOC args */
const cached_dir_t * const cached_dir_t *
dirvote_get_vote(const char *id) dirvote_get_vote(const char *fp, int by_id, int include_previous,
int include_pending)
{ {
if (!pending_vote_list) if (!pending_vote_list && !previous_vote_list)
return NULL; return NULL;
if (id == NULL) { if (fp == NULL) {
authority_cert_t *c = get_my_v3_authority_cert(); authority_cert_t *c = get_my_v3_authority_cert();
if (c) if (c) {
id = c->cache_info.identity_digest; fp = c->cache_info.identity_digest;
else by_id = 1;
} else
return NULL; return NULL;
} }
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv, if (by_id) {
if (!memcmp(get_voter(pv->vote)->identity_digest, id, DIGEST_LEN)) if (pending_vote_list && include_pending) {
return pv->vote_body); SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
return pv->vote_body);
}
if (previous_vote_list && include_previous) {
SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
return pv->vote_body);
}
} else {
if (pending_vote_list && include_pending) {
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
if (!memcmp(pv->vote->networkstatus_digest, fp, DIGEST_LEN))
return pv->vote_body);
}
if (previous_vote_list && include_previous) {
SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
if (!memcmp(pv->vote->networkstatus_digest, fp, DIGEST_LEN))
return pv->vote_body);
}
}
return NULL; return NULL;
} }

View File

@ -2887,7 +2887,7 @@ void dirvote_act(time_t now);
/* invoked on timers and by outside triggers. */ /* invoked on timers and by outside triggers. */
void dirvote_perform_vote(void); void dirvote_perform_vote(void);
void dirvote_clear_pending_votes(void); void dirvote_clear_votes(int all_votes);
struct pending_vote_t * dirvote_add_vote(const char *vote_body, struct pending_vote_t * dirvote_add_vote(const char *vote_body,
const char **msg_out, const char **msg_out,
int *status_out); int *status_out);
@ -2898,7 +2898,9 @@ int dirvote_publish_consensus(void);
/* Item access */ /* Item access */
const char *dirvote_get_pending_consensus(void); const char *dirvote_get_pending_consensus(void);
const char *dirvote_get_pending_detached_signatures(void); const char *dirvote_get_pending_detached_signatures(void);
const cached_dir_t *dirvote_get_vote(const char *id); const cached_dir_t *dirvote_get_vote(const char *fp, int by_id,
int include_pending,
int include_previous);
#ifdef DIRVOTE_PRIVATE #ifdef DIRVOTE_PRIVATE
int networkstatus_check_voter_signature(networkstatus_vote_t *consensus, int networkstatus_check_voter_signature(networkstatus_vote_t *consensus,