tor/src/feature/hs/hs_dos.c

61 lines
2 KiB
C
Raw Normal View History

/* 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;
}