Loading changes/bug28269 0 → 100644 +7 −0 Original line number Diff line number Diff line o Minor bugfixes (onion services): - If we are launching repeated HSFETCH queries and are rate-limited, we introduce a new controller response QUERY_RATE_LIMITED instead of QUERY_NO_HSDIR, while keeping the latter for when onion service directories are missing a descriptor. Previously, we returned QUERY_NO_HSDIR for both cases. Fixes bug 28269; bugfix on 0.3.1.1-alpha. Patch by Neel Chauhan src/feature/hs/hs_client.c +1 −1 Original line number Diff line number Diff line Loading @@ -434,7 +434,7 @@ pick_hsdir_v3(const ed25519_public_key_t *onion_identity_pk) /* Pick an HSDir from the responsible ones. The ownership of * responsible_hsdirs is given to this function so no need to free it. */ hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey); hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey, NULL); return hsdir_rs; } Loading src/feature/hs/hs_common.c +16 −4 Original line number Diff line number Diff line Loading @@ -1589,20 +1589,25 @@ hs_purge_last_hid_serv_requests(void) /** Given the list of responsible HSDirs in <b>responsible_dirs</b>, pick the * one that we should use to fetch a descriptor right now. Take into account * previous failed attempts at fetching this descriptor from HSDirs using the * string identifier <b>req_key_str</b>. * string identifier <b>req_key_str</b>. We return whether we are rate limited * into *<b>is_rate_limited</b> if it is not NULL. * * Steals ownership of <b>responsible_dirs</b>. * * Return the routerstatus of the chosen HSDir if successful, otherwise return * NULL if no HSDirs are worth trying right now. */ routerstatus_t * hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str, int *is_rate_limited) { smartlist_t *usable_responsible_dirs = smartlist_new(); const or_options_t *options = get_options(); routerstatus_t *hs_dir; time_t now = time(NULL); int excluded_some; int rate_limited; int rate_limited_count = 0; int responsible_dirs_count = smartlist_len(responsible_dirs); tor_assert(req_key_str); Loading @@ -1622,6 +1627,7 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) if (last + hs_hsdir_requery_period(options) >= now || !node || !node_has_preferred_descriptor(node, 0)) { SMARTLIST_DEL_CURRENT(responsible_dirs, dir); rate_limited_count++; continue; } if (!routerset_contains_node(options->ExcludeNodes, node)) { Loading @@ -1629,6 +1635,7 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) } } SMARTLIST_FOREACH_END(dir); rate_limited = rate_limited_count == responsible_dirs_count; excluded_some = smartlist_len(usable_responsible_dirs) < smartlist_len(responsible_dirs); Loading @@ -1640,9 +1647,10 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) smartlist_free(responsible_dirs); smartlist_free(usable_responsible_dirs); if (!hs_dir) { const char *warn_str = (rate_limited) ? "we are rate limited." : "we requested them all recently without success"; log_info(LD_REND, "Could not pick one of the responsible hidden " "service directories, because we requested them all " "recently without success."); "service directories, because %s.", warn_str); if (options->StrictNodes && excluded_some) { log_warn(LD_REND, "Could not pick a hidden service directory for the " "requested hidden service: they are all either down or " Loading @@ -1654,6 +1662,10 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) hs_lookup_last_hid_serv_request(hs_dir, req_key_str, now, 1); } if (is_rate_limited != NULL) { *is_rate_limited = rate_limited; } return hs_dir; } Loading src/feature/hs/hs_common.h +1 −1 Original line number Diff line number Diff line Loading @@ -241,7 +241,7 @@ void hs_get_responsible_hsdirs(const struct ed25519_public_key_t *blinded_pk, int use_second_hsdir_index, int for_fetching, smartlist_t *responsible_dirs); routerstatus_t *hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str); const char *req_key_str, int *is_rate_limited); time_t hs_hsdir_requery_period(const or_options_t *options); time_t hs_lookup_last_hid_serv_request(routerstatus_t *hs_dir, Loading src/feature/rend/rendclient.c +6 −3 Original line number Diff line number Diff line Loading @@ -469,16 +469,19 @@ directory_get_from_hs_dir(const char *desc_id, /* Automatically pick an hs dir if none given. */ if (!rs_hsdir) { int rate_limited; /* Determine responsible dirs. Even if we can't get all we want, work with * the ones we have. If it's empty, we'll notice in hs_pick_hsdir(). */ smartlist_t *responsible_dirs = smartlist_new(); hid_serv_get_responsible_directories(responsible_dirs, desc_id); hs_dir = hs_pick_hsdir(responsible_dirs, desc_id_base32); hs_dir = hs_pick_hsdir(responsible_dirs, desc_id_base32, &rate_limited); if (!hs_dir) { /* No suitable hs dir can be found, stop right now. */ control_event_hsv2_descriptor_failed(rend_query, NULL, "QUERY_NO_HSDIR"); const char *query_response = (rate_limited) ? "QUERY_RATE_LIMITED" : "QUERY_NO_HSDIR"; control_event_hsv2_descriptor_failed(rend_query, NULL, query_response); control_event_hs_descriptor_content(rend_data_get_address(rend_query), desc_id_base32, NULL, NULL); return 0; Loading Loading
changes/bug28269 0 → 100644 +7 −0 Original line number Diff line number Diff line o Minor bugfixes (onion services): - If we are launching repeated HSFETCH queries and are rate-limited, we introduce a new controller response QUERY_RATE_LIMITED instead of QUERY_NO_HSDIR, while keeping the latter for when onion service directories are missing a descriptor. Previously, we returned QUERY_NO_HSDIR for both cases. Fixes bug 28269; bugfix on 0.3.1.1-alpha. Patch by Neel Chauhan
src/feature/hs/hs_client.c +1 −1 Original line number Diff line number Diff line Loading @@ -434,7 +434,7 @@ pick_hsdir_v3(const ed25519_public_key_t *onion_identity_pk) /* Pick an HSDir from the responsible ones. The ownership of * responsible_hsdirs is given to this function so no need to free it. */ hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey); hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey, NULL); return hsdir_rs; } Loading
src/feature/hs/hs_common.c +16 −4 Original line number Diff line number Diff line Loading @@ -1589,20 +1589,25 @@ hs_purge_last_hid_serv_requests(void) /** Given the list of responsible HSDirs in <b>responsible_dirs</b>, pick the * one that we should use to fetch a descriptor right now. Take into account * previous failed attempts at fetching this descriptor from HSDirs using the * string identifier <b>req_key_str</b>. * string identifier <b>req_key_str</b>. We return whether we are rate limited * into *<b>is_rate_limited</b> if it is not NULL. * * Steals ownership of <b>responsible_dirs</b>. * * Return the routerstatus of the chosen HSDir if successful, otherwise return * NULL if no HSDirs are worth trying right now. */ routerstatus_t * hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str, int *is_rate_limited) { smartlist_t *usable_responsible_dirs = smartlist_new(); const or_options_t *options = get_options(); routerstatus_t *hs_dir; time_t now = time(NULL); int excluded_some; int rate_limited; int rate_limited_count = 0; int responsible_dirs_count = smartlist_len(responsible_dirs); tor_assert(req_key_str); Loading @@ -1622,6 +1627,7 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) if (last + hs_hsdir_requery_period(options) >= now || !node || !node_has_preferred_descriptor(node, 0)) { SMARTLIST_DEL_CURRENT(responsible_dirs, dir); rate_limited_count++; continue; } if (!routerset_contains_node(options->ExcludeNodes, node)) { Loading @@ -1629,6 +1635,7 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) } } SMARTLIST_FOREACH_END(dir); rate_limited = rate_limited_count == responsible_dirs_count; excluded_some = smartlist_len(usable_responsible_dirs) < smartlist_len(responsible_dirs); Loading @@ -1640,9 +1647,10 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) smartlist_free(responsible_dirs); smartlist_free(usable_responsible_dirs); if (!hs_dir) { const char *warn_str = (rate_limited) ? "we are rate limited." : "we requested them all recently without success"; log_info(LD_REND, "Could not pick one of the responsible hidden " "service directories, because we requested them all " "recently without success."); "service directories, because %s.", warn_str); if (options->StrictNodes && excluded_some) { log_warn(LD_REND, "Could not pick a hidden service directory for the " "requested hidden service: they are all either down or " Loading @@ -1654,6 +1662,10 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) hs_lookup_last_hid_serv_request(hs_dir, req_key_str, now, 1); } if (is_rate_limited != NULL) { *is_rate_limited = rate_limited; } return hs_dir; } Loading
src/feature/hs/hs_common.h +1 −1 Original line number Diff line number Diff line Loading @@ -241,7 +241,7 @@ void hs_get_responsible_hsdirs(const struct ed25519_public_key_t *blinded_pk, int use_second_hsdir_index, int for_fetching, smartlist_t *responsible_dirs); routerstatus_t *hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str); const char *req_key_str, int *is_rate_limited); time_t hs_hsdir_requery_period(const or_options_t *options); time_t hs_lookup_last_hid_serv_request(routerstatus_t *hs_dir, Loading
src/feature/rend/rendclient.c +6 −3 Original line number Diff line number Diff line Loading @@ -469,16 +469,19 @@ directory_get_from_hs_dir(const char *desc_id, /* Automatically pick an hs dir if none given. */ if (!rs_hsdir) { int rate_limited; /* Determine responsible dirs. Even if we can't get all we want, work with * the ones we have. If it's empty, we'll notice in hs_pick_hsdir(). */ smartlist_t *responsible_dirs = smartlist_new(); hid_serv_get_responsible_directories(responsible_dirs, desc_id); hs_dir = hs_pick_hsdir(responsible_dirs, desc_id_base32); hs_dir = hs_pick_hsdir(responsible_dirs, desc_id_base32, &rate_limited); if (!hs_dir) { /* No suitable hs dir can be found, stop right now. */ control_event_hsv2_descriptor_failed(rend_query, NULL, "QUERY_NO_HSDIR"); const char *query_response = (rate_limited) ? "QUERY_RATE_LIMITED" : "QUERY_NO_HSDIR"; control_event_hsv2_descriptor_failed(rend_query, NULL, query_response); control_event_hs_descriptor_content(rend_data_get_address(rend_query), desc_id_base32, NULL, NULL); return 0; Loading