diff options
-rw-r--r-- | src/or/directory.c | 25 | ||||
-rw-r--r-- | src/or/networkstatus.c | 11 | ||||
-rw-r--r-- | src/or/or.h | 19 | ||||
-rw-r--r-- | src/or/rendclient.c | 5 | ||||
-rw-r--r-- | src/or/rendcommon.c | 16 | ||||
-rw-r--r-- | src/or/rendservice.c | 9 | ||||
-rw-r--r-- | src/or/routerlist.c | 203 |
7 files changed, 148 insertions, 140 deletions
diff --git a/src/or/directory.c b/src/or/directory.c index 7d58ad8af5..29e852f512 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3084,12 +3084,11 @@ dir_split_resource_into_fingerprints(const char *resource, /* I guess they should. -KL */ void directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs, - const char *service_id, int seconds_valid, - smartlist_t *hs_dirs) + const char *service_id, int seconds_valid) { int i, j; smartlist_t *responsible_dirs; - routerinfo_t *hs_dir; + routerstatus_t *hs_dir; if (smartlist_len(desc_ids) != REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS || smartlist_len(desc_strs) != REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS) { log_warn(LD_BUG, "Could not post descriptors to hidden service " @@ -3102,8 +3101,7 @@ directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs, const char *desc_id = smartlist_get(desc_ids, i); const char *desc_str = smartlist_get(desc_strs, i); /* Determine responsible dirs. */ - if (hid_serv_get_responsible_directories(responsible_dirs, desc_id, - hs_dirs) < 0) { + if (hid_serv_get_responsible_directories(responsible_dirs, desc_id) < 0) { log_warn(LD_REND, "Could not determine the responsible hidden service " "directories to post descriptors to."); smartlist_free(responsible_dirs); @@ -3115,9 +3113,7 @@ directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs, char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; hs_dir = smartlist_get(responsible_dirs, j); /* Send publish request. */ - directory_initiate_command(hs_dir->address, hs_dir->addr, - hs_dir->or_port, hs_dir->dir_port, 1, - hs_dir->cache_info.identity_digest, + directory_initiate_command_routerstatus(hs_dir, DIR_PURPOSE_UPLOAD_RENDDESC_V2, ROUTER_PURPOSE_GENERAL, 1, NULL, desc_str, strlen(desc_str), 0); @@ -3142,18 +3138,16 @@ directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs, * and fetch the descriptor belonging to this ID from one of them; * <b>query</b> is only passed for pretty log statements. */ void -directory_get_from_hs_dir(const char *desc_id, const char *query, - smartlist_t *hs_dirs) +directory_get_from_hs_dir(const char *desc_id, const char *query) { smartlist_t *responsible_dirs = smartlist_create(); - routerinfo_t *hs_dir; + routerstatus_t *hs_dir; char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; tor_assert(desc_id); tor_assert(query); tor_assert(strlen(query) == REND_SERVICE_ID_LEN); /* Determine responsible dirs. */ - if (hid_serv_get_responsible_directories(responsible_dirs, desc_id, - hs_dirs) < 0) { + if (hid_serv_get_responsible_directories(responsible_dirs, desc_id) < 0) { log_warn(LD_REND, "Could not determine the responsible hidden service " "directories to fetch descriptors."); smartlist_free(responsible_dirs); @@ -3170,9 +3164,8 @@ directory_get_from_hs_dir(const char *desc_id, const char *query, base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_id, DIGEST_LEN); /* Send fetch request. */ - directory_initiate_command(hs_dir->address, hs_dir->addr, - hs_dir->or_port, hs_dir->dir_port, 1, - hs_dir->cache_info.identity_digest, + directory_initiate_command_routerstatus( + hs_dir, DIR_PURPOSE_FETCH_RENDDESC_V2, ROUTER_PURPOSE_GENERAL, 1, desc_id_base32, NULL, 0, 0); diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index f08cf5334e..57b4996c63 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -754,6 +754,17 @@ networkstatus_vote_find_entry(networkstatus_vote_t *ns, const char *digest) _compare_digest_to_routerstatus_entry); } +/*XXXX020 make this static once functions are moved into this file. */ +/** DOCDOC */ +int +networkstatus_vote_find_entry_idx(networkstatus_vote_t *ns, + const char *digest, int *found_out) +{ + return smartlist_bsearch_idx(ns->routerstatus_list, digest, + _compare_digest_to_routerstatus_entry, + found_out); +} + /** Return a list of the v2 networkstatus documents. */ const smartlist_t * networkstatus_get_v2_list(void) diff --git a/src/or/or.h b/src/or/or.h index 04f94602b9..f6c80ce96c 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2912,10 +2912,8 @@ char *directory_dump_request_log(void); int router_supports_extrainfo(const char *identity_digest, int is_authority); void directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *descs, - const char *service_id, int seconds_valid, - smartlist_t *hs_dirs); -void directory_get_from_hs_dir(const char *desc_id, const char *query, - smartlist_t *hs_dirs); + const char *service_id, int seconds_valid); +void directory_get_from_hs_dir(const char *desc_id, const char *query); time_t download_status_increment_failure(download_status_t *dls, int status_code, const char *item, @@ -3191,6 +3189,8 @@ routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest); routerstatus_t *networkstatus_vote_find_entry(networkstatus_vote_t *ns, const char *digest); +int networkstatus_vote_find_entry_idx(networkstatus_vote_t *ns, + const char *digest, int *found_out); const smartlist_t *networkstatus_get_v2_list(void); download_status_t *router_get_dl_status_by_descriptor_digest(const char *d); routerstatus_t *router_get_consensus_status_by_id(const char *digest); @@ -3779,17 +3779,18 @@ void routerlist_assert_ok(routerlist_t *rl); const char *esc_router_info(routerinfo_t *router); void routers_sort_by_identity(smartlist_t *routers); -smartlist_t *hid_serv_create_routing_table(void); +smartlist_t *hid_serv_create_routing_table_st(void); int hid_serv_have_enough_directories(const smartlist_t *hs_dirs); int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs, - const char *id, - const smartlist_t *hs_dirs); + const char *id); +#if 0 routerinfo_t *hid_serv_next_directory(const char *id, const smartlist_t *hs_dirs); routerinfo_t *hid_serv_previous_directory(const char *id, const smartlist_t *hs_dirs); -int hid_serv_acting_as_directory(const smartlist_t *hs_dirs); -int hid_serv_responsible_for_desc_id(const char *id, smartlist_t *hs_dirs); +#endif +int hid_serv_acting_as_directory(void); +int hid_serv_responsible_for_desc_id(const char *id); /********************************* routerparse.c ************************/ diff --git a/src/or/rendclient.c b/src/or/rendclient.c index da86808f0c..b0fe325a92 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -288,7 +288,6 @@ rend_client_refetch_v2_renddesc(const char *query) { char descriptor_id[DIGEST_LEN]; int replica; - smartlist_t *hs_dirs; tor_assert(query); tor_assert(strlen(query) == REND_SERVICE_ID_LEN); /* Are we configured to fetch descriptors? */ @@ -306,9 +305,7 @@ rend_client_refetch_v2_renddesc(const char *query) "descriptor ID did not succeed."); return; } - hs_dirs = hid_serv_create_routing_table(); - directory_get_from_hs_dir(descriptor_id, query, hs_dirs); - smartlist_free(hs_dirs); + directory_get_from_hs_dir(descriptor_id, query); return; } diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 196d6d488e..80c9de95ea 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -681,7 +681,6 @@ void rend_cache_clean_v2_descs_as_dir(void) { digestmap_iter_t *iter; - smartlist_t *hs_dirs = hid_serv_create_routing_table(); time_t cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW; for (iter = digestmap_iter_init(rend_cache_v2_dir); !digestmap_iter_done(iter); ) { @@ -691,7 +690,7 @@ rend_cache_clean_v2_descs_as_dir(void) digestmap_iter_get(iter, &key, &val); ent = val; if (ent->parsed->timestamp < cutoff || - !hid_serv_responsible_for_desc_id(key, hs_dirs)) { + !hid_serv_responsible_for_desc_id(key)) { char key_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; base32_encode(key_base32, sizeof(key_base32), key, DIGEST_LEN); log_info(LD_REND, "Removing descriptor with ID '%s' from cache", @@ -702,7 +701,6 @@ rend_cache_clean_v2_descs_as_dir(void) iter = digestmap_iter_next(rend_cache_v2_dir, iter); } } - smartlist_free(hs_dirs); } /** Determines whether <b>a</b> is in the interval of <b>b</b> (excluded) and @@ -807,7 +805,6 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc) { rend_cache_entry_t *e; char desc_id_digest[DIGEST_LEN]; - smartlist_t *hs_dirs; tor_assert(rend_cache_v2_dir); if (base32_decode(desc_id_digest, DIGEST_LEN, desc_id, REND_DESC_ID_V2_LEN_BASE32) < 0) { @@ -816,15 +813,12 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc) return -1; } /* Determine if we are responsible. */ - hs_dirs = hid_serv_create_routing_table(); - if (hid_serv_responsible_for_desc_id(desc_id_digest, hs_dirs) < 0) { + if (hid_serv_responsible_for_desc_id(desc_id_digest) < 0) { log_info(LD_REND, "Could not answer fetch request for v2 descriptor; " "either we are no hidden service directory, or we are " "not responsible for the requested ID."); - smartlist_free(hs_dirs); return -1; } - smartlist_free(hs_dirs); /* Lookup descriptor and return. */ e = digestmap_get(rend_cache_v2_dir, desc_id_digest); if (e) { @@ -940,14 +934,12 @@ rend_cache_store_v2_desc_as_dir(const char *desc) const char *next_desc; rend_cache_entry_t *e; time_t now = time(NULL); - smartlist_t *hs_dirs = hid_serv_create_routing_table(); tor_assert(rend_cache_v2_dir); tor_assert(desc); - if (!hid_serv_acting_as_directory(hs_dirs)) { + if (!hid_serv_acting_as_directory()) { /* Cannot store descs, because we are (currently) not acting as * hidden service directory. */ log_info(LD_REND, "Cannot store descs: Not acting as hs dir"); - smartlist_free(hs_dirs); return -1; } while (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content, @@ -960,7 +952,7 @@ rend_cache_store_v2_desc_as_dir(const char *desc) desc_id, DIGEST_LEN); /* Is desc ID in the range that we are (directly or indirectly) responsible * for? */ - if (!hid_serv_responsible_for_desc_id(desc_id, hs_dirs)) { + if (!hid_serv_responsible_for_desc_id(desc_id)) { log_info(LD_REND, "Service descriptor with desc ID %s is not in " "interval that we are responsible for.", desc_id_base32); diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 7665b2793f..0b9ec22357 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1100,7 +1100,7 @@ upload_service_descriptor(rend_service_t *service) /* Upload v2 descriptor? */ if (service->descriptor_versions & (1 << 2) && get_options()->PublishHidServDescriptors) { - smartlist_t *hs_dirs = hid_serv_create_routing_table(); + smartlist_t *hs_dirs = hid_serv_create_routing_table_st(); if (hid_serv_have_enough_directories(hs_dirs)) { int seconds_valid; smartlist_t *desc_strs = smartlist_create(); @@ -1119,8 +1119,7 @@ upload_service_descriptor(rend_service_t *service) rend_get_service_id(service->desc->pk, serviceid); log_info(LD_REND, "Sending publish request for hidden service %s", serviceid); - directory_post_to_hs_dir(desc_ids, desc_strs, serviceid, seconds_valid, - hs_dirs); + directory_post_to_hs_dir(desc_ids, desc_strs, serviceid, seconds_valid); /* Free memory for descriptors. */ for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++) { tor_free(smartlist_get(desc_strs, i)); @@ -1148,7 +1147,7 @@ upload_service_descriptor(rend_service_t *service) return; } directory_post_to_hs_dir(desc_ids, desc_strs, serviceid, - seconds_valid, hs_dirs); + seconds_valid); /* Free memory for descriptors. */ for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++) { tor_free(smartlist_get(desc_strs, i)); @@ -1157,10 +1156,10 @@ upload_service_descriptor(rend_service_t *service) smartlist_free(desc_strs); smartlist_free(desc_ids); } - smartlist_free(hs_dirs); uploaded = 1; log_info(LD_REND, "Successfully uploaded v2 rend descriptors!"); } + smartlist_free(hs_dirs); } /* If not uploaded, try again in one minute. */ 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; } |