From 01a5b41be0aa0d8ab2574d7075af8db2878a1cf3 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Mon, 25 Jan 2021 02:16:44 -0500 Subject: [PATCH] New ReconfigDropsBridgeDescs config option Let external bridge reachability testing tools discard cached bridge descriptors when setting new bridges, so they can be sure to get a clean reachability test. Implements ticket 40209. --- changes/ticket40209 | 4 ++++ src/app/config/config.c | 3 +++ src/app/config/or_options_st.h | 7 +++++++ src/feature/nodelist/routerlist.c | 24 ++++++++++++++++++++++++ src/feature/nodelist/routerlist.h | 1 + 5 files changed, 39 insertions(+) create mode 100644 changes/ticket40209 diff --git a/changes/ticket40209 b/changes/ticket40209 new file mode 100644 index 0000000000..a90243be8c --- /dev/null +++ b/changes/ticket40209 @@ -0,0 +1,4 @@ + o Minor features (bridge testing support): + - Let external bridge reachability testing tools discard cached + bridge descriptors when setting new bridges, so they can be sure + to get a clean reachability test. Implements ticket 40209. diff --git a/src/app/config/config.c b/src/app/config/config.c index c7799ec1a2..79629a2465 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -628,6 +628,7 @@ static const config_var_t option_vars_[] = { V(ConnectionPadding, AUTOBOOL, "auto"), V(RefuseUnknownExits, AUTOBOOL, "auto"), V(CircuitPadding, BOOL, "1"), + V(ReconfigDropsBridgeDescs, BOOL, "0"), V(ReducedCircuitPadding, BOOL, "0"), V(RejectPlaintextPorts, CSV, ""), V(RelayBandwidthBurst, MEMUNIT, "0"), @@ -2321,6 +2322,8 @@ options_act,(const or_options_t *old_options)) } if (transition_affects_guards) { + if (options->ReconfigDropsBridgeDescs) + routerlist_drop_bridge_descriptors(); if (guards_update_all()) { abandon_circuits = 1; } diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h index 4364f145ed..d3488afa5c 100644 --- a/src/app/config/or_options_st.h +++ b/src/app/config/or_options_st.h @@ -293,6 +293,13 @@ struct or_options_t { * disabled. */ int CircuitPadding; + /** Boolean: if true, then this client will discard cached bridge + * descriptors on a setconf or other config change that impacts guards + * or bridges (see options_transition_affects_guards() for exactly which + * config changes trigger it). Useful for tools that test bridge + * reachability by fetching fresh descriptors. */ + int ReconfigDropsBridgeDescs; + /** Boolean: if true, then this client will only use circuit padding * algorithms that are known to use a low amount of overhead. If false, * we will use all available circuit padding algorithms. diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c index a1a348edb9..67f4a4546a 100644 --- a/src/feature/nodelist/routerlist.c +++ b/src/feature/nodelist/routerlist.c @@ -2012,6 +2012,30 @@ routerlist_remove_old_routers(void) router_rebuild_store(RRS_DONT_REMOVE_OLD,&routerlist->extrainfo_store); } +/* Drop every bridge descriptor in our routerlist. Used by the external + * 'bridgestrap' tool to discard bridge descriptors so that it can then + * do a clean reachability test. */ +void +routerlist_drop_bridge_descriptors(void) +{ + routerinfo_t *router; + int i; + + if (!routerlist) + return; + + for (i = 0; i < smartlist_len(routerlist->routers); ++i) { + router = smartlist_get(routerlist->routers, i); + if (router->purpose == ROUTER_PURPOSE_BRIDGE) { + log_notice(LD_DIR, + "Dropping existing bridge descriptor for %s", + router_describe(router)); + routerlist_remove(routerlist, router, 0, time(NULL)); + i--; + } + } +} + /** We just added a new set of descriptors. Take whatever extra steps * we need. */ void diff --git a/src/feature/nodelist/routerlist.h b/src/feature/nodelist/routerlist.h index 98472b2771..f72fdfc117 100644 --- a/src/feature/nodelist/routerlist.h +++ b/src/feature/nodelist/routerlist.h @@ -145,6 +145,7 @@ was_router_added_t router_add_extrainfo_to_routerlist( int from_cache, int from_fetch); void routerlist_descriptors_added(smartlist_t *sl, int from_cache); void routerlist_remove_old_routers(void); +void routerlist_drop_bridge_descriptors(void); int router_load_single_router(const char *s, uint8_t purpose, int cache, const char **msg); int router_load_routers_from_string(const char *s, const char *eos,