summaryrefslogtreecommitdiff
path: root/src/or/routerlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/routerlist.c')
-rw-r--r--src/or/routerlist.c203
1 files changed, 109 insertions, 94 deletions
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 2ffc2b254f..95e048cb77 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -4289,24 +4289,31 @@ routers_sort_by_identity(smartlist_t *routers)
smartlist_sort(routers, _compare_routerinfo_by_id_digest);
}
+#if 0
/** Return the first router that is acting as hidden service directory and that
* has a greater ID than <b>id</b>; if all routers have smaller IDs than
* <b>id</b>, return the router with the smallest ID; if the router list is
* NULL, or has no elements, return NULL.
*/
-routerinfo_t *
-hid_serv_next_directory(const char *id, const smartlist_t *hs_dirs)
+routerstatus_t *
+hid_serv_next_directory(const char *id)
{
- int i;
- if (!hs_dirs) return NULL;
- if (smartlist_len(hs_dirs) == 0) return NULL;
- for (i = 0; i < smartlist_len(hs_dirs); i++) {
- routerinfo_t *router = smartlist_get(hs_dirs, i);
- if (memcmp(router->cache_info.identity_digest, id, DIGEST_LEN) > 0) {
- return router;
- }
- }
- return smartlist_get(hs_dirs, 0);
+ networkstatus_vote_t *c = networkstatus_get_latest_consensus();
+ int idx, i, f;
+ if (!c || !smartlist_len(c->routerstatus_list)) return NULL;
+ idx = networkstatus_vote_find_entry_idx(c, id, &f);
+ if (f) ++idx;
+ if (idx >= smartlist_len(c->routerstatus_list))
+ idx = 0;
+ i = idx;
+ do {
+ routerstatus_t *rs = smartlist_get(c->routerstatus_list, i);
+ if (rs->is_hs_dir)
+ return rs;
+ if (++i == smartlist_len(c->routerstatus_list))
+ i = 0;
+ } while (i != idx);
+ return NULL;
}
/** Return the first router that is acting as hidden service directory and that
@@ -4314,20 +4321,27 @@ hid_serv_next_directory(const char *id, const smartlist_t *hs_dirs)
* <b>id</b>, return the router with the highest ID; if the router list is
* NULL, or has no elements, return NULL.
*/
-routerinfo_t *
-hid_serv_previous_directory(const char *id, const smartlist_t *hs_dirs)
+routerstatus_t *
+hid_serv_previous_directory(const char *id)
{
- int i;
- if (!hs_dirs) return NULL;
- if (smartlist_len(hs_dirs) == 0) return NULL;
- for (i = smartlist_len(hs_dirs) - 1; i >= 0; i--) {
- routerinfo_t *router = smartlist_get(hs_dirs, i);
- if (memcmp(router->cache_info.identity_digest, id, DIGEST_LEN) < 0) {
- return router;
- }
- }
- return smartlist_get(hs_dirs, smartlist_len(hs_dirs) - 1);
+ networkstatus_vote_t *c = networkstatus_get_latest_consensus();
+ int idx, i, f;
+ if (!c || !smartlist_len(c->routerstatus_list)) return NULL;
+ idx = networkstatus_vote_find_entry_idx(c, id, &f);
+ --idx;
+ if (idx < 0)
+ idx = smartlist_len(c->routerstatus_list) - 1;
+ i = idx;
+ do {
+ routerstatus_t *rs = smartlist_get(c->routerstatus_list, i);
+ if (rs->is_hs_dir)
+ return rs;
+ if (--i < 0)
+ i = smartlist_len(c->routerstatus_list) - 1;
+ } while (i != idx);
+ return NULL;
}
+#endif
/** Returns true, if we are aware of enough hidden service directory to
* usefully perform v2 rend operations on them (publish, fetch, replicate),
@@ -4340,100 +4354,93 @@ hid_serv_have_enough_directories(const smartlist_t *hs_dirs)
/** Determine the REND_NUMBER_OF_CONSECUTIVE_REPLICAS routers that are
* responsible for <b>id</b> (binary) and add pointers to those routers'
- * routerinfo_t to <b>responsible_dirs</b>. If we don't have enough
+ * routerstatus_t to <b>responsible_dirs</b>. If we don't have enough
* hidden service directories, return -1, else 0. */
-/*XXXX020 yield routerstatus_t, not routerinfo_t! */
int
hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
- const char *id,
- const smartlist_t *hs_dirs)
+ const char *id)
{
- const char *digest;
- int i;
- routerinfo_t *router;
- char id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
- tor_assert(id);
- base32_encode(id_base32, sizeof(id_base32), id, DIGEST_LEN);
- if (!hid_serv_have_enough_directories(hs_dirs)) {
- log_warn(LD_REND, "We don't have enough hidden service directories to "
- "perform v2 rendezvous operations!");
- return -1;
+ int start, found, n_added = 0, i;
+ networkstatus_vote_t *c = networkstatus_get_latest_consensus();
+ if (!c || !smartlist_len(c->routerstatus_list)) {
+ log_warn(LD_REND, "We don't have a consensus, so we can't perform v2 "
+ "rendezvous operations.");
}
- digest = id;
- for (i = 0; i < REND_NUMBER_OF_CONSECUTIVE_REPLICAS; i++) {
- router = hid_serv_next_directory(digest, hs_dirs);
- digest = router->cache_info.identity_digest;
- if (!router) {
- log_warn(LD_REND, "Could not determine next router in "
- "hidden service routing table.");
- return -1;
+ tor_assert(id);
+ start = networkstatus_vote_find_entry_idx(c, id, &found);
+ if (found) ++start;
+ if (start == smartlist_len(c->routerstatus_list)) start = 0;
+ i = start;
+ do {
+ routerstatus_t *r = smartlist_get(c->routerstatus_list, i);
+ if (r->is_hs_dir) {
+ smartlist_add(responsible_dirs, r);
+ if (++n_added == REND_NUMBER_OF_CONSECUTIVE_REPLICAS)
+ return 0;
}
- smartlist_add(responsible_dirs, router);
- }
- return 0;
+ if (++i == smartlist_len(c->routerstatus_list))
+ i = 0;
+ } while (i != start);
+
+ log_warn(LD_REND, "We don't have enough hidden service directories to "
+ "perform v2 rendezvous operations!");
+ return -1;
}
-/** Create a list of routerinfo_t in ascending order of identity digests
+/** Create a list of routerstatus_t in ascending order of identity digests
* containing all routers that have been assigned as hidden service
* directories by the directory authorities; this list can be used as
* hidden service routing table. */
-/*XXXX020 using routerinfo_t here instead of routerstatus_t is error-prone.
- * Best change that. */
smartlist_t *
-hid_serv_create_routing_table(void)
+hid_serv_create_routing_table_st(void)
{
smartlist_t *hs_dirs = smartlist_create();
- tor_assert(routerlist);
- /* Copy the routerinfo_t's of all hidden service directories to a new
+ networkstatus_vote_t *c = networkstatus_get_latest_consensus();
+ if (!c) return hs_dirs;
+ /* Copy the routerstatus_t's of all hidden service directories to a new
* smartlist. */
- SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, r,
+ SMARTLIST_FOREACH(c->routerstatus_list, routerstatus_t *, r,
{
if (r->is_hs_dir)
smartlist_add(hs_dirs, r);
});
- routers_sort_by_identity(hs_dirs);
+ /* It's already sorted by ID. */
return hs_dirs;
}
/** Return true if this node is currently acting as hidden service
* directory, false otherwise. */
int
-hid_serv_acting_as_directory(const smartlist_t *hs_dirs)
+hid_serv_acting_as_directory(void)
{
- routerinfo_t *me = routerlist_find_my_routerinfo();
- int found_me = 0;
- if (!me) {
+ routerinfo_t *me = router_get_my_routerinfo();
+ networkstatus_vote_t *c;
+ routerstatus_t *rs;
+ if (!me)
return 0;
- }
if (!get_options()->HidServDirectoryV2) {
log_info(LD_REND, "We are not acting as hidden service directory, "
"because we have not been configured as such.");
return 0;
}
- if (!hs_dirs) {
- /* routing table is NULL */
- log_info(LD_REND, "We are not acting as hidden service directory, "
- "because our own routing table is NULL.");
+ if (!(c = networkstatus_get_latest_consensus())) {
+ log_info(LD_REND, "There's no consensus, so I can't tell if I'm a hidden "
+ "service directory");
return 0;
}
- SMARTLIST_FOREACH(hs_dirs, routerinfo_t *, router,
- {
- if (router_is_me(router)) {
- found_me = 1;
- break;
- }
- });
- if (!found_me) {
- /* not acting as HS Dir */
- char me_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
- base32_encode(me_base32, sizeof(me_base32),
- me->cache_info.identity_digest, DIGEST_LEN);
- log_info(LD_REND, "We are not acting as hidden service directory, "
- "because we are not listed as such in our own "
- "routing table. me=%s, num entries in RT=%d",
- me_base32, smartlist_len(hs_dirs));
+ rs = networkstatus_vote_find_entry(c, me->cache_info.identity_digest);
+ if (!rs) {
+ log_info(LD_REND, "We're not listed in the consensus, so we're not "
+ "being a hidden service directory.");
return 0;
}
+ if (!rs->is_hs_dir) {
+ log_info(LD_REND, "We're not listed as a hidden service directory in "
+ "the consensus, so we won't be one.");
+ return 0;
+ }
+
+#if 0
if (smartlist_len(hs_dirs) <= REND_NUMBER_OF_CONSECUTIVE_REPLICAS) {
/* too few HS Dirs -- that won't work */
log_info(LD_REND, "We are not acting as hidden service directory, "
@@ -4441,26 +4448,34 @@ hid_serv_acting_as_directory(const smartlist_t *hs_dirs)
"directories in the routing table.");
return 0;
}
+#endif
return 1;
}
/** Return true if this node is responsible for storing the descriptor ID
* in <b>query</b> and false otherwise. */
int
-hid_serv_responsible_for_desc_id(const char *query, smartlist_t *hs_dirs)
+hid_serv_responsible_for_desc_id(const char *query)
{
- const char *me;
- const char *predecessor;
- routerinfo_t *router;
- int i;
- if (!hid_serv_acting_as_directory(hs_dirs))
+ routerinfo_t *me;
+ routerstatus_t *last_rs;
+ const char *my_id, *last_id;
+ int result;
+ smartlist_t *responsible;
+ if (!hid_serv_acting_as_directory())
+ return 0;
+ if (!(me = router_get_my_routerinfo()))
+ return 0; /* This is redundant, but let's be paranoid. */
+ my_id = me->cache_info.identity_digest;
+ responsible = smartlist_create();
+ if (hid_serv_get_responsible_directories(responsible, query)<0) {
+ smartlist_free(responsible);
return 0;
- me = router_get_my_routerinfo()->cache_info.identity_digest;
- predecessor = me;
- for (i = 0; i < REND_NUMBER_OF_CONSECUTIVE_REPLICAS; i++) {
- router = hid_serv_previous_directory(predecessor, hs_dirs);
- predecessor = router->cache_info.identity_digest;
}
- return rend_id_is_in_interval(query, predecessor, me);
+ last_rs = smartlist_get(responsible, smartlist_len(responsible)-1);
+ last_id = last_rs->identity_digest;
+ result = rend_id_is_in_interval(my_id, query, last_id);
+ smartlist_free(responsible);
+ return result;
}