diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/hs_client.c | 8 | ||||
-rw-r--r-- | src/or/hs_client.h | 2 | ||||
-rw-r--r-- | src/or/hs_common.c | 6 | ||||
-rw-r--r-- | src/or/hs_service.c | 218 | ||||
-rw-r--r-- | src/or/hs_service.h | 10 | ||||
-rw-r--r-- | src/or/main.c | 2 | ||||
-rw-r--r-- | src/or/networkstatus.c | 2 | ||||
-rw-r--r-- | src/or/nodelist.c | 2 | ||||
-rw-r--r-- | src/test/test_hs_common.c | 134 |
9 files changed, 167 insertions, 217 deletions
diff --git a/src/or/hs_client.c b/src/or/hs_client.c index 99be058eb7..19e20c0e8d 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -1251,3 +1251,11 @@ hs_client_reextend_intro_circuit(origin_circuit_t *circ) return ret; } +/* Release all the storage held by the client subsystem. */ +void +hs_client_free_all(void) +{ + /* Purge the hidden service request cache. */ + hs_purge_last_hid_serv_requests(); +} + diff --git a/src/or/hs_client.h b/src/or/hs_client.h index 8ed0501c91..86784f52c3 100644 --- a/src/or/hs_client.h +++ b/src/or/hs_client.h @@ -46,5 +46,7 @@ extend_info_t *hs_client_get_random_intro_from_edge( int hs_client_reextend_intro_circuit(origin_circuit_t *circ); +void hs_client_free_all(void); + #endif /* TOR_HS_CLIENT_H */ diff --git a/src/or/hs_common.c b/src/or/hs_common.c index d866ab6a8f..5ea44b97e7 100644 --- a/src/or/hs_common.c +++ b/src/or/hs_common.c @@ -19,6 +19,7 @@ #include "nodelist.h" #include "hs_cache.h" #include "hs_common.h" +#include "hs_client.h" #include "hs_ident.h" #include "hs_service.h" #include "policies.h" @@ -1206,12 +1207,16 @@ node_has_hsdir_index(const node_t *node, int is_for_next_period) if (BUG(node->hsdir_index == NULL) || BUG(tor_mem_is_zero((const char*)node->hsdir_index->current, DIGEST256_LEN))) { + log_warn(LD_BUG, "Zero current index (ri: %p, rs: %p, md: %p)", + node->ri, node->rs, node->md); return 0; } if (is_for_next_period && BUG(tor_mem_is_zero((const char*)node->hsdir_index->next, DIGEST256_LEN))) { + log_warn(LD_BUG, "Zero next index (ri: %p, rs: %p, md: %p)", + node->ri, node->rs, node->md); return 0; } @@ -1700,6 +1705,7 @@ hs_free_all(void) hs_circuitmap_free_all(); hs_service_free_all(); hs_cache_free_all(); + hs_client_free_all(); } /* For the given origin circuit circ, decrement the number of rendezvous diff --git a/src/or/hs_service.c b/src/or/hs_service.c index 5ff118222d..796efa0c9b 100644 --- a/src/or/hs_service.c +++ b/src/or/hs_service.c @@ -78,6 +78,7 @@ static smartlist_t *hs_service_staging_list; static int consider_republishing_hs_descriptors = 0; static void set_descriptor_revision_counter(hs_descriptor_t *hs_desc); +static void move_descriptors(hs_service_t *src, hs_service_t *dst); /* Helper: Function to compare two objects in the service map. Return 1 if the * two service have the same master public identity key. */ @@ -714,37 +715,6 @@ close_service_circuits(hs_service_t *service) close_service_rp_circuits(service); } -/* Move introduction points from the src descriptor to the dst descriptor. The - * destination service intropoints are wiped out if any before moving. */ -static void -move_descriptor_intro_points(hs_service_descriptor_t *src, - hs_service_descriptor_t *dst) -{ - tor_assert(src); - tor_assert(dst); - - digest256map_free(dst->intro_points.map, service_intro_point_free_); - dst->intro_points.map = src->intro_points.map; - /* Nullify the source. */ - src->intro_points.map = NULL; -} - -/* Move introduction points from the src service to the dst service. The - * destination service intropoints are wiped out if any before moving. */ -static void -move_intro_points(hs_service_t *src, hs_service_t *dst) -{ - tor_assert(src); - tor_assert(dst); - - if (src->desc_current && dst->desc_current) { - move_descriptor_intro_points(src->desc_current, dst->desc_current); - } - if (src->desc_next && dst->desc_next) { - move_descriptor_intro_points(src->desc_next, dst->desc_next); - } -} - /* Move every ephemeral services from the src service map to the dst service * map. It is possible that a service can't be register to the dst map which * won't stop the process of moving them all but will trigger a log warn. */ @@ -785,6 +755,26 @@ service_escaped_dir(const hs_service_t *s) escaped(s->config.directory_path); } +/** Move the hidden service state from <b>src</b> to <b>dst</b>. We do this + * when we receive a SIGHUP: <b>dst</b> is the post-HUP service */ +static void +move_hs_state(hs_service_t *src_service, hs_service_t *dst_service) +{ + tor_assert(src_service); + tor_assert(dst_service); + + hs_service_state_t *src = &src_service->state; + hs_service_state_t *dst = &dst_service->state; + + /* Let's do a shallow copy */ + dst->intro_circ_retry_started_time = src->intro_circ_retry_started_time; + dst->num_intro_circ_launched = src->num_intro_circ_launched; + dst->in_overlap_period = src->in_overlap_period; + dst->replay_cache_rend_cookie = src->replay_cache_rend_cookie; + + src->replay_cache_rend_cookie = NULL; /* steal pointer reference */ +} + /* Register services that are in the staging list. Once this function returns, * the global service map will be set with the right content and all non * surviving services will be cleaned up. */ @@ -817,13 +807,15 @@ register_all_services(void) * transfer the intro points to it. */ s = find_service(hs_service_map, &snew->keys.identity_pk); if (s) { - /* Pass ownership of intro points from s (the current service) to snew - * (the newly configured one). */ - move_intro_points(s, snew); + /* Pass ownership of the descriptors from s (the current service) to + * snew (the newly configured one). */ + move_descriptors(s, snew); + move_hs_state(s, snew); /* Remove the service from the global map because after this, we need to * go over the remaining service in that map that aren't surviving the * reload to close their circuits. */ remove_service(hs_service_map, s); + hs_service_free(s); } /* Great, this service is now ready to be added to our new map. */ if (BUG(register_service(new_service_map, snew) < 0)) { @@ -972,8 +964,6 @@ service_descriptor_free(hs_service_descriptor_t *desc) hs_descriptor_free(desc->desc); memwipe(&desc->signing_kp, 0, sizeof(desc->signing_kp)); memwipe(&desc->blinded_kp, 0, sizeof(desc->blinded_kp)); - SMARTLIST_FOREACH(desc->hsdir_missing_info, char *, id, tor_free(id)); - smartlist_free(desc->hsdir_missing_info); /* Cleanup all intro points. */ digest256map_free(desc->intro_points.map, service_intro_point_free_); digestmap_free(desc->intro_points.failed_id, tor_free_); @@ -993,11 +983,37 @@ service_descriptor_new(void) /* Initialize the intro points map. */ sdesc->intro_points.map = digest256map_new(); sdesc->intro_points.failed_id = digestmap_new(); - sdesc->hsdir_missing_info = smartlist_new(); sdesc->previous_hsdirs = smartlist_new(); return sdesc; } +/* Move descriptor(s) from the src service to the dst service. We do this + * during SIGHUP when we re-create our hidden services. */ +static void +move_descriptors(hs_service_t *src, hs_service_t *dst) +{ + tor_assert(src); + tor_assert(dst); + + if (src->desc_current) { + /* Nothing should be there, but clean it up just in case */ + if (BUG(dst->desc_current)) { + service_descriptor_free(dst->desc_current); + } + dst->desc_current = src->desc_current; + src->desc_current = NULL; + } + + if (src->desc_next) { + /* Nothing should be there, but clean it up just in case */ + if (BUG(dst->desc_next)) { + service_descriptor_free(dst->desc_next); + } + dst->desc_next = src->desc_next; + src->desc_next = NULL; + } +} + /* From the given service, remove all expired failing intro points for each * descriptor. */ static void @@ -1546,7 +1562,6 @@ service_desc_note_upload(hs_service_descriptor_t *desc, const node_t *hsdir) if (!smartlist_contains_string(desc->previous_hsdirs, b64_digest)) { smartlist_add_strdup(desc->previous_hsdirs, b64_digest); - smartlist_sort_strings(desc->previous_hsdirs); } } @@ -2317,6 +2332,10 @@ upload_descriptor_to_all(const hs_service_t *service, hs_get_responsible_hsdirs(&desc->blinded_kp.pubkey, desc->time_period_num, for_next_period, 0, responsible_dirs); + /** Clear list of previous hsdirs since we are about to upload to a new + * list. Let's keep it up to date. */ + service_desc_clear_previous_hsdirs(desc); + /* For each responsible HSDir we have, initiate an upload command. */ SMARTLIST_FOREACH_BEGIN(responsible_dirs, const routerstatus_t *, hsdir_rs) { @@ -2324,18 +2343,6 @@ upload_descriptor_to_all(const hs_service_t *service, /* Getting responsible hsdir implies that the node_t object exists for the * routerstatus_t found in the consensus else we have a problem. */ tor_assert(hsdir_node); - /* Do not upload to an HSDir we don't have a descriptor for. */ - if (!node_has_descriptor(hsdir_node)) { - log_info(LD_REND, "Missing descriptor for HSDir %s. Not uploading " - "descriptor. We'll try later once we have it.", - safe_str_client(node_describe(hsdir_node))); - /* Once we get new directory information, this HSDir will be retried if - * we ever get the descriptor. */ - smartlist_add(desc->hsdir_missing_info, - tor_memdup(hsdir_rs->identity_digest, DIGEST_LEN)); - continue; - } - /* Upload this descriptor to the chosen directory. */ upload_descriptor_to_hsdir(service, desc, hsdir_node); } SMARTLIST_FOREACH_END(hsdir_rs); @@ -2366,9 +2373,8 @@ STATIC int service_desc_hsdirs_changed(const hs_service_t *service, const hs_service_descriptor_t *desc) { - int retval = 0; + int should_reupload = 0; smartlist_t *responsible_dirs = smartlist_new(); - smartlist_t *b64_responsible_dirs = smartlist_new(); /* No desc upload has happened yet: it will happen eventually */ if (!desc->previous_hsdirs || !smartlist_len(desc->previous_hsdirs)) { @@ -2379,32 +2385,24 @@ service_desc_hsdirs_changed(const hs_service_t *service, hs_get_responsible_hsdirs(&desc->blinded_kp.pubkey, desc->time_period_num, service->desc_next == desc, 0, responsible_dirs); - /* Make a second list with their b64ed identity digests, so that we can - * compare it with out previous list of hsdirs */ + /* Check if any new hsdirs have been added to the responsible hsdirs set: + * Iterate over the list of new hsdirs, and reupload if any of them is not + * present in the list of previous hsdirs. + */ SMARTLIST_FOREACH_BEGIN(responsible_dirs, const routerstatus_t *, hsdir_rs) { char b64_digest[BASE64_DIGEST_LEN+1] = {0}; digest_to_base64(b64_digest, hsdir_rs->identity_digest); - smartlist_add_strdup(b64_responsible_dirs, b64_digest); - } SMARTLIST_FOREACH_END(hsdir_rs); - - /* Sort this new smartlist so that we can compare it with the other one */ - smartlist_sort_strings(b64_responsible_dirs); - /* Check whether the set of HSDirs changed */ - if (!smartlist_strings_eq(b64_responsible_dirs, desc->previous_hsdirs)) { - log_info(LD_GENERAL, "Received new dirinfo and set of hsdirs changed!"); - retval = 1; - } else { - log_debug(LD_GENERAL, "No change in hsdir set!"); - } + if (!smartlist_contains_string(desc->previous_hsdirs, b64_digest)) { + should_reupload = 1; + break; + } + } SMARTLIST_FOREACH_END(hsdir_rs); done: smartlist_free(responsible_dirs); - SMARTLIST_FOREACH(b64_responsible_dirs, char*, s, tor_free(s)); - smartlist_free(b64_responsible_dirs); - - return retval; + return should_reupload; } /* Return 1 if the given descriptor from the given service can be uploaded @@ -2724,58 +2722,6 @@ service_handle_introduce2(origin_circuit_t *circ, const uint8_t *payload, return -1; } -/* For a given service and a descriptor of that service, consider retrying to - * upload the descriptor to any directories from which we had missing - * information when originally tried to be uploaded. This is called when our - * directory information has changed. */ -static void -consider_hsdir_upload_retry(const hs_service_t *service, - hs_service_descriptor_t *desc) -{ - smartlist_t *responsible_dirs = NULL; - smartlist_t *still_missing_dirs = NULL; - - tor_assert(service); - tor_assert(desc); - - responsible_dirs = smartlist_new(); - still_missing_dirs = smartlist_new(); - - /* We first need to get responsible directories from the latest consensus so - * we can then make sure that the node that we were missing information for - * is still responsible for this descriptor. */ - hs_get_responsible_hsdirs(&desc->blinded_kp.pubkey, desc->time_period_num, - service->desc_next == desc, 0, responsible_dirs); - - SMARTLIST_FOREACH_BEGIN(responsible_dirs, const routerstatus_t *, rs) { - const node_t *node; - const char *id = rs->identity_digest; - if (!smartlist_contains_digest(desc->hsdir_missing_info, id)) { - continue; - } - /* We do need a node_t object and descriptor to perform an upload. If - * found, we remove the id from the missing dir list else we add it to the - * still missing dir list to keep track of id that are still missing. */ - node = node_get_by_id(id); - if (node && node_has_descriptor(node)) { - upload_descriptor_to_hsdir(service, desc, node); - smartlist_remove(desc->hsdir_missing_info, id); - } else { - smartlist_add(still_missing_dirs, tor_memdup(id, DIGEST_LEN)); - } - } SMARTLIST_FOREACH_END(rs); - - /* Switch the still missing dir list with the current missing dir list in - * the descriptor. It is possible that the list ends up empty which is what - * we want if we have no more missing dir. */ - SMARTLIST_FOREACH(desc->hsdir_missing_info, char *, id, tor_free(id)); - smartlist_free(desc->hsdir_missing_info); - desc->hsdir_missing_info = still_missing_dirs; - - /* No ownership of the routerstatus_t object in this list. */ - smartlist_free(responsible_dirs); -} - /* Add to list every filename used by service. This is used by the sandbox * subsystem. */ static void @@ -2802,16 +2748,6 @@ service_add_fnames_to_list(const hs_service_t *service, smartlist_t *list) /* Public API */ /* ========== */ -/* We just received a new batch of descriptors which might affect the shape of - * the HSDir hash ring. Signal that we should reexamine the hash ring and - * re-upload our HS descriptors if needed. */ -void -hs_hsdir_set_changed_consider_reupload(void) -{ - log_info(LD_REND, "New dirinfo arrived: consider reuploading descriptor"); - consider_republishing_hs_descriptors = 1; -} - /* Return the number of service we have configured and usable. */ unsigned int hs_service_get_num_services(void) @@ -2981,22 +2917,14 @@ hs_service_lists_fnames_for_sandbox(smartlist_t *file_list, } /* Called when our internal view of the directory has changed. We might have - * new descriptors for hidden service directories that we didn't have before - * so try them if it's the case. */ + * received a new batch of descriptors which might affect the shape of the + * HSDir hash ring. Signal that we should reexamine the hash ring and + * re-upload our HS descriptors if needed. */ void hs_service_dir_info_changed(void) { - /* For each service we have, check every descriptor and consider retrying to - * upload it to directories that we might have had missing information - * previously that is missing a router descriptor. */ - FOR_EACH_SERVICE_BEGIN(service) { - FOR_EACH_DESCRIPTOR_BEGIN(service, desc) { - /* This cleans up the descriptor missing hsdir information list if a - * successful upload is made or if any of the directory aren't - * responsible anymore for the service descriptor. */ - consider_hsdir_upload_retry(service, desc); - } FOR_EACH_DESCRIPTOR_END; - } FOR_EACH_SERVICE_END; + log_info(LD_REND, "New dirinfo arrived: consider reuploading descriptor"); + consider_republishing_hs_descriptors = 1; } /* Called when we get an INTRODUCE2 cell on the circ. Respond to the cell and diff --git a/src/or/hs_service.h b/src/or/hs_service.h index 57717fc927..317b9d795d 100644 --- a/src/or/hs_service.h +++ b/src/or/hs_service.h @@ -123,17 +123,10 @@ typedef struct hs_service_descriptor_t { * couldn't pick any nodes. */ unsigned int missing_intro_points : 1; - /* List of identity digests for hidden service directories to which we - * couldn't upload this descriptor because we didn't have its router - * descriptor at the time. If this list is non-empty, only the relays in this - * list are re-tried to upload this descriptor when our directory information - * have been updated. */ - smartlist_t *hsdir_missing_info; - /** List of the responsible HSDirs (their b64ed identity digest) last time we * uploaded this descriptor. If the set of responsible HSDirs is different * from this list, this means we received new dirinfo and we need to - * reupload our descriptor. This list is always sorted lexicographically. */ + * reupload our descriptor. */ smartlist_t *previous_hsdirs; } hs_service_descriptor_t; @@ -266,7 +259,6 @@ void hs_service_lists_fnames_for_sandbox(smartlist_t *file_list, smartlist_t *dir_list); int hs_service_set_conn_addr_port(const origin_circuit_t *circ, edge_connection_t *conn); -void hs_hsdir_set_changed_consider_reupload(void); void hs_service_dir_info_changed(void); void hs_service_run_scheduled_events(time_t now); diff --git a/src/or/main.c b/src/or/main.c index 5d51d1dead..a29fc315a2 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1483,7 +1483,7 @@ run_scheduled_events(time_t now) /* 12. launch diff computations. (This is free if there are none to * launch.) */ - if (server_mode(options)) { + if (dir_server_mode(options)) { consdiffmgr_rescan(); } } diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 69bff55cff..7136ab2968 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -2021,7 +2021,7 @@ networkstatus_set_current_consensus(const char *consensus, &c->digests, c->digest_sha3_as_signed, c->valid_after); - if (server_mode(get_options())) { + if (dir_server_mode(get_options())) { consdiffmgr_add_consensus(consensus, c); } } diff --git a/src/or/nodelist.c b/src/or/nodelist.c index 6acc87f967..155a511ca1 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -1810,7 +1810,7 @@ router_dir_info_changed(void) { need_to_update_have_min_dir_info = 1; rend_hsdir_routers_changed(); - hs_hsdir_set_changed_consider_reupload(); + hs_service_dir_info_changed(); } /** Return a string describing what we're missing before we have enough diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c index b9215ea187..9980892951 100644 --- a/src/test/test_hs_common.c +++ b/src/test/test_hs_common.c @@ -21,6 +21,7 @@ #include "networkstatus.h" #include "directory.h" #include "nodelist.h" +#include "routerlist.h" #include "statefile.h" /** Test the validation of HS v3 addresses */ @@ -362,20 +363,26 @@ test_desc_overlap_period_testnet(void *arg) static void helper_add_hsdir_to_networkstatus(networkstatus_t *ns, - const uint8_t *identity, - const uint8_t *curr_hsdir_index, + int identity_idx, const char *nickname, int is_hsdir) { routerstatus_t *rs = tor_malloc_zero(sizeof(routerstatus_t)); routerinfo_t *ri = tor_malloc_zero(sizeof(routerinfo_t)); - + uint8_t identity[DIGEST_LEN]; + uint8_t curr_hsdir_index[DIGEST256_LEN]; tor_addr_t ipv4_addr; + + memset(identity, identity_idx, sizeof(identity)); + memset(curr_hsdir_index, identity_idx, sizeof(curr_hsdir_index)); + memcpy(rs->identity_digest, identity, DIGEST_LEN); rs->is_hs_dir = is_hsdir; rs->supports_v3_hsdir = 1; + strlcpy(rs->nickname, nickname, sizeof(rs->nickname)); tor_addr_parse(&ipv4_addr, "1.2.3.4"); ri->addr = tor_addr_to_ipv4h(&ipv4_addr); + rs->addr = tor_addr_to_ipv4h(&ipv4_addr); ri->nickname = tor_strdup(nickname); ri->protocol_list = tor_strdup("HSDir=1-2 LinkAuth=3"); memcpy(ri->cache_info.identity_digest, identity, DIGEST_LEN); @@ -388,7 +395,7 @@ helper_add_hsdir_to_networkstatus(networkstatus_t *ns, smartlist_add(ns->routerstatus_list, rs); done: - ; + routerinfo_free(ri); } static networkstatus_t *mock_ns = NULL; @@ -412,6 +419,7 @@ mock_networkstatus_get_latest_consensus(void) mock_ns->valid_until = now+2; /* Create routerstatus list */ mock_ns->routerstatus_list = smartlist_new(); + mock_ns->type = NS_TYPE_CONSENSUS; return mock_ns; } @@ -435,36 +443,15 @@ test_responsible_hsdirs(void *arg) ns = networkstatus_get_latest_consensus(); { /* First router: HSdir */ - uint8_t identity[DIGEST_LEN]; - uint8_t curr_hsdir_index[DIGEST256_LEN]; - char nickname[] = "let_me"; - memset(identity, 1, sizeof(identity)); - memset(curr_hsdir_index, 1, sizeof(curr_hsdir_index)); - - helper_add_hsdir_to_networkstatus(ns, identity, - curr_hsdir_index, nickname, 1); + helper_add_hsdir_to_networkstatus(ns, 1, "igor", 1); } { /* Second HSDir */ - uint8_t identity[DIGEST_LEN]; - uint8_t curr_hsdir_index[DIGEST256_LEN]; - char nickname[] = "show_you"; - memset(identity, 2, sizeof(identity)); - memset(curr_hsdir_index, 2, sizeof(curr_hsdir_index)); - - helper_add_hsdir_to_networkstatus(ns, identity, - curr_hsdir_index, nickname, 1); + helper_add_hsdir_to_networkstatus(ns, 2, "victor", 1); } { /* Third relay but not HSDir */ - uint8_t identity[DIGEST_LEN]; - uint8_t curr_hsdir_index[DIGEST256_LEN]; - char nickname[] = "how_to_dance"; - memset(identity, 3, sizeof(identity)); - memset(curr_hsdir_index, 3, sizeof(curr_hsdir_index)); - - helper_add_hsdir_to_networkstatus(ns, identity, - curr_hsdir_index, nickname, 0); + helper_add_hsdir_to_networkstatus(ns, 3, "spyro", 0); } ed25519_keypair_t kp; @@ -579,32 +566,19 @@ test_desc_reupload_logic(void *arg) tt_int_op(hs_service_get_num_services(), OP_EQ, 1); /* Now let's create our hash ring: */ - { /* First HSDir */ - uint8_t identity[DIGEST_LEN]; - uint8_t curr_hsdir_index[DIGEST256_LEN]; - char nickname[] = "let_me"; - memset(identity, 1, sizeof(identity)); - memset(curr_hsdir_index, 1, sizeof(curr_hsdir_index)); - - helper_add_hsdir_to_networkstatus(ns, identity, - curr_hsdir_index, nickname, 1); - } - - { /* Second HSDir */ - uint8_t identity[DIGEST_LEN]; - uint8_t curr_hsdir_index[DIGEST256_LEN]; - char nickname[] = "show_you"; - memset(identity, 2, sizeof(identity)); - memset(curr_hsdir_index, 2, sizeof(curr_hsdir_index)); - - helper_add_hsdir_to_networkstatus(ns, identity, - curr_hsdir_index, nickname, 1); + { + helper_add_hsdir_to_networkstatus(ns, 1, "dingus", 1); + helper_add_hsdir_to_networkstatus(ns, 2, "clive", 1); + helper_add_hsdir_to_networkstatus(ns, 3, "aaron", 1); + helper_add_hsdir_to_networkstatus(ns, 4, "lizzie", 1); + helper_add_hsdir_to_networkstatus(ns, 5, "daewon", 1); + helper_add_hsdir_to_networkstatus(ns, 6, "clarke", 1); } /* Now let's upload our desc to all hsdirs */ upload_descriptor_to_all(service, desc, 0); /* Check that previous hsdirs were populated */ - tt_int_op(smartlist_len(desc->previous_hsdirs), OP_EQ, 2); + tt_int_op(smartlist_len(desc->previous_hsdirs), OP_EQ, 6); /* Poison next upload time so that we can see if it was changed by * router_dir_info_changed(). No changes in hash ring so far, so the upload @@ -613,17 +587,23 @@ test_desc_reupload_logic(void *arg) router_dir_info_changed(); tt_int_op(desc->next_upload_time, OP_EQ, 42); - /* Now change the HSDir hash ring by adding another node */ - - { /* Third HSDir */ - uint8_t identity[DIGEST_LEN]; - uint8_t curr_hsdir_index[DIGEST256_LEN]; - char nickname[] = "how_to_dance"; - memset(identity, 3, sizeof(identity)); - memset(curr_hsdir_index, 3, sizeof(curr_hsdir_index)); + /* Now change the HSDir hash ring by swapping nora for aaron. + * Start by clearing the hash ring */ + { + SMARTLIST_FOREACH(ns->routerstatus_list, + routerstatus_t *, rs, routerstatus_free(rs)); + smartlist_clear(ns->routerstatus_list); + nodelist_free_all(); + routerlist_free_all(); + } - helper_add_hsdir_to_networkstatus(ns, identity, - curr_hsdir_index, nickname, 1); + { /* Now add back all the nodes */ + helper_add_hsdir_to_networkstatus(ns, 1, "dingus", 1); + helper_add_hsdir_to_networkstatus(ns, 2, "clive", 1); + helper_add_hsdir_to_networkstatus(ns, 4, "lizzie", 1); + helper_add_hsdir_to_networkstatus(ns, 5, "daewon", 1); + helper_add_hsdir_to_networkstatus(ns, 6, "clarke", 1); + helper_add_hsdir_to_networkstatus(ns, 7, "nora", 1); } /* Now call service_desc_hsdirs_changed() and see that it detected the hash @@ -631,6 +611,35 @@ test_desc_reupload_logic(void *arg) time_t now = approx_time(); tt_assert(now); tt_int_op(service_desc_hsdirs_changed(service, desc), OP_EQ, 1); + tt_int_op(smartlist_len(desc->previous_hsdirs), OP_EQ, 6); + + /* Now order another upload and see that we keep having 6 prev hsdirs */ + upload_descriptor_to_all(service, desc, 0); + /* Check that previous hsdirs were populated */ + tt_int_op(smartlist_len(desc->previous_hsdirs), OP_EQ, 6); + + /* Now restore the HSDir hash ring to its original state by swapping back + aaron for nora */ + /* First clear up the hash ring */ + { + SMARTLIST_FOREACH(ns->routerstatus_list, + routerstatus_t *, rs, routerstatus_free(rs)); + smartlist_clear(ns->routerstatus_list); + nodelist_free_all(); + routerlist_free_all(); + } + + { /* Now populate the hash ring again */ + helper_add_hsdir_to_networkstatus(ns, 1, "dingus", 1); + helper_add_hsdir_to_networkstatus(ns, 2, "clive", 1); + helper_add_hsdir_to_networkstatus(ns, 3, "aaron", 1); + helper_add_hsdir_to_networkstatus(ns, 4, "lizzie", 1); + helper_add_hsdir_to_networkstatus(ns, 5, "daewon", 1); + helper_add_hsdir_to_networkstatus(ns, 6, "clarke", 1); + } + + /* Check that our algorithm catches this change of hsdirs */ + tt_int_op(service_desc_hsdirs_changed(service, desc), OP_EQ, 1); /* Now pretend that the descriptor changed, and order a reupload to all HSDirs. Make sure that the set of previous HSDirs was cleared. */ @@ -639,9 +648,14 @@ test_desc_reupload_logic(void *arg) /* Now reupload again: see that the prev hsdir set got populated again. */ upload_descriptor_to_all(service, desc, 0); - tt_int_op(smartlist_len(desc->previous_hsdirs), OP_EQ, 3); + tt_int_op(smartlist_len(desc->previous_hsdirs), OP_EQ, 6); done: + SMARTLIST_FOREACH(ns->routerstatus_list, + routerstatus_t *, rs, routerstatus_free(rs)); + smartlist_clear(ns->routerstatus_list); + networkstatus_vote_free(ns); + nodelist_free_all(); hs_free_all(); } |