diff options
Diffstat (limited to 'src/or/rendcommon.c')
-rw-r--r-- | src/or/rendcommon.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 7f7d04bdaa..79509cbe2f 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -17,8 +17,10 @@ #include "rendmid.h" #include "rendservice.h" #include "rephist.h" +#include "router.h" #include "routerlist.h" #include "routerparse.h" +#include "networkstatus.h" /** Return 0 if one and two are the same service ids, else -1 or 1 */ int @@ -935,3 +937,75 @@ rend_data_client_create(const char *onion_address, const char *desc_id, return NULL; } +/** Determine the routers that are responsible for <b>id</b> (binary) and + * add pointers to those routers' routerstatus_t to <b>responsible_dirs</b>. + * Return -1 if we're returning an empty smartlist, else return 0. + */ +int +hid_serv_get_responsible_directories(smartlist_t *responsible_dirs, + const char *id) +{ + int start, found, n_added = 0, i; + networkstatus_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."); + return -1; + } + tor_assert(id); + start = networkstatus_vote_find_entry_idx(c, id, &found); + 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; + } + if (++i == smartlist_len(c->routerstatus_list)) + i = 0; + } while (i != start); + + /* Even though we don't have the desired number of hidden service + * directories, be happy if we got any. */ + return smartlist_len(responsible_dirs) ? 0 : -1; +} + +/** Return true if this node is currently acting as hidden service + * directory, false otherwise. */ +int +hid_serv_acting_as_directory(void) +{ + const routerinfo_t *me = router_get_my_routerinfo(); + if (!me) + return 0; + return 1; +} + +/** Return true if this node is responsible for storing the descriptor ID + * in <b>query</b> and false otherwise. */ +MOCK_IMPL(int, hid_serv_responsible_for_desc_id, + (const char *query)) +{ + const 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_new(); + if (hid_serv_get_responsible_directories(responsible, query) < 0) { + smartlist_free(responsible); + return 0; + } + 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; +} |