diff --git a/src/feature/hs/hs_circuitmap.c b/src/feature/hs/hs_circuitmap.c index 5480d5eb84..e34f564fb4 100644 --- a/src/feature/hs/hs_circuitmap.c +++ b/src/feature/hs/hs_circuitmap.c @@ -272,6 +272,33 @@ hs_circuitmap_get_or_circuit(hs_token_type_t type, /**** Public relay-side getters: */ +/* Public function: Return v2 and v3 introduction circuit to this relay. + * Always return a newly allocated list for which it is the caller's + * responsability to free it. */ +smartlist_t * +hs_circuitmap_get_all_intro_circ_relay_side(void) +{ + circuit_t **iter; + smartlist_t *circuit_list = smartlist_new(); + + HT_FOREACH(iter, hs_circuitmap_ht, the_hs_circuitmap) { + circuit_t *circ = *iter; + + /* An origin circuit or purpose is wrong or the hs token is not set to be + * a v2 or v3 intro relay side type, we ignore the circuit. Else, we have + * a match so add it to our list. */ + if (CIRCUIT_IS_ORIGIN(circ) || + circ->purpose != CIRCUIT_PURPOSE_INTRO_POINT || + (circ->hs_token->type != HS_TOKEN_INTRO_V3_RELAY_SIDE && + circ->hs_token->type != HS_TOKEN_INTRO_V2_RELAY_SIDE)) { + continue; + } + smartlist_add(circuit_list, circ); + } + + return circuit_list; +} + /* Public function: Return a v3 introduction circuit to this relay with * auth_key. Return NULL if no such circuit is found in the * circuitmap. */ diff --git a/src/feature/hs/hs_circuitmap.h b/src/feature/hs/hs_circuitmap.h index c1bbb1ff1c..eac8230bbf 100644 --- a/src/feature/hs/hs_circuitmap.h +++ b/src/feature/hs/hs_circuitmap.h @@ -34,6 +34,8 @@ void hs_circuitmap_register_intro_circ_v2_relay_side(struct or_circuit_t *circ, void hs_circuitmap_register_intro_circ_v3_relay_side(struct or_circuit_t *circ, const ed25519_public_key_t *auth_key); +smartlist_t *hs_circuitmap_get_all_intro_circ_relay_side(void); + /** Public service-side API: */ struct origin_circuit_t * diff --git a/src/feature/hs/hs_dos.c b/src/feature/hs/hs_dos.c index f817b49885..da898dc3a0 100644 --- a/src/feature/hs/hs_dos.c +++ b/src/feature/hs/hs_dos.c @@ -23,6 +23,7 @@ #include "core/or/circuitlist.h" +#include "feature/hs/hs_circuitmap.h" #include "feature/nodelist/networkstatus.h" #include "feature/relay/routermode.h" @@ -77,6 +78,25 @@ get_param_burst_per_sec(const networkstatus_t *ns) 0, INT32_MAX); } +/* Go over all introduction circuit relay side and adjust their rate/burst + * values using the global parameters. This is called right after the + * consensus parameters might have changed. */ +static void +update_intro_circuits(void) +{ + /* Returns all HS version intro circuits. */ + smartlist_t *intro_circs = hs_circuitmap_get_all_intro_circ_relay_side(); + + SMARTLIST_FOREACH_BEGIN(intro_circs, circuit_t *, circ) { + /* Adjust the rate/burst value that might have changed. */ + token_bucket_ctr_adjust(&TO_OR_CIRCUIT(circ)->introduce2_bucket, + hs_dos_get_intro2_rate(), + hs_dos_get_intro2_burst()); + } SMARTLIST_FOREACH_END(circ); + + smartlist_free(intro_circs); +} + /* Set consensus parameters. */ static void set_consensus_parameters(const networkstatus_t *ns) @@ -84,6 +104,10 @@ set_consensus_parameters(const networkstatus_t *ns) hs_dos_introduce_rate_per_sec = get_param_rate_per_sec(ns); hs_dos_introduce_burst_per_sec = get_param_burst_per_sec(ns); hs_dos_introduce_enabled = get_param_intro_dos_enabled(ns); + + /* The above might have changed which means we need to go through all + * introduction circuits (relay side) and update the token buckets. */ + update_intro_circuits(); } /*