tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit 33c3059c8233fb9a3076c8452f7cea00412ccdfb
parent 61aa4c3657b43e11414f8c607aadfad87eea40fd
Author: Mike Perry <mikeperry-git@torproject.org>
Date:   Thu, 20 Apr 2023 20:55:17 +0000

Handle infinite loop with only one bridge (or snowflake).

Diffstat:
Msrc/core/or/conflux_pool.c | 9+++++++++
Msrc/feature/client/bridges.c | 35+++++++++++++++++++++++++++++++++++
Msrc/feature/client/bridges.h | 1+
3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/src/core/or/conflux_pool.c b/src/core/or/conflux_pool.c @@ -35,6 +35,7 @@ #include "core/or/conflux_st.h" #include "feature/nodelist/nodelist.h" +#include "feature/client/bridges.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" @@ -1150,6 +1151,14 @@ conflux_add_guards_to_exclude_list(const origin_circuit_t *orig_circ, return; } + /* If there is only one bridge, then only issue a warn once that + * at least two bridges are best for conflux. Exempt Snowflake + * from this warn */ + if (get_options()->UseBridges && !conflux_can_exclude_used_bridges()) { + /* Do not build any exclude lists; not enough bridges */ + return; + } + /* A linked set exists, use it. */ const conflux_t *cfx = linked_pool_get(circ->conflux_pending_nonce, true); if (cfx) { diff --git a/src/feature/client/bridges.c b/src/feature/client/bridges.c @@ -140,6 +140,41 @@ bridge_list_get(void) } /** + * Returns true if there are enough bridges to make a conflux set + * without re-using the same bridge. + */ +bool +conflux_can_exclude_used_bridges(void) +{ + if (smartlist_len(bridge_list_get()) == 1) { + static bool warned_once = false; + bridge_info_t *bridge = smartlist_get(bridge_list_get(), 0); + tor_assert(bridge); + + /* Snowflake is a special case. With one snowflake bridge, + * you are load balanced among many back-end bridges. + * So we do not need to warn the user for it. */ + if (bridge->transport_name && + strcasecmp(bridge->transport_name, "snowflake") == 0) { + return false; + } + + if (!warned_once) { + log_warn(LD_CIRC, "Only one bridge (transport: '%s') is configured. " + "You should have at least two for conflux, " + "for any transport that is not 'snowflake'.", + bridge->transport_name ? + bridge->transport_name : "vanilla"); + warned_once = true; + } + + return false; + } + + return true; +} + +/** * Given a <b>bridge</b>, return a pointer to its RSA identity digest, or * NULL if we don't know one for it. */ diff --git a/src/feature/client/bridges.h b/src/feature/client/bridges.h @@ -67,6 +67,7 @@ MOCK_DECL(download_status_t *, get_bridge_dl_status_by_id, (const char *digest)); void bridges_free_all(void); +bool conflux_can_exclude_used_bridges(void); #ifdef TOR_BRIDGES_PRIVATE STATIC void clear_bridge_list(void);