tor

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

dos.h (8312B)


      1 /* Copyright (c) 2018-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 /*
      5 * \file dos.h
      6 * \brief Header file for dos.c
      7 */
      8 
      9 #ifndef TOR_DOS_H
     10 #define TOR_DOS_H
     11 
     12 #include "core/or/or.h"
     13 
     14 #include "lib/evloop/token_bucket.h"
     15 
     16 /* Structure that keeps stats of circuit creation per client connection IP. */
     17 typedef struct cc_client_stats_t {
     18  /* Number of allocated circuits remaining for this address.  It is
     19   * decremented every time a new circuit is seen for this client address and
     20   * if the count goes to 0, we have a positive detection. */
     21  uint32_t circuit_bucket;
     22 
     23  /* When was the last time we've refilled the circuit bucket? This is used to
     24   * know if we need to refill the bucket when a new circuit is seen. It is
     25   * synchronized using approx_time(). */
     26  time_t last_circ_bucket_refill_ts;
     27 
     28  /* This client address was detected to be above the circuit creation rate
     29   * and this timestamp indicates until when it should remain marked as
     30   * detected so we can apply a defense for the address. It is synchronized
     31   * using the approx_time(). */
     32  time_t marked_until_ts;
     33 } cc_client_stats_t;
     34 
     35 /* Structure that keeps stats of client connection per-IP. */
     36 typedef struct conn_client_stats_t {
     37  /* Concurrent connection count from the specific address. 2^32 - 1 is most
     38   * likely way too big for the amount of allowed file descriptors. */
     39  uint32_t concurrent_count;
     40 
     41  /* Connect count from the specific address. We use a token bucket here to
     42   * track the rate and burst of connections from the same IP address.*/
     43  token_bucket_ctr_t connect_count;
     44 
     45  /* The client address attempted too many connections, per the connect_count
     46   * rules, and thus is marked so defense(s) can be applied. It is
     47   * synchronized using the approx_time(). */
     48  time_t marked_until_ts;
     49 } conn_client_stats_t;
     50 
     51 /* This object is a top level object that contains everything related to the
     52 * per-IP client DoS mitigation. Because it is per-IP, it is used in the geoip
     53 * clientmap_entry_t object. */
     54 typedef struct dos_client_stats_t {
     55  /* Client connection statistics. */
     56  conn_client_stats_t conn_stats;
     57 
     58  /* Circuit creation statistics. This is only used if the circuit creation
     59   * subsystem has been enabled (dos_cc_enabled). */
     60  cc_client_stats_t cc_stats;
     61 
     62  /** Number of times the circ_max_cell_queue_size limit has been reached. */
     63  uint32_t num_circ_max_cell_queue_size;
     64 } dos_client_stats_t;
     65 
     66 /* General API. */
     67 
     68 /* Stub. */
     69 struct clientmap_entry_t;
     70 
     71 void dos_init(void);
     72 void dos_free_all(void);
     73 void dos_consensus_has_changed(const networkstatus_t *ns);
     74 int dos_enabled(void);
     75 void dos_log_heartbeat(void);
     76 void dos_geoip_entry_init(struct clientmap_entry_t *geoip_ent);
     77 void dos_geoip_entry_about_to_free(const struct clientmap_entry_t *geoip_ent);
     78 
     79 void dos_new_client_conn(or_connection_t *or_conn,
     80                         const char *transport_name);
     81 void dos_close_client_conn(const or_connection_t *or_conn);
     82 
     83 int dos_should_refuse_single_hop_client(void);
     84 void dos_note_refuse_single_hop_client(void);
     85 void dos_note_circ_max_outq(const channel_t *chan);
     86 
     87 uint32_t dos_get_num_cc_marked_addr(void);
     88 uint32_t dos_get_num_cc_marked_addr_maxq(void);
     89 uint64_t dos_get_num_cc_rejected(void);
     90 uint64_t dos_get_num_conn_addr_rejected(void);
     91 uint64_t dos_get_num_conn_addr_connect_rejected(void);
     92 uint64_t dos_get_num_single_hop_refused(void);
     93 uint64_t dos_get_num_stream_rejected(void);
     94 
     95 /*
     96 * Circuit creation DoS mitigation subsystemn interface.
     97 */
     98 
     99 /* DoSCircuitCreationEnabled default. Disabled by default. */
    100 #define DOS_CC_ENABLED_DEFAULT 0
    101 /* DoSCircuitCreationDefenseType maps to the dos_cc_defense_type_t enum. */
    102 #define DOS_CC_DEFENSE_TYPE_DEFAULT DOS_CC_DEFENSE_REFUSE_CELL
    103 /* DoSCircuitCreationMinConnections default */
    104 #define DOS_CC_MIN_CONCURRENT_CONN_DEFAULT 3
    105 /* DoSCircuitCreationRateTenths is 3 per seconds. */
    106 #define DOS_CC_CIRCUIT_RATE_DEFAULT 3
    107 /* DoSCircuitCreationBurst default. */
    108 #define DOS_CC_CIRCUIT_BURST_DEFAULT 90
    109 /* DoSCircuitCreationDefenseTimePeriod in seconds. */
    110 #define DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT (60 * 60)
    111 
    112 /* Type of defense that we can use for the circuit creation DoS mitigation. */
    113 typedef enum dos_cc_defense_type_t {
    114  /* No defense used. */
    115  DOS_CC_DEFENSE_NONE             = 1,
    116  /* Refuse any cells which means a DESTROY cell will be sent back. */
    117  DOS_CC_DEFENSE_REFUSE_CELL      = 2,
    118 
    119  /* Maximum value that can be used. Useful for the boundaries of the
    120   * consensus parameter. */
    121  DOS_CC_DEFENSE_MAX              = 2,
    122 } dos_cc_defense_type_t;
    123 
    124 void dos_cc_new_create_cell(channel_t *channel);
    125 dos_cc_defense_type_t dos_cc_get_defense_type(channel_t *chan);
    126 
    127 /*
    128 * Concurrent connection DoS mitigation interface.
    129 */
    130 
    131 /* DoSConnectionEnabled default. Disabled by default. */
    132 #define DOS_CONN_ENABLED_DEFAULT 0
    133 /* DoSConnectionMaxConcurrentCount default. */
    134 #define DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT 100
    135 /* DoSConnectionDefenseType maps to the dos_conn_defense_type_t enum. */
    136 #define DOS_CONN_DEFENSE_TYPE_DEFAULT DOS_CONN_DEFENSE_CLOSE
    137 /* DoSConnectionConnectRate default. Per second. */
    138 #define DOS_CONN_CONNECT_RATE_DEFAULT 20
    139 /* DoSConnectionConnectBurst default. Per second. */
    140 #define DOS_CONN_CONNECT_BURST_DEFAULT 40
    141 /* DoSConnectionConnectDefenseTimePeriod default. Set to 24 hours. */
    142 #define DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_DEFAULT (24 * 60 * 60)
    143 /* DoSCircuitCreationDefenseTimePeriod minimum value. Because we add a random
    144 * offset to the marked timestamp, we need the minimum value to be non zero.
    145 * We consider that 10 seconds is an acceptable lower bound. */
    146 #define DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_MIN (10)
    147 
    148 /* Type of defense that we can use for the concurrent connection DoS
    149 * mitigation. */
    150 typedef enum dos_conn_defense_type_t {
    151  /* No defense used. */
    152  DOS_CONN_DEFENSE_NONE             = 1,
    153  /* Close immediately the connection meaning refuse it. */
    154  DOS_CONN_DEFENSE_CLOSE            = 2,
    155 
    156  /* Maximum value that can be used. Useful for the boundaries of the
    157   * consensus parameter. */
    158  DOS_CONN_DEFENSE_MAX              = 2,
    159 } dos_conn_defense_type_t;
    160 
    161 dos_conn_defense_type_t dos_conn_addr_get_defense_type(const tor_addr_t *addr);
    162 
    163 /*
    164 * Stream creation DoS mitigation subsystem interface.
    165 */
    166 
    167 /* DoSStreamCreationEnabled default. Disabled by deault. */
    168 #define DOS_STREAM_ENABLED_DEFAULT 0
    169 /* DoSStreamCreationDefenseType maps to the dos_stream_defense_type_t enum */
    170 #define DOS_STREAM_DEFENSE_TYPE_DEFAULT DOS_STREAM_DEFENSE_REFUSE_STREAM
    171 /* DosStreamCreationRate is 100 per seconds. */
    172 #define DOS_STREAM_RATE_DEFAULT 100
    173 /* DosStreamCreationBurst default. */
    174 #define DOS_STREAM_BURST_DEFAULT 300
    175 
    176 /* Type of defense that we can use for the stream creation DoS mitigation. */
    177 typedef enum dos_stream_defense_type_t {
    178  /* No defense used. */
    179  DOS_STREAM_DEFENSE_NONE           = 1,
    180  /* Reject the stream */
    181  DOS_STREAM_DEFENSE_REFUSE_STREAM  = 2,
    182  /* Close the circuit */
    183  DOS_STREAM_DEFENSE_CLOSE_CIRCUIT  = 3,
    184 
    185  /* Maximum value that can be used. Useful for the boundaries of the
    186   * consensus parameter. */
    187  DOS_STREAM_DEFENSE_MAX            = 3,
    188 } dos_stream_defense_type_t;
    189 
    190 dos_stream_defense_type_t dos_stream_new_begin_or_resolve_cell(
    191                                                          or_circuit_t *circ);
    192 void dos_stream_init_circ_tbf(or_circuit_t *circ);
    193 
    194 #ifdef DOS_PRIVATE
    195 
    196 STATIC uint32_t get_param_conn_max_concurrent_count(
    197                                              const networkstatus_t *ns);
    198 STATIC uint32_t get_param_cc_circuit_burst(const networkstatus_t *ns);
    199 STATIC uint32_t get_param_cc_min_concurrent_connection(
    200                                            const networkstatus_t *ns);
    201 STATIC uint32_t get_param_conn_connect_burst(const networkstatus_t *ns);
    202 
    203 STATIC uint64_t get_circuit_rate_per_second(void);
    204 STATIC void cc_stats_refill_bucket(cc_client_stats_t *stats,
    205                                   const tor_addr_t *addr);
    206 
    207 MOCK_DECL(STATIC unsigned int, get_param_cc_enabled,
    208          (const networkstatus_t *ns));
    209 MOCK_DECL(STATIC unsigned int, get_param_conn_enabled,
    210          (const networkstatus_t *ns));
    211 MOCK_DECL(STATIC unsigned int, get_param_stream_enabled,
    212          (const networkstatus_t *ns));
    213 
    214 #endif /* defined(DOS_PRIVATE) */
    215 
    216 #endif /* !defined(TOR_DOS_H) */