diff options
author | David Goulet <dgoulet@torproject.org> | 2019-05-29 14:05:16 -0400 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2019-08-06 07:58:14 -0400 |
commit | 9f738be8937d675929b43a149d706160641a089d (patch) | |
tree | 8a54a82b32bea028f6693f97e359899d3bd43aec /src/feature/hs/hs_dos.c | |
parent | 4ee65a6f877e841739f037ad27d2d588ce4e0c51 (diff) | |
download | tor-9f738be8937d675929b43a149d706160641a089d.tar.gz tor-9f738be8937d675929b43a149d706160641a089d.zip |
hs: Limit the amount of relayed INTRODUCE2
This commit add the hs_dos.{c|h} file that has the purpose of having the
anti-DoS code for onion services.
At this commit, it only has one which is a function that decides if an
INTRODUCE2 can be sent on the given introduction service circuit (S<->IP)
using a simple token bucket.
The rate per second is 25 and allowed burst to 200.
Basic defenses on #15516.
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/feature/hs/hs_dos.c')
-rw-r--r-- | src/feature/hs/hs_dos.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/feature/hs/hs_dos.c b/src/feature/hs/hs_dos.c new file mode 100644 index 0000000000..ad9d044f48 --- /dev/null +++ b/src/feature/hs/hs_dos.c @@ -0,0 +1,60 @@ +/* Copyright (c) 2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file hs_dos.c + * \brief Implement denial of service mitigation for the onion service + * subsystem. + * + * This module defenses: + * + * - Introduction Rate Limiting: If enabled by the consensus, an introduction + * point will rate limit client introduction towards the service (INTRODUCE2 + * cells). It uses a token bucket model with a rate and burst per second. + * + * Proposal 305 will expand this module by allowing an operator to define + * these values into the ESTABLISH_INTRO cell. Not yet implemented. + **/ + +#define HS_DOS_PRIVATE + +#include "core/or/circuitlist.h" + +#include "hs_dos.h" + +/* + * Public API. + */ + +/* Return true iff an INTRODUCE2 cell can be sent on the given service + * introduction circuit. */ +bool +hs_dos_can_send_intro2(or_circuit_t *s_intro_circ) +{ + tor_assert(s_intro_circ); + + /* Should not happen but if so, scream loudly. */ + if (BUG(TO_CIRCUIT(s_intro_circ)->purpose != CIRCUIT_PURPOSE_INTRO_POINT)) { + return false; + } + + /* This is called just after we got a valid and parsed INTRODUCE1 cell. The + * service has been found and we have its introduction circuit. + * + * First, the INTRODUCE2 bucket will be refilled (if any). Then, decremented + * because we are about to send or not the cell we just got. Finally, + * evaluate if we can send it based on our token bucket state. */ + + /* Refill INTRODUCE2 bucket. */ + token_bucket_ctr_refill(&s_intro_circ->introduce2_bucket, + (uint32_t) approx_time()); + + /* Decrement the bucket for this valid INTRODUCE1 cell we just got. Don't + * underflow else we end up with a too big of a bucket. */ + if (token_bucket_ctr_get(&s_intro_circ->introduce2_bucket) > 0) { + token_bucket_ctr_dec(&s_intro_circ->introduce2_bucket, 1); + } + + /* Finally, we can send a new INTRODUCE2 if there are still tokens. */ + return token_bucket_ctr_get(&s_intro_circ->introduce2_bucket) > 0; +} |