dos.h 4.26 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* Copyright (c) 2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/*
 * \file dos.h
 * \brief Header file for dos.c
 */

#ifndef TOR_DOS_H
#define TOR_DOS_H

/* Structure that keeps stats of client connection per-IP. */
typedef struct cc_client_stats_t {
  /* Number of allocated circuits remaining for this address.  It is
   * decremented every time a new circuit is seen for this client address and
   * if the count goes to 0, we have a positive detection. */
  uint32_t circuit_bucket;

  /* When was the last time we've refilled the circuit bucket? This is used to
   * know if we need to refill the bucket when a new circuit is seen. It is
   * synchronized using approx_time(). */
  time_t last_circ_bucket_refill_ts;

  /* This client address was detected to be above the circuit creation rate
   * and this timestamp indicates until when it should remain marked as
   * detected so we can apply a defense for the address. It is synchronized
   * using the approx_time(). */
  time_t marked_until_ts;
} cc_client_stats_t;

/* This object is a top level object that contains everything related to the
 * per-IP client DoS mitigation. Because it is per-IP, it is used in the geoip
 * clientmap_entry_t object. */
typedef struct dos_client_stats_t {
  /* Concurrent connection count from the specific address. 2^32 is most
   * likely way too big for the amount of allowed file descriptors. */
  uint32_t concurrent_count;

  /* Circuit creation statistics. This is only used if the circuit creation
   * subsystem has been enabled (dos_cc_enabled). */
  cc_client_stats_t cc_stats;
} dos_client_stats_t;

/* General API. */

void dos_init(void);
void dos_free_all(void);
void dos_consensus_has_changed(const networkstatus_t *ns);
int dos_enabled(void);

/*
 * Circuit creation DoS mitigation subsystemn interface.
 */

/* DoSCircuitCreationEnabled default. Disabled by default. */
#define DOS_CC_ENABLED_DEFAULT 0
/* DoSCircuitCreationDefenseType maps to the dos_cc_defense_type_t enum. */
#define DOS_CC_DEFENSE_TYPE_DEFAULT DOS_CC_DEFENSE_REFUSE_CELL
/* DoSCircuitCreationMinConnections default */
#define DOS_CC_MIN_CONCURRENT_CONN_DEFAULT 3
/* DoSCircuitCreationRateTenths is 3 per seconds. */
#define DOS_CC_CIRCUIT_RATE_TENTHS_DEFAULT (3 * 10)
/* DoSCircuitCreationBurst default. */
#define DOS_CC_CIRCUIT_BURST_DEFAULT 90
/* DoSCircuitCreationDefenseTimePeriod in seconds. */
#define DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT (60 * 60)

/* Type of defense that we can use for the circuit creation DoS mitigation. */
typedef enum dos_cc_defense_type_t {
  /* No defense used. */
  DOS_CC_DEFENSE_NONE             = 1,
  /* Refuse any cells which means a DESTROY cell will be sent back. */
  DOS_CC_DEFENSE_REFUSE_CELL      = 2,

  /* Maximum value that can be used. Useful for the boundaries of the
   * consensus parameter. */
  DOS_CC_DEFENSE_MAX              = 2,
} dos_cc_defense_type_t;

/*
 * Concurrent connection DoS mitigation interface.
 */

/* DoSConnectionEnabled default. Disabled by default. */
#define DOS_CONN_ENABLED_DEFAULT 0
/* DoSConnectionMaxConcurrentCount default. */
#define DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT 100
/* DoSConnectionDefenseType maps to the dos_conn_defense_type_t enum. */
#define DOS_CONN_DEFENSE_TYPE_DEFAULT DOS_CONN_DEFENSE_CLOSE

/* Type of defense that we can use for the concurrent connection DoS
 * mitigation. */
typedef enum dos_conn_defense_type_t {
  /* No defense used. */
  DOS_CONN_DEFENSE_NONE             = 1,
  /* Close immediately the connection meaning refuse it. */
  DOS_CONN_DEFENSE_CLOSE            = 2,

  /* Maximum value that can be used. Useful for the boundaries of the
   * consensus parameter. */
  DOS_CONN_DEFENSE_MAX              = 2,
} dos_conn_defense_type_t;

#ifdef DOS_PRIVATE

STATIC uint32_t get_param_conn_max_concurrent_count(
                                              const networkstatus_t *ns);
STATIC uint32_t get_param_cc_circuit_burst(const networkstatus_t *ns);
STATIC uint32_t get_param_cc_min_concurrent_connection(
                                            const networkstatus_t *ns);

MOCK_DECL(STATIC unsigned int, get_param_cc_enabled,
          (const networkstatus_t *ns));
MOCK_DECL(STATIC unsigned int, get_param_conn_enabled,
          (const networkstatus_t *ns));

#endif /* TOR_DOS_PRIVATE */

#endif /* TOR_DOS_H */