Loading src/core/or/circuitbuild.c +16 −8 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include "core/or/command.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" #include "core/or/conflux_pool.h" #include "core/or/extendinfo.h" #include "core/or/onion.h" #include "core/or/ocirc_event.h" Loading Loading @@ -89,7 +90,8 @@ static int circuit_send_first_onion_skin(origin_circuit_t *circ); static int circuit_build_no_more_hops(origin_circuit_t *circ); static int circuit_send_intermediate_onion_skin(origin_circuit_t *circ, crypt_path_t *hop); static const node_t *choose_good_middle_server(uint8_t purpose, static const node_t *choose_good_middle_server(const origin_circuit_t *, uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len); Loading Loading @@ -2313,7 +2315,8 @@ build_vanguard_middle_exclude_list(uint8_t purpose, * hop, based on already chosen nodes. */ static smartlist_t * build_middle_exclude_list(uint8_t purpose, build_middle_exclude_list(const origin_circuit_t *circ, uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len) Loading @@ -2330,6 +2333,9 @@ build_middle_exclude_list(uint8_t purpose, excluded = smartlist_new(); // Exclude other middles on pending and built conflux circs conflux_add_middles_to_exclude_list(circ, excluded); /* For non-vanguard circuits, add the exit and its family to the exclude list * (note that the exit/last hop is always chosen first in * circuit_establish_circuit()). */ Loading Loading @@ -2423,7 +2429,8 @@ pick_vanguard_middle_node(const or_options_t *options, * family, and make sure we don't duplicate any previous nodes or their * families. */ static const node_t * choose_good_middle_server(uint8_t purpose, choose_good_middle_server(const origin_circuit_t * circ, uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len) Loading @@ -2438,7 +2445,7 @@ choose_good_middle_server(uint8_t purpose, log_debug(LD_CIRC, "Contemplating intermediate hop #%d: random choice.", cur_len+1); excluded = build_middle_exclude_list(purpose, state, head, cur_len); excluded = build_middle_exclude_list(circ, purpose, state, head, cur_len); flags |= cpath_build_state_to_crn_flags(state); flags |= cpath_build_state_to_crn_ipv6_extend_flag(state, cur_len); Loading Loading @@ -2483,7 +2490,8 @@ choose_good_middle_server(uint8_t purpose, * guard worked or not. */ const node_t * choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state, choose_good_entry_server(const origin_circuit_t *circ, uint8_t purpose, cpath_build_state_t *state, circuit_guard_state_t **guard_state_out) { const node_t *choice; Loading @@ -2505,7 +2513,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state, /* This request is for an entry server to use for a regular circuit, * and we use entry guard nodes. Just return one of the guard nodes. */ tor_assert(guard_state_out); return guards_choose_guard(state, purpose, guard_state_out); return guards_choose_guard(circ, state, purpose, guard_state_out); } excluded = smartlist_new(); Loading Loading @@ -2551,7 +2559,7 @@ onion_extend_cpath(origin_circuit_t *circ) if (cur_len == state->desired_path_len - 1) { /* Picking last node */ info = extend_info_dup(state->chosen_exit); } else if (cur_len == 0) { /* picking first node */ const node_t *r = choose_good_entry_server(purpose, state, const node_t *r = choose_good_entry_server(circ, purpose, state, &circ->guard_state); if (r) { /* If we're a client, use the preferred address rather than the Loading @@ -2564,7 +2572,7 @@ onion_extend_cpath(origin_circuit_t *circ) } } else { const node_t *r = choose_good_middle_server(purpose, state, circ->cpath, cur_len); choose_good_middle_server(circ, purpose, state, circ->cpath, cur_len); if (r) { info = extend_info_from_node(r, 0, false); } Loading src/core/or/circuitbuild.h +2 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,8 @@ const char *build_state_get_exit_nickname(cpath_build_state_t *state); struct circuit_guard_state_t; const node_t *choose_good_entry_server(uint8_t purpose, const node_t *choose_good_entry_server(const origin_circuit_t *circ, uint8_t purpose, cpath_build_state_t *state, struct circuit_guard_state_t **guard_state_out); void circuit_upgrade_circuits_from_guard_wait(void); Loading src/core/or/conflux_pool.c +123 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ #include "core/or/crypt_path_st.h" #include "core/or/or_circuit_st.h" #include "core/or/origin_circuit_st.h" #include "core/or/extend_info_st.h" #include "core/or/conflux_st.h" #include "feature/nodelist/nodelist.h" Loading Loading @@ -1092,6 +1094,127 @@ conflux_launch_leg(const uint8_t *nonce) return false; } /** * Add the identity digest of the guard nodes of all legs of the conflux * circuit. * * This function checks both pending and linked conflux circuits. */ void conflux_add_guards_to_exclude_list(const origin_circuit_t *orig_circ, smartlist_t *excluded) { tor_assert(orig_circ); tor_assert(excluded); /* Ease our lives. */ const circuit_t *circ = TO_CIRCUIT(orig_circ); /* Ignore if this is not conflux related. */ if (!CIRCUIT_IS_CONFLUX(circ)) { return; } /* When building a circuit, we should not have a conflux object * ourselves (though one may exist elsewhere). */ tor_assert(!circ->conflux); /* Getting here without a nonce is a code flow issue. */ if (BUG(!circ->conflux_pending_nonce)) { return; } /* A linked set exists, use it. */ const conflux_t *cfx = linked_pool_get(circ->conflux_pending_nonce, true); if (cfx) { CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) { const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); smartlist_add(excluded, tor_memdup(ocirc->cpath->extend_info->identity_digest, DIGEST_LEN)); } CONFLUX_FOR_EACH_LEG_END(leg); } /* An unlinked set might exist for this nonce, if so, add the second hop of * the existing legs to the exclusion list. */ unlinked_circuits_t *unlinked = unlinked_pool_get(circ->conflux_pending_nonce, true); if (unlinked) { tor_assert(unlinked->is_client); SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { /* Convert to origin circ and get cpath */ const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); smartlist_add(excluded, tor_memdup(ocirc->cpath->extend_info->identity_digest, DIGEST_LEN)); } SMARTLIST_FOREACH_END(leg); } } /** * Add the identity digest of the middle nodes of all legs of the conflux * circuit. * * This function checks both pending and linked conflux circuits. * * XXX: The add guard and middle could be merged since it is the exact same * code except for the cpath position and the identity digest vs node_t in * the list. We could use an extra param indicating guard or middle. */ void conflux_add_middles_to_exclude_list(const origin_circuit_t *orig_circ, smartlist_t *excluded) { tor_assert(orig_circ); tor_assert(excluded); /* Ease our lives. */ const circuit_t *circ = TO_CIRCUIT(orig_circ); /* Ignore if this is not conflux related. */ if (!CIRCUIT_IS_CONFLUX(circ)) { return; } /* When building a circuit, we should not have a conflux object * ourselves (though one may exist elsewhere). */ tor_assert(!circ->conflux); /* Getting here without a nonce is a code flow issue. */ if (BUG(!circ->conflux_pending_nonce)) { return; } /* A linked set exists, use it. */ const conflux_t *cfx = linked_pool_get(circ->conflux_pending_nonce, true); if (cfx) { CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) { const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); node_t *node = node_get_mutable_by_id( ocirc->cpath->next->extend_info->identity_digest); if (node) { smartlist_add(excluded, node); } } CONFLUX_FOR_EACH_LEG_END(leg); } /* An unlinked set might exist for this nonce, if so, add the second hop of * the existing legs to the exclusion list. */ unlinked_circuits_t *unlinked = unlinked_pool_get(circ->conflux_pending_nonce, true); if (unlinked) { tor_assert(unlinked->is_client); SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { /* Convert to origin circ and get cpath */ const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); node_t *node = node_get_mutable_by_id( ocirc->cpath->next->extend_info->identity_digest); if (node) { smartlist_add(excluded, node); } } SMARTLIST_FOREACH_END(leg); } } /** The given circuit is conflux pending and has closed. This deletes the leg * from the set, attempt to finalize it and relaunch a new leg. If the set is * empty after removing this leg, it is deleted. */ Loading src/core/or/conflux_pool.h +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,11 @@ void conflux_predict_new(time_t now); bool conflux_launch_leg(const uint8_t *nonce); void conflux_add_guards_to_exclude_list(const origin_circuit_t *circ, smartlist_t *excluded); void conflux_add_middles_to_exclude_list(const origin_circuit_t *circ, smartlist_t *excluded); void conflux_circuit_has_closed(circuit_t *circ); void conflux_circuit_has_opened(origin_circuit_t *orig_circ); void conflux_circuit_about_to_free(circuit_t *circ); Loading src/feature/client/entrynodes.c +35 −7 Original line number Diff line number Diff line Loading @@ -126,6 +126,7 @@ #include "core/or/circuitlist.h" #include "core/or/circuitstats.h" #include "core/or/circuituse.h" #include "core/or/conflux_pool.h" #include "core/or/policies.h" #include "feature/client/bridges.h" #include "feature/client/circpathbias.h" Loading @@ -151,6 +152,8 @@ #include "core/or/origin_circuit_st.h" #include "app/config/or_state_st.h" #include "core/or/conflux_util.h" /** A list of existing guard selection contexts. */ static smartlist_t *guard_contexts = NULL; /** The currently enabled guard selection context. */ Loading Loading @@ -1588,6 +1591,19 @@ guard_create_exit_restriction(const uint8_t *exit_id) return rst; } /* Allocate and return a new exit guard restriction that excludes all current * and pending conflux guards */ STATIC entry_guard_restriction_t * guard_create_conflux_restriction(const origin_circuit_t *circ) { entry_guard_restriction_t *rst = NULL; rst = tor_malloc_zero(sizeof(entry_guard_restriction_t)); rst->type = RST_EXCL_LIST; rst->excluded = smartlist_new(); conflux_add_guards_to_exclude_list(circ, rst->excluded); return rst; } /** If we have fewer than this many possible usable guards, don't set * MD-availability-based restrictions: we might denylist all of them. */ #define MIN_GUARDS_FOR_MD_RESTRICTION 10 Loading Loading @@ -1680,6 +1696,8 @@ entry_guard_obeys_restriction(const entry_guard_t *guard, return guard_obeys_exit_restriction(guard, rst); } else if (rst->type == RST_OUTDATED_MD_DIRSERVER) { return guard_obeys_md_dirserver_restriction(guard); } else if (rst->type == RST_EXCL_LIST) { return !smartlist_contains_digest(rst->excluded, guard->identity); } tor_assert_nonfatal_unreached(); Loading Loading @@ -2427,6 +2445,11 @@ entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b) STATIC void entry_guard_restriction_free_(entry_guard_restriction_t *rst) { if (rst && rst->excluded) { SMARTLIST_FOREACH(rst->excluded, void *, g, tor_free(g)); smartlist_free(rst->excluded); } tor_free(rst); } Loading Loading @@ -3780,7 +3803,8 @@ guards_update_all(void) /** Helper: pick a guard for a circuit, with whatever algorithm is used. */ const node_t * guards_choose_guard(cpath_build_state_t *state, guards_choose_guard(const origin_circuit_t *circ, cpath_build_state_t *state, uint8_t purpose, circuit_guard_state_t **guard_state_out) { Loading @@ -3788,14 +3812,18 @@ guards_choose_guard(cpath_build_state_t *state, const uint8_t *exit_id = NULL; entry_guard_restriction_t *rst = NULL; /* Only apply restrictions if we have a specific exit node in mind, and only * if we are not doing vanguard circuits: we don't want to apply guard * restrictions to vanguard circuits. */ if (state && !circuit_should_use_vanguards(purpose) && /* If we this is a conflux circuit, build an exclusion list for it. */ if (CIRCUIT_IS_CONFLUX(TO_CIRCUIT(circ))) { rst = guard_create_conflux_restriction(circ); /* Don't allow connecting back to the exit if there is one */ if (state && (exit_id = build_state_get_exit_rsa_id(state))) { /* add the exit_id to the excluded list */ smartlist_add(rst->excluded, tor_memdup(exit_id, DIGEST_LEN)); } } else if (state && !circuit_should_use_vanguards(purpose) && (exit_id = build_state_get_exit_rsa_id(state))) { /* We're building to a targeted exit node, so that node can't be * chosen as our guard for this circuit. Remember that fact in a * restriction. */ * chosen as our guard for this circuit, unless we're vanguards. */ rst = guard_create_exit_restriction(exit_id); tor_assert(rst); } Loading Loading
src/core/or/circuitbuild.c +16 −8 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include "core/or/command.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" #include "core/or/conflux_pool.h" #include "core/or/extendinfo.h" #include "core/or/onion.h" #include "core/or/ocirc_event.h" Loading Loading @@ -89,7 +90,8 @@ static int circuit_send_first_onion_skin(origin_circuit_t *circ); static int circuit_build_no_more_hops(origin_circuit_t *circ); static int circuit_send_intermediate_onion_skin(origin_circuit_t *circ, crypt_path_t *hop); static const node_t *choose_good_middle_server(uint8_t purpose, static const node_t *choose_good_middle_server(const origin_circuit_t *, uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len); Loading Loading @@ -2313,7 +2315,8 @@ build_vanguard_middle_exclude_list(uint8_t purpose, * hop, based on already chosen nodes. */ static smartlist_t * build_middle_exclude_list(uint8_t purpose, build_middle_exclude_list(const origin_circuit_t *circ, uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len) Loading @@ -2330,6 +2333,9 @@ build_middle_exclude_list(uint8_t purpose, excluded = smartlist_new(); // Exclude other middles on pending and built conflux circs conflux_add_middles_to_exclude_list(circ, excluded); /* For non-vanguard circuits, add the exit and its family to the exclude list * (note that the exit/last hop is always chosen first in * circuit_establish_circuit()). */ Loading Loading @@ -2423,7 +2429,8 @@ pick_vanguard_middle_node(const or_options_t *options, * family, and make sure we don't duplicate any previous nodes or their * families. */ static const node_t * choose_good_middle_server(uint8_t purpose, choose_good_middle_server(const origin_circuit_t * circ, uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len) Loading @@ -2438,7 +2445,7 @@ choose_good_middle_server(uint8_t purpose, log_debug(LD_CIRC, "Contemplating intermediate hop #%d: random choice.", cur_len+1); excluded = build_middle_exclude_list(purpose, state, head, cur_len); excluded = build_middle_exclude_list(circ, purpose, state, head, cur_len); flags |= cpath_build_state_to_crn_flags(state); flags |= cpath_build_state_to_crn_ipv6_extend_flag(state, cur_len); Loading Loading @@ -2483,7 +2490,8 @@ choose_good_middle_server(uint8_t purpose, * guard worked or not. */ const node_t * choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state, choose_good_entry_server(const origin_circuit_t *circ, uint8_t purpose, cpath_build_state_t *state, circuit_guard_state_t **guard_state_out) { const node_t *choice; Loading @@ -2505,7 +2513,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state, /* This request is for an entry server to use for a regular circuit, * and we use entry guard nodes. Just return one of the guard nodes. */ tor_assert(guard_state_out); return guards_choose_guard(state, purpose, guard_state_out); return guards_choose_guard(circ, state, purpose, guard_state_out); } excluded = smartlist_new(); Loading Loading @@ -2551,7 +2559,7 @@ onion_extend_cpath(origin_circuit_t *circ) if (cur_len == state->desired_path_len - 1) { /* Picking last node */ info = extend_info_dup(state->chosen_exit); } else if (cur_len == 0) { /* picking first node */ const node_t *r = choose_good_entry_server(purpose, state, const node_t *r = choose_good_entry_server(circ, purpose, state, &circ->guard_state); if (r) { /* If we're a client, use the preferred address rather than the Loading @@ -2564,7 +2572,7 @@ onion_extend_cpath(origin_circuit_t *circ) } } else { const node_t *r = choose_good_middle_server(purpose, state, circ->cpath, cur_len); choose_good_middle_server(circ, purpose, state, circ->cpath, cur_len); if (r) { info = extend_info_from_node(r, 0, false); } Loading
src/core/or/circuitbuild.h +2 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,8 @@ const char *build_state_get_exit_nickname(cpath_build_state_t *state); struct circuit_guard_state_t; const node_t *choose_good_entry_server(uint8_t purpose, const node_t *choose_good_entry_server(const origin_circuit_t *circ, uint8_t purpose, cpath_build_state_t *state, struct circuit_guard_state_t **guard_state_out); void circuit_upgrade_circuits_from_guard_wait(void); Loading
src/core/or/conflux_pool.c +123 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ #include "core/or/crypt_path_st.h" #include "core/or/or_circuit_st.h" #include "core/or/origin_circuit_st.h" #include "core/or/extend_info_st.h" #include "core/or/conflux_st.h" #include "feature/nodelist/nodelist.h" Loading Loading @@ -1092,6 +1094,127 @@ conflux_launch_leg(const uint8_t *nonce) return false; } /** * Add the identity digest of the guard nodes of all legs of the conflux * circuit. * * This function checks both pending and linked conflux circuits. */ void conflux_add_guards_to_exclude_list(const origin_circuit_t *orig_circ, smartlist_t *excluded) { tor_assert(orig_circ); tor_assert(excluded); /* Ease our lives. */ const circuit_t *circ = TO_CIRCUIT(orig_circ); /* Ignore if this is not conflux related. */ if (!CIRCUIT_IS_CONFLUX(circ)) { return; } /* When building a circuit, we should not have a conflux object * ourselves (though one may exist elsewhere). */ tor_assert(!circ->conflux); /* Getting here without a nonce is a code flow issue. */ if (BUG(!circ->conflux_pending_nonce)) { return; } /* A linked set exists, use it. */ const conflux_t *cfx = linked_pool_get(circ->conflux_pending_nonce, true); if (cfx) { CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) { const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); smartlist_add(excluded, tor_memdup(ocirc->cpath->extend_info->identity_digest, DIGEST_LEN)); } CONFLUX_FOR_EACH_LEG_END(leg); } /* An unlinked set might exist for this nonce, if so, add the second hop of * the existing legs to the exclusion list. */ unlinked_circuits_t *unlinked = unlinked_pool_get(circ->conflux_pending_nonce, true); if (unlinked) { tor_assert(unlinked->is_client); SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { /* Convert to origin circ and get cpath */ const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); smartlist_add(excluded, tor_memdup(ocirc->cpath->extend_info->identity_digest, DIGEST_LEN)); } SMARTLIST_FOREACH_END(leg); } } /** * Add the identity digest of the middle nodes of all legs of the conflux * circuit. * * This function checks both pending and linked conflux circuits. * * XXX: The add guard and middle could be merged since it is the exact same * code except for the cpath position and the identity digest vs node_t in * the list. We could use an extra param indicating guard or middle. */ void conflux_add_middles_to_exclude_list(const origin_circuit_t *orig_circ, smartlist_t *excluded) { tor_assert(orig_circ); tor_assert(excluded); /* Ease our lives. */ const circuit_t *circ = TO_CIRCUIT(orig_circ); /* Ignore if this is not conflux related. */ if (!CIRCUIT_IS_CONFLUX(circ)) { return; } /* When building a circuit, we should not have a conflux object * ourselves (though one may exist elsewhere). */ tor_assert(!circ->conflux); /* Getting here without a nonce is a code flow issue. */ if (BUG(!circ->conflux_pending_nonce)) { return; } /* A linked set exists, use it. */ const conflux_t *cfx = linked_pool_get(circ->conflux_pending_nonce, true); if (cfx) { CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) { const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); node_t *node = node_get_mutable_by_id( ocirc->cpath->next->extend_info->identity_digest); if (node) { smartlist_add(excluded, node); } } CONFLUX_FOR_EACH_LEG_END(leg); } /* An unlinked set might exist for this nonce, if so, add the second hop of * the existing legs to the exclusion list. */ unlinked_circuits_t *unlinked = unlinked_pool_get(circ->conflux_pending_nonce, true); if (unlinked) { tor_assert(unlinked->is_client); SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { /* Convert to origin circ and get cpath */ const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); node_t *node = node_get_mutable_by_id( ocirc->cpath->next->extend_info->identity_digest); if (node) { smartlist_add(excluded, node); } } SMARTLIST_FOREACH_END(leg); } } /** The given circuit is conflux pending and has closed. This deletes the leg * from the set, attempt to finalize it and relaunch a new leg. If the set is * empty after removing this leg, it is deleted. */ Loading
src/core/or/conflux_pool.h +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,11 @@ void conflux_predict_new(time_t now); bool conflux_launch_leg(const uint8_t *nonce); void conflux_add_guards_to_exclude_list(const origin_circuit_t *circ, smartlist_t *excluded); void conflux_add_middles_to_exclude_list(const origin_circuit_t *circ, smartlist_t *excluded); void conflux_circuit_has_closed(circuit_t *circ); void conflux_circuit_has_opened(origin_circuit_t *orig_circ); void conflux_circuit_about_to_free(circuit_t *circ); Loading
src/feature/client/entrynodes.c +35 −7 Original line number Diff line number Diff line Loading @@ -126,6 +126,7 @@ #include "core/or/circuitlist.h" #include "core/or/circuitstats.h" #include "core/or/circuituse.h" #include "core/or/conflux_pool.h" #include "core/or/policies.h" #include "feature/client/bridges.h" #include "feature/client/circpathbias.h" Loading @@ -151,6 +152,8 @@ #include "core/or/origin_circuit_st.h" #include "app/config/or_state_st.h" #include "core/or/conflux_util.h" /** A list of existing guard selection contexts. */ static smartlist_t *guard_contexts = NULL; /** The currently enabled guard selection context. */ Loading Loading @@ -1588,6 +1591,19 @@ guard_create_exit_restriction(const uint8_t *exit_id) return rst; } /* Allocate and return a new exit guard restriction that excludes all current * and pending conflux guards */ STATIC entry_guard_restriction_t * guard_create_conflux_restriction(const origin_circuit_t *circ) { entry_guard_restriction_t *rst = NULL; rst = tor_malloc_zero(sizeof(entry_guard_restriction_t)); rst->type = RST_EXCL_LIST; rst->excluded = smartlist_new(); conflux_add_guards_to_exclude_list(circ, rst->excluded); return rst; } /** If we have fewer than this many possible usable guards, don't set * MD-availability-based restrictions: we might denylist all of them. */ #define MIN_GUARDS_FOR_MD_RESTRICTION 10 Loading Loading @@ -1680,6 +1696,8 @@ entry_guard_obeys_restriction(const entry_guard_t *guard, return guard_obeys_exit_restriction(guard, rst); } else if (rst->type == RST_OUTDATED_MD_DIRSERVER) { return guard_obeys_md_dirserver_restriction(guard); } else if (rst->type == RST_EXCL_LIST) { return !smartlist_contains_digest(rst->excluded, guard->identity); } tor_assert_nonfatal_unreached(); Loading Loading @@ -2427,6 +2445,11 @@ entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b) STATIC void entry_guard_restriction_free_(entry_guard_restriction_t *rst) { if (rst && rst->excluded) { SMARTLIST_FOREACH(rst->excluded, void *, g, tor_free(g)); smartlist_free(rst->excluded); } tor_free(rst); } Loading Loading @@ -3780,7 +3803,8 @@ guards_update_all(void) /** Helper: pick a guard for a circuit, with whatever algorithm is used. */ const node_t * guards_choose_guard(cpath_build_state_t *state, guards_choose_guard(const origin_circuit_t *circ, cpath_build_state_t *state, uint8_t purpose, circuit_guard_state_t **guard_state_out) { Loading @@ -3788,14 +3812,18 @@ guards_choose_guard(cpath_build_state_t *state, const uint8_t *exit_id = NULL; entry_guard_restriction_t *rst = NULL; /* Only apply restrictions if we have a specific exit node in mind, and only * if we are not doing vanguard circuits: we don't want to apply guard * restrictions to vanguard circuits. */ if (state && !circuit_should_use_vanguards(purpose) && /* If we this is a conflux circuit, build an exclusion list for it. */ if (CIRCUIT_IS_CONFLUX(TO_CIRCUIT(circ))) { rst = guard_create_conflux_restriction(circ); /* Don't allow connecting back to the exit if there is one */ if (state && (exit_id = build_state_get_exit_rsa_id(state))) { /* add the exit_id to the excluded list */ smartlist_add(rst->excluded, tor_memdup(exit_id, DIGEST_LEN)); } } else if (state && !circuit_should_use_vanguards(purpose) && (exit_id = build_state_get_exit_rsa_id(state))) { /* We're building to a targeted exit node, so that node can't be * chosen as our guard for this circuit. Remember that fact in a * restriction. */ * chosen as our guard for this circuit, unless we're vanguards. */ rst = guard_create_exit_restriction(exit_id); tor_assert(rst); } Loading