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) */