diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-11-12 14:29:05 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-05-28 10:42:29 -0400 |
commit | 6c564e6c081514bab56bacec89b1f6f9457a7022 (patch) | |
tree | dd61357bebc5b7a3290f6a214e80da25be95f8e2 /src/or/dircollate.c | |
parent | 525383c46d1430abf680133e486fc532050d7123 (diff) | |
download | tor-6c564e6c081514bab56bacec89b1f6f9457a7022.tar.gz tor-6c564e6c081514bab56bacec89b1f6f9457a7022.zip |
Refactor code that matches up routers with the same identity in votes
This makes 'routerstatus collation' into a first-class concept, so
we can change how that works for prop220.
Diffstat (limited to 'src/or/dircollate.c')
-rw-r--r-- | src/or/dircollate.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/src/or/dircollate.c b/src/or/dircollate.c new file mode 100644 index 0000000000..92f3dcc2e5 --- /dev/null +++ b/src/or/dircollate.c @@ -0,0 +1,122 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file dircollate.c + * + * \brief Collation code for figuring out which identities to vote for in + * the directory voting process. + */ + +#define DIRCOLLATE_PRIVATE +#include "dircollate.h" + +static void dircollator_collate_by_rsa(dircollator_t *dc); + +static void +dircollator_add_routerstatus(dircollator_t *dc, + int vote_num, + networkstatus_t *vote, + vote_routerstatus_t *vrs) +{ + const char *id = vrs->status.identity_digest; + + (void) vote; + vote_routerstatus_t **vrs_lst = digestmap_get(dc->by_rsa_sha1, id); + if (NULL == vrs_lst) { + vrs_lst = tor_calloc(sizeof(vote_routerstatus_t *), dc->n_votes); + digestmap_set(dc->by_rsa_sha1, id, vrs_lst); + } + + tor_assert(vrs_lst[vote_num] == NULL); + vrs_lst[vote_num] = vrs; +} + +dircollator_t * +dircollator_new(int n_votes, int n_authorities) +{ + dircollator_t *dc = tor_malloc_zero(sizeof(dircollator_t)); + + tor_assert(n_votes <= n_authorities); + + dc->n_votes = n_votes; + dc->n_authorities = n_authorities; + + dc->by_rsa_sha1 = digestmap_new(); + + return dc; +} + +void +dircollator_free(dircollator_t *dc) +{ + if (!dc) + return; + + digestmap_free(dc->by_rsa_sha1, tor_free_); + + tor_free(dc); +} + +void +dircollator_add_vote(dircollator_t *dc, networkstatus_t *v) +{ + tor_assert(v->type == NS_TYPE_VOTE); + tor_assert(dc->next_vote_num < dc->n_votes); + tor_assert(!dc->is_collated); + + const int votenum = dc->next_vote_num++; + + SMARTLIST_FOREACH_BEGIN(v->routerstatus_list, vote_routerstatus_t *, vrs) { + dircollator_add_routerstatus(dc, votenum, v, vrs); + } SMARTLIST_FOREACH_END(vrs); +} + +void +dircollator_collate(dircollator_t *dc) +{ + dircollator_collate_by_rsa(dc); +} + +static void +dircollator_collate_by_rsa(dircollator_t *dc) +{ + tor_assert(!dc->is_collated); + + dc->all_rsa_sha1_lst = smartlist_new(); + + const int total_authorities = dc->n_authorities; + + DIGESTMAP_FOREACH(dc->by_rsa_sha1, k, vote_routerstatus_t **, vrs_lst) { + int n = 0, i; + for (i = 0; i < dc->n_votes; ++i) { + if (vrs_lst[i] != NULL) + ++n; + } + + if (n <= total_authorities / 2) + continue; + + smartlist_add(dc->all_rsa_sha1_lst, (char *)k); + } DIGESTMAP_FOREACH_END; + + smartlist_sort_digests(dc->all_rsa_sha1_lst); + dc->is_collated = 1; +} + +int +dircollator_n_routers(dircollator_t *dc) +{ + return smartlist_len(dc->all_rsa_sha1_lst); +} + +vote_routerstatus_t ** +dircollator_get_votes_for_router(dircollator_t *dc, int idx) +{ + tor_assert(idx < smartlist_len(dc->all_rsa_sha1_lst)); + return digestmap_get(dc->by_rsa_sha1, + smartlist_get(dc->all_rsa_sha1_lst, idx)); +} + |