dos: Change the DoS heartbeat line format
[tor.git] / src / core / or / dos.c
blobb00863c118232cff9e79fb4e6bde89087a1acfa1
1 /* Copyright (c) 2018-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /*
5 * \file dos.c
6 * \brief Implement Denial of Service mitigation subsystem.
7 */
9 #define DOS_PRIVATE
11 #include "core/or/or.h"
12 #include "app/config/config.h"
13 #include "core/mainloop/connection.h"
14 #include "core/mainloop/mainloop.h"
15 #include "core/or/channel.h"
16 #include "core/or/connection_or.h"
17 #include "core/or/relay.h"
18 #include "feature/hs/hs_dos.h"
19 #include "feature/nodelist/networkstatus.h"
20 #include "feature/nodelist/nodelist.h"
21 #include "feature/relay/routermode.h"
22 #include "feature/stats/geoip_stats.h"
23 #include "lib/crypt_ops/crypto_rand.h"
25 #include "core/or/dos.h"
26 #include "core/or/dos_sys.h"
28 #include "core/or/dos_options_st.h"
29 #include "core/or/or_connection_st.h"
32 * Circuit creation denial of service mitigation.
34 * Namespace used for this mitigation framework is "dos_cc_" where "cc" is for
35 * Circuit Creation.
38 /* Is the circuit creation DoS mitigation enabled? */
39 static unsigned int dos_cc_enabled = 0;
41 /* Consensus parameters. They can be changed when a new consensus arrives.
42 * They are initialized with the hardcoded default values. */
43 static uint32_t dos_cc_min_concurrent_conn;
44 static uint32_t dos_cc_circuit_rate;
45 static uint32_t dos_cc_circuit_burst;
46 static dos_cc_defense_type_t dos_cc_defense_type;
47 static int32_t dos_cc_defense_time_period;
49 /* Keep some stats for the heartbeat so we can report out. */
50 static uint64_t cc_num_rejected_cells;
51 static uint32_t cc_num_marked_addrs;
54 * Concurrent connection denial of service mitigation.
56 * Namespace used for this mitigation framework is "dos_conn_".
59 /* Is the connection DoS mitigation enabled? */
60 static unsigned int dos_conn_enabled = 0;
62 /* Consensus parameters. They can be changed when a new consensus arrives.
63 * They are initialized with the hardcoded default values. */
64 static uint32_t dos_conn_max_concurrent_count;
65 static dos_conn_defense_type_t dos_conn_defense_type;
66 static uint32_t dos_conn_connect_rate = DOS_CONN_CONNECT_RATE_DEFAULT;
67 static uint32_t dos_conn_connect_burst = DOS_CONN_CONNECT_BURST_DEFAULT;
68 static int32_t dos_conn_connect_defense_time_period =
69 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_DEFAULT;
71 /* Keep some stats for the heartbeat so we can report out. */
72 static uint64_t conn_num_addr_rejected;
73 static uint64_t conn_num_addr_connect_rejected;
76 * General interface of the denial of service mitigation subsystem.
79 /* Keep stats for the heartbeat. */
80 static uint64_t num_single_hop_client_refused;
82 /* Return true iff the circuit creation mitigation is enabled. We look at the
83 * consensus for this else a default value is returned. */
84 MOCK_IMPL(STATIC unsigned int,
85 get_param_cc_enabled, (const networkstatus_t *ns))
87 if (dos_get_options()->DoSCircuitCreationEnabled != -1) {
88 return dos_get_options()->DoSCircuitCreationEnabled;
91 return !!networkstatus_get_param(ns, "DoSCircuitCreationEnabled",
92 DOS_CC_ENABLED_DEFAULT, 0, 1);
95 /* Return the parameter for the minimum concurrent connection at which we'll
96 * start counting circuit for a specific client address. */
97 STATIC uint32_t
98 get_param_cc_min_concurrent_connection(const networkstatus_t *ns)
100 if (dos_get_options()->DoSCircuitCreationMinConnections) {
101 return dos_get_options()->DoSCircuitCreationMinConnections;
103 return networkstatus_get_param(ns, "DoSCircuitCreationMinConnections",
104 DOS_CC_MIN_CONCURRENT_CONN_DEFAULT,
105 1, INT32_MAX);
108 /* Return the parameter for the time rate that is how many circuits over this
109 * time span. */
110 static uint32_t
111 get_param_cc_circuit_rate(const networkstatus_t *ns)
113 /* This is in seconds. */
114 if (dos_get_options()->DoSCircuitCreationRate) {
115 return dos_get_options()->DoSCircuitCreationRate;
117 return networkstatus_get_param(ns, "DoSCircuitCreationRate",
118 DOS_CC_CIRCUIT_RATE_DEFAULT,
119 1, INT32_MAX);
122 /* Return the parameter for the maximum circuit count for the circuit time
123 * rate. */
124 STATIC uint32_t
125 get_param_cc_circuit_burst(const networkstatus_t *ns)
127 if (dos_get_options()->DoSCircuitCreationBurst) {
128 return dos_get_options()->DoSCircuitCreationBurst;
130 return networkstatus_get_param(ns, "DoSCircuitCreationBurst",
131 DOS_CC_CIRCUIT_BURST_DEFAULT,
132 1, INT32_MAX);
135 /* Return the consensus parameter of the circuit creation defense type. */
136 static uint32_t
137 get_param_cc_defense_type(const networkstatus_t *ns)
139 if (dos_get_options()->DoSCircuitCreationDefenseType) {
140 return dos_get_options()->DoSCircuitCreationDefenseType;
142 return networkstatus_get_param(ns, "DoSCircuitCreationDefenseType",
143 DOS_CC_DEFENSE_TYPE_DEFAULT,
144 DOS_CC_DEFENSE_NONE, DOS_CC_DEFENSE_MAX);
147 /* Return the consensus parameter of the defense time period which is how much
148 * time should we defend against a malicious client address. */
149 static int32_t
150 get_param_cc_defense_time_period(const networkstatus_t *ns)
152 /* Time in seconds. */
153 if (dos_get_options()->DoSCircuitCreationDefenseTimePeriod) {
154 return dos_get_options()->DoSCircuitCreationDefenseTimePeriod;
156 return networkstatus_get_param(ns, "DoSCircuitCreationDefenseTimePeriod",
157 DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT,
158 0, INT32_MAX);
161 /* Return true iff connection mitigation is enabled. We look at the consensus
162 * for this else a default value is returned. */
163 MOCK_IMPL(STATIC unsigned int,
164 get_param_conn_enabled, (const networkstatus_t *ns))
166 if (dos_get_options()->DoSConnectionEnabled != -1) {
167 return dos_get_options()->DoSConnectionEnabled;
169 return !!networkstatus_get_param(ns, "DoSConnectionEnabled",
170 DOS_CONN_ENABLED_DEFAULT, 0, 1);
173 /* Return the consensus parameter for the maximum concurrent connection
174 * allowed. */
175 STATIC uint32_t
176 get_param_conn_max_concurrent_count(const networkstatus_t *ns)
178 if (dos_get_options()->DoSConnectionMaxConcurrentCount) {
179 return dos_get_options()->DoSConnectionMaxConcurrentCount;
181 return networkstatus_get_param(ns, "DoSConnectionMaxConcurrentCount",
182 DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT,
183 1, INT32_MAX);
186 /* Return the consensus parameter of the connection defense type. */
187 static uint32_t
188 get_param_conn_defense_type(const networkstatus_t *ns)
190 if (dos_get_options()->DoSConnectionDefenseType) {
191 return dos_get_options()->DoSConnectionDefenseType;
193 return networkstatus_get_param(ns, "DoSConnectionDefenseType",
194 DOS_CONN_DEFENSE_TYPE_DEFAULT,
195 DOS_CONN_DEFENSE_NONE, DOS_CONN_DEFENSE_MAX);
198 /* Return the connection connect rate parameters either from the configuration
199 * file or, if not found, consensus parameter. */
200 static uint32_t
201 get_param_conn_connect_rate(const networkstatus_t *ns)
203 if (dos_get_options()->DoSConnectionConnectRate) {
204 return dos_get_options()->DoSConnectionConnectRate;
206 return networkstatus_get_param(ns, "DoSConnectionConnectRate",
207 DOS_CONN_CONNECT_RATE_DEFAULT,
208 1, INT32_MAX);
211 /* Return the connection connect burst parameters either from the
212 * configuration file or, if not found, consensus parameter. */
213 STATIC uint32_t
214 get_param_conn_connect_burst(const networkstatus_t *ns)
216 if (dos_get_options()->DoSConnectionConnectBurst) {
217 return dos_get_options()->DoSConnectionConnectBurst;
219 return networkstatus_get_param(ns, "DoSConnectionConnectBurst",
220 DOS_CONN_CONNECT_BURST_DEFAULT,
221 1, INT32_MAX);
224 /* Return the connection connect defense time period from the configuration
225 * file or, if not found, the consensus parameter. */
226 static int32_t
227 get_param_conn_connect_defense_time_period(const networkstatus_t *ns)
229 /* Time in seconds. */
230 if (dos_get_options()->DoSConnectionConnectDefenseTimePeriod) {
231 return dos_get_options()->DoSConnectionConnectDefenseTimePeriod;
233 return networkstatus_get_param(ns, "DoSConnectionConnectDefenseTimePeriod",
234 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_DEFAULT,
235 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_MIN,
236 INT32_MAX);
239 /* Set circuit creation parameters located in the consensus or their default
240 * if none are present. Called at initialization or when the consensus
241 * changes. */
242 static void
243 set_dos_parameters(const networkstatus_t *ns)
245 /* Get the default consensus param values. */
246 dos_cc_enabled = get_param_cc_enabled(ns);
247 dos_cc_min_concurrent_conn = get_param_cc_min_concurrent_connection(ns);
248 dos_cc_circuit_rate = get_param_cc_circuit_rate(ns);
249 dos_cc_circuit_burst = get_param_cc_circuit_burst(ns);
250 dos_cc_defense_time_period = get_param_cc_defense_time_period(ns);
251 dos_cc_defense_type = get_param_cc_defense_type(ns);
253 /* Connection detection. */
254 dos_conn_enabled = get_param_conn_enabled(ns);
255 dos_conn_max_concurrent_count = get_param_conn_max_concurrent_count(ns);
256 dos_conn_defense_type = get_param_conn_defense_type(ns);
257 dos_conn_connect_rate = get_param_conn_connect_rate(ns);
258 dos_conn_connect_burst = get_param_conn_connect_burst(ns);
259 dos_conn_connect_defense_time_period =
260 get_param_conn_connect_defense_time_period(ns);
263 /* Free everything for the circuit creation DoS mitigation subsystem. */
264 static void
265 cc_free_all(void)
267 /* If everything is freed, the circuit creation subsystem is not enabled. */
268 dos_cc_enabled = 0;
271 /* Called when the consensus has changed. Do appropriate actions for the
272 * circuit creation subsystem. */
273 static void
274 cc_consensus_has_changed(const networkstatus_t *ns)
276 /* Looking at the consensus, is the circuit creation subsystem enabled? If
277 * not and it was enabled before, clean it up. */
278 if (dos_cc_enabled && !get_param_cc_enabled(ns)) {
279 cc_free_all();
283 /** Return the number of circuits we allow per second under the current
284 * configuration. */
285 STATIC uint64_t
286 get_circuit_rate_per_second(void)
288 return dos_cc_circuit_rate;
291 /* Given the circuit creation client statistics object, refill the circuit
292 * bucket if needed. This also works if the bucket was never filled in the
293 * first place. The addr is only used for logging purposes. */
294 STATIC void
295 cc_stats_refill_bucket(cc_client_stats_t *stats, const tor_addr_t *addr)
297 uint32_t new_circuit_bucket_count;
298 uint64_t num_token, elapsed_time_last_refill = 0, circuit_rate = 0;
299 time_t now;
300 int64_t last_refill_ts;
302 tor_assert(stats);
303 tor_assert(addr);
305 now = approx_time();
306 last_refill_ts = (int64_t)stats->last_circ_bucket_refill_ts;
308 /* If less than a second has elapsed, don't add any tokens.
309 * Note: If a relay's clock is ever 0, any new clients won't get a refill
310 * until the next second. But a relay that thinks it is 1970 will never
311 * validate the public consensus. */
312 if ((int64_t)now == last_refill_ts) {
313 goto done;
316 /* At this point, we know we might need to add token to the bucket. We'll
317 * first get the circuit rate that is how many circuit are we allowed to do
318 * per second. */
319 circuit_rate = get_circuit_rate_per_second();
321 /* We've never filled the bucket so fill it with the maximum being the burst
322 * and we are done.
323 * Note: If a relay's clock is ever 0, all clients that were last refilled
324 * in that zero second will get a full refill here. */
325 if (last_refill_ts == 0) {
326 num_token = dos_cc_circuit_burst;
327 goto end;
330 /* Our clock jumped backward so fill it up to the maximum. Not filling it
331 * could trigger a detection for a valid client. Also, if the clock jumped
332 * negative but we didn't notice until the elapsed time became positive
333 * again, then we potentially spent many seconds not refilling the bucket
334 * when we should have been refilling it. But the fact that we didn't notice
335 * until now means that no circuit creation requests came in during that
336 * time, so the client doesn't end up punished that much from this hopefully
337 * rare situation.*/
338 if ((int64_t)now < last_refill_ts) {
339 /* Use the maximum allowed value of token. */
340 num_token = dos_cc_circuit_burst;
341 goto end;
344 /* How many seconds have elapsed between now and the last refill?
345 * This subtraction can't underflow, because now >= last_refill_ts.
346 * And it can't overflow, because INT64_MAX - (-INT64_MIN) == UINT64_MAX. */
347 elapsed_time_last_refill = (uint64_t)now - last_refill_ts;
349 /* If the elapsed time is very large, it means our clock jumped forward.
350 * If the multiplication would overflow, use the maximum allowed value. */
351 if (elapsed_time_last_refill > UINT32_MAX) {
352 num_token = dos_cc_circuit_burst;
353 goto end;
356 /* Compute how many circuits we are allowed in that time frame which we'll
357 * add to the bucket. This can't overflow, because both multiplicands
358 * are less than or equal to UINT32_MAX, and num_token is uint64_t. */
359 num_token = elapsed_time_last_refill * circuit_rate;
361 end:
362 /* If the sum would overflow, use the maximum allowed value. */
363 if (num_token > UINT32_MAX - stats->circuit_bucket) {
364 new_circuit_bucket_count = dos_cc_circuit_burst;
365 } else {
366 /* We cap the bucket to the burst value else this could overflow uint32_t
367 * over time. */
368 new_circuit_bucket_count = MIN(stats->circuit_bucket + (uint32_t)num_token,
369 dos_cc_circuit_burst);
372 /* This function is not allowed to make the bucket count larger than the
373 * burst value */
374 tor_assert_nonfatal(new_circuit_bucket_count <= dos_cc_circuit_burst);
375 /* This function is not allowed to make the bucket count smaller, unless it
376 * is decreasing it to a newly configured, lower burst value. We allow the
377 * bucket to stay the same size, in case the circuit rate is zero. */
378 tor_assert_nonfatal(new_circuit_bucket_count >= stats->circuit_bucket ||
379 new_circuit_bucket_count == dos_cc_circuit_burst);
381 log_debug(LD_DOS, "DoS address %s has its circuit bucket value: %" PRIu32
382 ". Filling it to %" PRIu32 ". Circuit rate is %" PRIu64
383 ". Elapsed time is %" PRIi64,
384 fmt_addr(addr), stats->circuit_bucket, new_circuit_bucket_count,
385 circuit_rate, (int64_t)elapsed_time_last_refill);
387 stats->circuit_bucket = new_circuit_bucket_count;
388 stats->last_circ_bucket_refill_ts = now;
390 done:
391 return;
394 /* Return true iff the circuit bucket is down to 0 and the number of
395 * concurrent connections is greater or equal the minimum threshold set the
396 * consensus parameter. */
397 static int
398 cc_has_exhausted_circuits(const dos_client_stats_t *stats)
400 tor_assert(stats);
401 return stats->cc_stats.circuit_bucket == 0 &&
402 stats->conn_stats.concurrent_count >= dos_cc_min_concurrent_conn;
405 /* Mark client address by setting a timestamp in the stats object which tells
406 * us until when it is marked as positively detected. */
407 static void
408 cc_mark_client(cc_client_stats_t *stats)
410 tor_assert(stats);
411 /* We add a random offset of a maximum of half the defense time so it is
412 * less predictable. */
413 stats->marked_until_ts =
414 approx_time() + dos_cc_defense_time_period +
415 crypto_rand_int_range(1, dos_cc_defense_time_period / 2);
418 /* Return true iff the given channel address is marked as malicious. This is
419 * called a lot and part of the fast path of handling cells. It has to remain
420 * as fast as we can. */
421 static int
422 cc_channel_addr_is_marked(channel_t *chan)
424 time_t now;
425 tor_addr_t addr;
426 clientmap_entry_t *entry;
427 cc_client_stats_t *stats = NULL;
429 if (chan == NULL) {
430 goto end;
432 /* Must be a client connection else we ignore. */
433 if (!channel_is_client(chan)) {
434 goto end;
436 /* Without an IP address, nothing can work. */
437 if (!channel_get_addr_if_possible(chan, &addr)) {
438 goto end;
441 /* We are only interested in client connection from the geoip cache. */
442 entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
443 if (entry == NULL) {
444 /* We can have a connection creating circuits but not tracked by the geoip
445 * cache. Once this DoS subsystem is enabled, we can end up here with no
446 * entry for the channel. */
447 goto end;
449 now = approx_time();
450 stats = &entry->dos_stats.cc_stats;
452 end:
453 return stats && stats->marked_until_ts >= now;
456 /* Concurrent connection private API. */
458 /* Mark client connection stats by setting a timestamp which tells us until
459 * when it is marked as positively detected. */
460 static void
461 conn_mark_client(conn_client_stats_t *stats)
463 tor_assert(stats);
465 /* We add a random offset of a maximum of half the defense time so it is
466 * less predictable and thus more difficult to game. */
467 stats->marked_until_ts =
468 approx_time() + dos_conn_connect_defense_time_period +
469 crypto_rand_int_range(1, dos_conn_connect_defense_time_period / 2);
472 /* Free everything for the connection DoS mitigation subsystem. */
473 static void
474 conn_free_all(void)
476 dos_conn_enabled = 0;
479 /* Called when the consensus has changed. Do appropriate actions for the
480 * connection mitigation subsystem. */
481 static void
482 conn_consensus_has_changed(const networkstatus_t *ns)
484 /* Looking at the consensus, is the connection mitigation subsystem enabled?
485 * If not and it was enabled before, clean it up. */
486 if (dos_conn_enabled && !get_param_conn_enabled(ns)) {
487 conn_free_all();
491 /** Called when a new client connection has arrived. The following will update
492 * the client connection statistics.
494 * The addr is used for logging purposes only.
496 * If the connect counter reaches its limit, it is marked. */
497 static void
498 conn_update_on_connect(conn_client_stats_t *stats, const tor_addr_t *addr)
500 tor_assert(stats);
501 tor_assert(addr);
503 /* Update concurrent count for this new connect. */
504 stats->concurrent_count++;
506 /* Refill connect connection count. */
507 token_bucket_ctr_refill(&stats->connect_count, (uint32_t) approx_time());
509 /* Decrement counter for this new connection. */
510 if (token_bucket_ctr_get(&stats->connect_count) > 0) {
511 token_bucket_ctr_dec(&stats->connect_count, 1);
514 /* Assess connect counter. Mark it if counter is down to 0 and we haven't
515 * marked it before or it was reset. This is to avoid to re-mark it over and
516 * over again extending continously the blocked time. */
517 if (token_bucket_ctr_get(&stats->connect_count) == 0 &&
518 stats->marked_until_ts == 0) {
519 conn_mark_client(stats);
522 log_debug(LD_DOS, "Client address %s has now %u concurrent connections. "
523 "Remaining %lu/sec connections are allowed.",
524 fmt_addr(addr), stats->concurrent_count,
525 token_bucket_ctr_get(&stats->connect_count));
528 /** Called when a client connection is closed. The following will update
529 * the client connection statistics.
531 * The addr is used for logging purposes only. */
532 static void
533 conn_update_on_close(conn_client_stats_t *stats, const tor_addr_t *addr)
535 /* Extra super duper safety. Going below 0 means an underflow which could
536 * lead to most likely a false positive. In theory, this should never happen
537 * but lets be extra safe. */
538 if (BUG(stats->concurrent_count == 0)) {
539 return;
542 stats->concurrent_count--;
543 log_debug(LD_DOS, "Client address %s has lost a connection. Concurrent "
544 "connections are now at %u",
545 fmt_addr(addr), stats->concurrent_count);
548 /* General private API */
550 /* Return true iff we have at least one DoS detection enabled. This is used to
551 * decide if we need to allocate any kind of high level DoS object. */
552 static inline int
553 dos_is_enabled(void)
555 return (dos_cc_enabled || dos_conn_enabled);
558 /* Circuit creation public API. */
560 /* Called when a CREATE cell is received from the given channel. */
561 void
562 dos_cc_new_create_cell(channel_t *chan)
564 tor_addr_t addr;
565 clientmap_entry_t *entry;
567 tor_assert(chan);
569 /* Skip everything if not enabled. */
570 if (!dos_cc_enabled) {
571 goto end;
574 /* Must be a client connection else we ignore. */
575 if (!channel_is_client(chan)) {
576 goto end;
578 /* Without an IP address, nothing can work. */
579 if (!channel_get_addr_if_possible(chan, &addr)) {
580 goto end;
583 /* We are only interested in client connection from the geoip cache. */
584 entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
585 if (entry == NULL) {
586 /* We can have a connection creating circuits but not tracked by the geoip
587 * cache. Once this DoS subsystem is enabled, we can end up here with no
588 * entry for the channel. */
589 goto end;
592 /* General comment. Even though the client can already be marked as
593 * malicious, we continue to track statistics. If it keeps going above
594 * threshold while marked, the defense period time will grow longer. There
595 * is really no point at unmarking a client that keeps DoSing us. */
597 /* First of all, we'll try to refill the circuit bucket opportunistically
598 * before we assess. */
599 cc_stats_refill_bucket(&entry->dos_stats.cc_stats, &addr);
601 /* Take a token out of the circuit bucket if we are above 0 so we don't
602 * underflow the bucket. */
603 if (entry->dos_stats.cc_stats.circuit_bucket > 0) {
604 entry->dos_stats.cc_stats.circuit_bucket--;
607 /* This is the detection. Assess at every CREATE cell if the client should
608 * get marked as malicious. This should be kept as fast as possible. */
609 if (cc_has_exhausted_circuits(&entry->dos_stats)) {
610 /* If this is the first time we mark this entry, log it a info level.
611 * Under heavy DDoS, logging each time we mark would results in lots and
612 * lots of logs. */
613 if (entry->dos_stats.cc_stats.marked_until_ts == 0) {
614 log_debug(LD_DOS, "Detected circuit creation DoS by address: %s",
615 fmt_addr(&addr));
616 cc_num_marked_addrs++;
618 cc_mark_client(&entry->dos_stats.cc_stats);
621 end:
622 return;
625 /* Return the defense type that should be used for this circuit.
627 * This is part of the fast path and called a lot. */
628 dos_cc_defense_type_t
629 dos_cc_get_defense_type(channel_t *chan)
631 tor_assert(chan);
633 /* Skip everything if not enabled. */
634 if (!dos_cc_enabled) {
635 goto end;
638 /* On an OR circuit, we'll check if the previous channel is a marked client
639 * connection detected by our DoS circuit creation mitigation subsystem. */
640 if (cc_channel_addr_is_marked(chan)) {
641 /* We've just assess that this circuit should trigger a defense for the
642 * cell it just seen. Note it down. */
643 cc_num_rejected_cells++;
644 return dos_cc_defense_type;
647 end:
648 return DOS_CC_DEFENSE_NONE;
651 /* Concurrent connection detection public API. */
653 /* Return true iff the given address is permitted to open another connection.
654 * A defense value is returned for the caller to take appropriate actions. */
655 dos_conn_defense_type_t
656 dos_conn_addr_get_defense_type(const tor_addr_t *addr)
658 clientmap_entry_t *entry;
660 tor_assert(addr);
662 /* Skip everything if not enabled. */
663 if (!dos_conn_enabled) {
664 goto end;
667 /* We are only interested in client connection from the geoip cache. */
668 entry = geoip_lookup_client(addr, NULL, GEOIP_CLIENT_CONNECT);
669 if (entry == NULL) {
670 goto end;
673 /* Is this address marked as making too many client connections? */
674 if (entry->dos_stats.conn_stats.marked_until_ts >= approx_time()) {
675 conn_num_addr_connect_rejected++;
676 return dos_conn_defense_type;
678 /* Reset it to 0 here so that if the marked timestamp has expired that is
679 * we've gone beyond it, we have to reset it so the detection can mark it
680 * again in the future. */
681 entry->dos_stats.conn_stats.marked_until_ts = 0;
683 /* Need to be above the maximum concurrent connection count to trigger a
684 * defense. */
685 if (entry->dos_stats.conn_stats.concurrent_count >
686 dos_conn_max_concurrent_count) {
687 conn_num_addr_rejected++;
688 return dos_conn_defense_type;
691 end:
692 return DOS_CONN_DEFENSE_NONE;
695 /* General API */
697 /* Take any appropriate actions for the given geoip entry that is about to get
698 * freed. This is called for every entry that is being freed.
700 * This function will clear out the connection tracked flag if the concurrent
701 * count of the entry is above 0 so if those connections end up being seen by
702 * this subsystem, we won't try to decrement the counter for a new geoip entry
703 * that might have been added after this call for the same address. */
704 void
705 dos_geoip_entry_about_to_free(const clientmap_entry_t *geoip_ent)
707 tor_assert(geoip_ent);
709 /* The count is down to 0 meaning no connections right now, we can safely
710 * clear the geoip entry from the cache. */
711 if (geoip_ent->dos_stats.conn_stats.concurrent_count == 0) {
712 goto end;
715 /* For each connection matching the geoip entry address, we'll clear the
716 * tracked flag because the entry is about to get removed from the geoip
717 * cache. We do not try to decrement if the flag is not set. */
718 SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
719 if (conn->type == CONN_TYPE_OR) {
720 or_connection_t *or_conn = TO_OR_CONN(conn);
721 if (!tor_addr_compare(&geoip_ent->addr, &TO_CONN(or_conn)->addr,
722 CMP_EXACT)) {
723 or_conn->tracked_for_dos_mitigation = 0;
726 } SMARTLIST_FOREACH_END(conn);
728 end:
729 return;
732 /** A new geoip client entry has been allocated, initialize its DoS object. */
733 void
734 dos_geoip_entry_init(clientmap_entry_t *geoip_ent)
736 tor_assert(geoip_ent);
738 /* Initialize the connection count counter with the rate and burst
739 * parameters taken either from configuration or consensus.
741 * We do this even if the DoS connection detection is not enabled because it
742 * can be enabled at runtime and these counters need to be valid. */
743 token_bucket_ctr_init(&geoip_ent->dos_stats.conn_stats.connect_count,
744 dos_conn_connect_rate, dos_conn_connect_burst,
745 (uint32_t) approx_time());
748 /* Note down that we've just refused a single hop client. This increments a
749 * counter later used for the heartbeat. */
750 void
751 dos_note_refuse_single_hop_client(void)
753 num_single_hop_client_refused++;
756 /* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should
757 * be refused. */
759 dos_should_refuse_single_hop_client(void)
761 /* If we aren't a public relay, this shouldn't apply to anything. */
762 if (!public_server_mode(get_options())) {
763 return 0;
766 if (dos_get_options()->DoSRefuseSingleHopClientRendezvous != -1) {
767 return dos_get_options()->DoSRefuseSingleHopClientRendezvous;
770 return (int) networkstatus_get_param(NULL,
771 "DoSRefuseSingleHopClientRendezvous",
772 0 /* default */, 0, 1);
775 /* Log a heartbeat message with some statistics. */
776 void
777 dos_log_heartbeat(void)
779 smartlist_t *elems = smartlist_new();
781 /* Stats number coming from relay.c append_cell_to_circuit_queue(). */
782 smartlist_add_asprintf(elems,
783 "%" PRIu64 " circuits killed with too many cells",
784 stats_n_circ_max_cell_reached);
786 if (dos_cc_enabled) {
787 smartlist_add_asprintf(elems,
788 "%" PRIu64 " circuits rejected, "
789 "%" PRIu32 " marked addresses",
790 cc_num_rejected_cells, cc_num_marked_addrs);
791 } else {
792 smartlist_add_asprintf(elems, "[DoSCircuitCreationEnabled disabled]");
795 if (dos_conn_enabled) {
796 smartlist_add_asprintf(elems,
797 "%" PRIu64 " same address concurrent "
798 "connections rejected", conn_num_addr_rejected);
799 smartlist_add_asprintf(elems,
800 "%" PRIu64 " connections rejected",
801 conn_num_addr_connect_rejected);
802 } else {
803 smartlist_add_asprintf(elems, "[DoSConnectionEnabled disabled]");
806 if (dos_should_refuse_single_hop_client()) {
807 smartlist_add_asprintf(elems,
808 "%" PRIu64 " single hop clients refused",
809 num_single_hop_client_refused);
810 } else {
811 smartlist_add_asprintf(elems,
812 "[DoSRefuseSingleHopClientRendezvous disabled]");
815 /* HS DoS stats. */
816 smartlist_add_asprintf(elems,
817 "%" PRIu64 " INTRODUCE2 rejected",
818 hs_dos_get_intro2_rejected_count());
820 char *msg = smartlist_join_strings(elems, ", ", 0, NULL);
822 log_notice(LD_HEARTBEAT, "DoS mitigation since startup: %s.", msg);
824 tor_free(msg);
825 SMARTLIST_FOREACH(elems, char *, e, tor_free(e));
826 smartlist_free(elems);
829 /* Called when a new client connection has been established on the given
830 * address. */
831 void
832 dos_new_client_conn(or_connection_t *or_conn, const char *transport_name)
834 clientmap_entry_t *entry;
836 tor_assert(or_conn);
838 /* Past that point, we know we have at least one DoS detection subsystem
839 * enabled so we'll start allocating stuff. */
840 if (!dos_is_enabled()) {
841 goto end;
844 /* We ignore any known address meaning an address of a known relay. The
845 * reason to do so is because network reentry is possible where a client
846 * connection comes from an Exit node. Even when we'll fix reentry, this is
847 * a robust defense to keep in place. */
848 if (nodelist_probably_contains_address(&TO_CONN(or_conn)->addr)) {
849 goto end;
852 /* We are only interested in client connection from the geoip cache. */
853 entry = geoip_lookup_client(&TO_CONN(or_conn)->addr, transport_name,
854 GEOIP_CLIENT_CONNECT);
855 if (BUG(entry == NULL)) {
856 /* Should never happen because we note down the address in the geoip
857 * cache before this is called. */
858 goto end;
861 /* Update stats from this new connect. */
862 conn_update_on_connect(&entry->dos_stats.conn_stats,
863 &TO_CONN(or_conn)->addr);
865 or_conn->tracked_for_dos_mitigation = 1;
867 end:
868 return;
871 /* Called when a client connection for the given IP address has been closed. */
872 void
873 dos_close_client_conn(const or_connection_t *or_conn)
875 clientmap_entry_t *entry;
877 tor_assert(or_conn);
879 /* We have to decrement the count on tracked connection only even if the
880 * subsystem has been disabled at runtime because it might be re-enabled
881 * after and we need to keep a synchronized counter at all time. */
882 if (!or_conn->tracked_for_dos_mitigation) {
883 goto end;
886 /* We are only interested in client connection from the geoip cache. */
887 entry = geoip_lookup_client(&TO_CONN(or_conn)->addr, NULL,
888 GEOIP_CLIENT_CONNECT);
889 if (entry == NULL) {
890 /* This can happen because we can close a connection before the channel
891 * got to be noted down in the geoip cache. */
892 goto end;
895 /* Update stats from this new close. */
896 conn_update_on_close(&entry->dos_stats.conn_stats, &TO_CONN(or_conn)->addr);
898 end:
899 return;
902 /* Called when the consensus has changed. We might have new consensus
903 * parameters to look at. */
904 void
905 dos_consensus_has_changed(const networkstatus_t *ns)
907 /* There are two ways to configure this subsystem, one at startup through
908 * dos_init() which is called when the options are parsed. And this one
909 * through the consensus. We don't want to enable any DoS mitigation if we
910 * aren't a public relay. */
911 if (!public_server_mode(get_options())) {
912 return;
915 cc_consensus_has_changed(ns);
916 conn_consensus_has_changed(ns);
918 /* We were already enabled or we just became enabled but either way, set the
919 * consensus parameters for all subsystems. */
920 set_dos_parameters(ns);
923 /* Return true iff the DoS mitigation subsystem is enabled. */
925 dos_enabled(void)
927 return dos_is_enabled();
930 /* Free everything from the Denial of Service subsystem. */
931 void
932 dos_free_all(void)
934 /* Free the circuit creation mitigation subsystem. It is safe to do this
935 * even if it wasn't initialized. */
936 cc_free_all();
938 /* Free the connection mitigation subsystem. It is safe to do this even if
939 * it wasn't initialized. */
940 conn_free_all();
943 /* Initialize the Denial of Service subsystem. */
944 void
945 dos_init(void)
947 /* To initialize, we only need to get the parameters. */
948 set_dos_parameters(NULL);