1 /* Copyright (c) 2018-2018, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
6 * \brief Implement Denial of Service mitigation subsystem.
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/nodelist/networkstatus.h"
19 #include "feature/nodelist/nodelist.h"
20 #include "feature/relay/routermode.h"
21 #include "feature/stats/geoip_stats.h"
22 #include "lib/crypt_ops/crypto_rand.h"
24 #include "core/or/dos.h"
26 #include "core/or/or_connection_st.h"
29 * Circuit creation denial of service mitigation.
31 * Namespace used for this mitigation framework is "dos_cc_" where "cc" is for
35 /* Is the circuit creation DoS mitigation enabled? */
36 static unsigned int dos_cc_enabled
= 0;
38 /* Consensus parameters. They can be changed when a new consensus arrives.
39 * They are initialized with the hardcoded default values. */
40 static uint32_t dos_cc_min_concurrent_conn
;
41 static uint32_t dos_cc_circuit_rate
;
42 static uint32_t dos_cc_circuit_burst
;
43 static dos_cc_defense_type_t dos_cc_defense_type
;
44 static int32_t dos_cc_defense_time_period
;
46 /* Keep some stats for the heartbeat so we can report out. */
47 static uint64_t cc_num_rejected_cells
;
48 static uint32_t cc_num_marked_addrs
;
51 * Concurrent connection denial of service mitigation.
53 * Namespace used for this mitigation framework is "dos_conn_".
56 /* Is the connection DoS mitigation enabled? */
57 static unsigned int dos_conn_enabled
= 0;
59 /* Consensus parameters. They can be changed when a new consensus arrives.
60 * They are initialized with the hardcoded default values. */
61 static uint32_t dos_conn_max_concurrent_count
;
62 static dos_conn_defense_type_t dos_conn_defense_type
;
64 /* Keep some stats for the heartbeat so we can report out. */
65 static uint64_t conn_num_addr_rejected
;
68 * General interface of the denial of service mitigation subsystem.
71 /* Keep stats for the heartbeat. */
72 static uint64_t num_single_hop_client_refused
;
74 /* Return true iff the circuit creation mitigation is enabled. We look at the
75 * consensus for this else a default value is returned. */
76 MOCK_IMPL(STATIC
unsigned int,
77 get_param_cc_enabled
, (const networkstatus_t
*ns
))
79 if (get_options()->DoSCircuitCreationEnabled
!= -1) {
80 return get_options()->DoSCircuitCreationEnabled
;
83 return !!networkstatus_get_param(ns
, "DoSCircuitCreationEnabled",
84 DOS_CC_ENABLED_DEFAULT
, 0, 1);
87 /* Return the parameter for the minimum concurrent connection at which we'll
88 * start counting circuit for a specific client address. */
90 get_param_cc_min_concurrent_connection(const networkstatus_t
*ns
)
92 if (get_options()->DoSCircuitCreationMinConnections
) {
93 return get_options()->DoSCircuitCreationMinConnections
;
95 return networkstatus_get_param(ns
, "DoSCircuitCreationMinConnections",
96 DOS_CC_MIN_CONCURRENT_CONN_DEFAULT
,
100 /* Return the parameter for the time rate that is how many circuits over this
103 get_param_cc_circuit_rate(const networkstatus_t
*ns
)
105 /* This is in seconds. */
106 if (get_options()->DoSCircuitCreationRate
) {
107 return get_options()->DoSCircuitCreationRate
;
109 return networkstatus_get_param(ns
, "DoSCircuitCreationRate",
110 DOS_CC_CIRCUIT_RATE_DEFAULT
,
114 /* Return the parameter for the maximum circuit count for the circuit time
117 get_param_cc_circuit_burst(const networkstatus_t
*ns
)
119 if (get_options()->DoSCircuitCreationBurst
) {
120 return get_options()->DoSCircuitCreationBurst
;
122 return networkstatus_get_param(ns
, "DoSCircuitCreationBurst",
123 DOS_CC_CIRCUIT_BURST_DEFAULT
,
127 /* Return the consensus parameter of the circuit creation defense type. */
129 get_param_cc_defense_type(const networkstatus_t
*ns
)
131 if (get_options()->DoSCircuitCreationDefenseType
) {
132 return get_options()->DoSCircuitCreationDefenseType
;
134 return networkstatus_get_param(ns
, "DoSCircuitCreationDefenseType",
135 DOS_CC_DEFENSE_TYPE_DEFAULT
,
136 DOS_CC_DEFENSE_NONE
, DOS_CC_DEFENSE_MAX
);
139 /* Return the consensus parameter of the defense time period which is how much
140 * time should we defend against a malicious client address. */
142 get_param_cc_defense_time_period(const networkstatus_t
*ns
)
144 /* Time in seconds. */
145 if (get_options()->DoSCircuitCreationDefenseTimePeriod
) {
146 return get_options()->DoSCircuitCreationDefenseTimePeriod
;
148 return networkstatus_get_param(ns
, "DoSCircuitCreationDefenseTimePeriod",
149 DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT
,
153 /* Return true iff connection mitigation is enabled. We look at the consensus
154 * for this else a default value is returned. */
155 MOCK_IMPL(STATIC
unsigned int,
156 get_param_conn_enabled
, (const networkstatus_t
*ns
))
158 if (get_options()->DoSConnectionEnabled
!= -1) {
159 return get_options()->DoSConnectionEnabled
;
161 return !!networkstatus_get_param(ns
, "DoSConnectionEnabled",
162 DOS_CONN_ENABLED_DEFAULT
, 0, 1);
165 /* Return the consensus parameter for the maximum concurrent connection
168 get_param_conn_max_concurrent_count(const networkstatus_t
*ns
)
170 if (get_options()->DoSConnectionMaxConcurrentCount
) {
171 return get_options()->DoSConnectionMaxConcurrentCount
;
173 return networkstatus_get_param(ns
, "DoSConnectionMaxConcurrentCount",
174 DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT
,
178 /* Return the consensus parameter of the connection defense type. */
180 get_param_conn_defense_type(const networkstatus_t
*ns
)
182 if (get_options()->DoSConnectionDefenseType
) {
183 return get_options()->DoSConnectionDefenseType
;
185 return networkstatus_get_param(ns
, "DoSConnectionDefenseType",
186 DOS_CONN_DEFENSE_TYPE_DEFAULT
,
187 DOS_CONN_DEFENSE_NONE
, DOS_CONN_DEFENSE_MAX
);
190 /* Set circuit creation parameters located in the consensus or their default
191 * if none are present. Called at initialization or when the consensus
194 set_dos_parameters(const networkstatus_t
*ns
)
196 /* Get the default consensus param values. */
197 dos_cc_enabled
= get_param_cc_enabled(ns
);
198 dos_cc_min_concurrent_conn
= get_param_cc_min_concurrent_connection(ns
);
199 dos_cc_circuit_rate
= get_param_cc_circuit_rate(ns
);
200 dos_cc_circuit_burst
= get_param_cc_circuit_burst(ns
);
201 dos_cc_defense_time_period
= get_param_cc_defense_time_period(ns
);
202 dos_cc_defense_type
= get_param_cc_defense_type(ns
);
204 /* Connection detection. */
205 dos_conn_enabled
= get_param_conn_enabled(ns
);
206 dos_conn_max_concurrent_count
= get_param_conn_max_concurrent_count(ns
);
207 dos_conn_defense_type
= get_param_conn_defense_type(ns
);
210 /* Free everything for the circuit creation DoS mitigation subsystem. */
214 /* If everything is freed, the circuit creation subsystem is not enabled. */
218 /* Called when the consensus has changed. Do appropriate actions for the
219 * circuit creation subsystem. */
221 cc_consensus_has_changed(const networkstatus_t
*ns
)
223 /* Looking at the consensus, is the circuit creation subsystem enabled? If
224 * not and it was enabled before, clean it up. */
225 if (dos_cc_enabled
&& !get_param_cc_enabled(ns
)) {
230 /** Return the number of circuits we allow per second under the current
233 get_circuit_rate_per_second(void)
235 return dos_cc_circuit_rate
;
238 /* Given the circuit creation client statistics object, refill the circuit
239 * bucket if needed. This also works if the bucket was never filled in the
240 * first place. The addr is only used for logging purposes. */
242 cc_stats_refill_bucket(cc_client_stats_t
*stats
, const tor_addr_t
*addr
)
244 uint32_t new_circuit_bucket_count
;
245 uint64_t num_token
, elapsed_time_last_refill
= 0, circuit_rate
= 0;
247 int64_t last_refill_ts
;
253 last_refill_ts
= (int64_t)stats
->last_circ_bucket_refill_ts
;
255 /* If less than a second has elapsed, don't add any tokens.
256 * Note: If a relay's clock is ever 0, any new clients won't get a refill
257 * until the next second. But a relay that thinks it is 1970 will never
258 * validate the public consensus. */
259 if ((int64_t)now
== last_refill_ts
) {
263 /* At this point, we know we might need to add token to the bucket. We'll
264 * first get the circuit rate that is how many circuit are we allowed to do
266 circuit_rate
= get_circuit_rate_per_second();
268 /* We've never filled the bucket so fill it with the maximum being the burst
270 * Note: If a relay's clock is ever 0, all clients that were last refilled
271 * in that zero second will get a full refill here. */
272 if (last_refill_ts
== 0) {
273 num_token
= dos_cc_circuit_burst
;
277 /* Our clock jumped backward so fill it up to the maximum. Not filling it
278 * could trigger a detection for a valid client. Also, if the clock jumped
279 * negative but we didn't notice until the elapsed time became positive
280 * again, then we potentially spent many seconds not refilling the bucket
281 * when we should have been refilling it. But the fact that we didn't notice
282 * until now means that no circuit creation requests came in during that
283 * time, so the client doesn't end up punished that much from this hopefully
285 if ((int64_t)now
< last_refill_ts
) {
286 /* Use the maximum allowed value of token. */
287 num_token
= dos_cc_circuit_burst
;
291 /* How many seconds have elapsed between now and the last refill?
292 * This subtraction can't underflow, because now >= last_refill_ts.
293 * And it can't overflow, because INT64_MAX - (-INT64_MIN) == UINT64_MAX. */
294 elapsed_time_last_refill
= (uint64_t)now
- last_refill_ts
;
296 /* If the elapsed time is very large, it means our clock jumped forward.
297 * If the multiplication would overflow, use the maximum allowed value. */
298 if (elapsed_time_last_refill
> UINT32_MAX
) {
299 num_token
= dos_cc_circuit_burst
;
303 /* Compute how many circuits we are allowed in that time frame which we'll
304 * add to the bucket. This can't overflow, because both multiplicands
305 * are less than or equal to UINT32_MAX, and num_token is uint64_t. */
306 num_token
= elapsed_time_last_refill
* circuit_rate
;
309 /* If the sum would overflow, use the maximum allowed value. */
310 if (num_token
> UINT32_MAX
- stats
->circuit_bucket
) {
311 new_circuit_bucket_count
= dos_cc_circuit_burst
;
313 /* We cap the bucket to the burst value else this could overflow uint32_t
315 new_circuit_bucket_count
= MIN(stats
->circuit_bucket
+ (uint32_t)num_token
,
316 dos_cc_circuit_burst
);
319 /* This function is not allowed to make the bucket count larger than the
321 tor_assert_nonfatal(new_circuit_bucket_count
<= dos_cc_circuit_burst
);
322 /* This function is not allowed to make the bucket count smaller, unless it
323 * is decreasing it to a newly configured, lower burst value. We allow the
324 * bucket to stay the same size, in case the circuit rate is zero. */
325 tor_assert_nonfatal(new_circuit_bucket_count
>= stats
->circuit_bucket
||
326 new_circuit_bucket_count
== dos_cc_circuit_burst
);
328 log_debug(LD_DOS
, "DoS address %s has its circuit bucket value: %" PRIu32
329 ". Filling it to %" PRIu32
". Circuit rate is %" PRIu64
330 ". Elapsed time is %" PRIi64
,
331 fmt_addr(addr
), stats
->circuit_bucket
, new_circuit_bucket_count
,
332 circuit_rate
, (int64_t)elapsed_time_last_refill
);
334 stats
->circuit_bucket
= new_circuit_bucket_count
;
335 stats
->last_circ_bucket_refill_ts
= now
;
341 /* Return true iff the circuit bucket is down to 0 and the number of
342 * concurrent connections is greater or equal the minimum threshold set the
343 * consensus parameter. */
345 cc_has_exhausted_circuits(const dos_client_stats_t
*stats
)
348 return stats
->cc_stats
.circuit_bucket
== 0 &&
349 stats
->concurrent_count
>= dos_cc_min_concurrent_conn
;
352 /* Mark client address by setting a timestamp in the stats object which tells
353 * us until when it is marked as positively detected. */
355 cc_mark_client(cc_client_stats_t
*stats
)
358 /* We add a random offset of a maximum of half the defense time so it is
359 * less predictable. */
360 stats
->marked_until_ts
=
361 approx_time() + dos_cc_defense_time_period
+
362 crypto_rand_int_range(1, dos_cc_defense_time_period
/ 2);
365 /* Return true iff the given channel address is marked as malicious. This is
366 * called a lot and part of the fast path of handling cells. It has to remain
367 * as fast as we can. */
369 cc_channel_addr_is_marked(channel_t
*chan
)
373 clientmap_entry_t
*entry
;
374 cc_client_stats_t
*stats
= NULL
;
379 /* Must be a client connection else we ignore. */
380 if (!channel_is_client(chan
)) {
383 /* Without an IP address, nothing can work. */
384 if (!channel_get_addr_if_possible(chan
, &addr
)) {
388 /* We are only interested in client connection from the geoip cache. */
389 entry
= geoip_lookup_client(&addr
, NULL
, GEOIP_CLIENT_CONNECT
);
391 /* We can have a connection creating circuits but not tracked by the geoip
392 * cache. Once this DoS subsystem is enabled, we can end up here with no
393 * entry for the channel. */
397 stats
= &entry
->dos_stats
.cc_stats
;
400 return stats
&& stats
->marked_until_ts
>= now
;
403 /* Concurrent connection private API. */
405 /* Free everything for the connection DoS mitigation subsystem. */
409 dos_conn_enabled
= 0;
412 /* Called when the consensus has changed. Do appropriate actions for the
413 * connection mitigation subsystem. */
415 conn_consensus_has_changed(const networkstatus_t
*ns
)
417 /* Looking at the consensus, is the connection mitigation subsystem enabled?
418 * If not and it was enabled before, clean it up. */
419 if (dos_conn_enabled
&& !get_param_conn_enabled(ns
)) {
424 /* General private API */
426 /* Return true iff we have at least one DoS detection enabled. This is used to
427 * decide if we need to allocate any kind of high level DoS object. */
431 return (dos_cc_enabled
|| dos_conn_enabled
);
434 /* Circuit creation public API. */
436 /* Called when a CREATE cell is received from the given channel. */
438 dos_cc_new_create_cell(channel_t
*chan
)
441 clientmap_entry_t
*entry
;
445 /* Skip everything if not enabled. */
446 if (!dos_cc_enabled
) {
450 /* Must be a client connection else we ignore. */
451 if (!channel_is_client(chan
)) {
454 /* Without an IP address, nothing can work. */
455 if (!channel_get_addr_if_possible(chan
, &addr
)) {
459 /* We are only interested in client connection from the geoip cache. */
460 entry
= geoip_lookup_client(&addr
, NULL
, GEOIP_CLIENT_CONNECT
);
462 /* We can have a connection creating circuits but not tracked by the geoip
463 * cache. Once this DoS subsystem is enabled, we can end up here with no
464 * entry for the channel. */
468 /* General comment. Even though the client can already be marked as
469 * malicious, we continue to track statistics. If it keeps going above
470 * threshold while marked, the defense period time will grow longer. There
471 * is really no point at unmarking a client that keeps DoSing us. */
473 /* First of all, we'll try to refill the circuit bucket opportunistically
474 * before we assess. */
475 cc_stats_refill_bucket(&entry
->dos_stats
.cc_stats
, &addr
);
477 /* Take a token out of the circuit bucket if we are above 0 so we don't
478 * underflow the bucket. */
479 if (entry
->dos_stats
.cc_stats
.circuit_bucket
> 0) {
480 entry
->dos_stats
.cc_stats
.circuit_bucket
--;
483 /* This is the detection. Assess at every CREATE cell if the client should
484 * get marked as malicious. This should be kept as fast as possible. */
485 if (cc_has_exhausted_circuits(&entry
->dos_stats
)) {
486 /* If this is the first time we mark this entry, log it a info level.
487 * Under heavy DDoS, logging each time we mark would results in lots and
489 if (entry
->dos_stats
.cc_stats
.marked_until_ts
== 0) {
490 log_debug(LD_DOS
, "Detected circuit creation DoS by address: %s",
492 cc_num_marked_addrs
++;
494 cc_mark_client(&entry
->dos_stats
.cc_stats
);
501 /* Return the defense type that should be used for this circuit.
503 * This is part of the fast path and called a lot. */
504 dos_cc_defense_type_t
505 dos_cc_get_defense_type(channel_t
*chan
)
509 /* Skip everything if not enabled. */
510 if (!dos_cc_enabled
) {
514 /* On an OR circuit, we'll check if the previous channel is a marked client
515 * connection detected by our DoS circuit creation mitigation subsystem. */
516 if (cc_channel_addr_is_marked(chan
)) {
517 /* We've just assess that this circuit should trigger a defense for the
518 * cell it just seen. Note it down. */
519 cc_num_rejected_cells
++;
520 return dos_cc_defense_type
;
524 return DOS_CC_DEFENSE_NONE
;
527 /* Concurrent connection detection public API. */
529 /* Return true iff the given address is permitted to open another connection.
530 * A defense value is returned for the caller to take appropriate actions. */
531 dos_conn_defense_type_t
532 dos_conn_addr_get_defense_type(const tor_addr_t
*addr
)
534 clientmap_entry_t
*entry
;
538 /* Skip everything if not enabled. */
539 if (!dos_conn_enabled
) {
543 /* We are only interested in client connection from the geoip cache. */
544 entry
= geoip_lookup_client(addr
, NULL
, GEOIP_CLIENT_CONNECT
);
549 /* Need to be above the maximum concurrent connection count to trigger a
551 if (entry
->dos_stats
.concurrent_count
> dos_conn_max_concurrent_count
) {
552 conn_num_addr_rejected
++;
553 return dos_conn_defense_type
;
557 return DOS_CONN_DEFENSE_NONE
;
562 /* Take any appropriate actions for the given geoip entry that is about to get
563 * freed. This is called for every entry that is being freed.
565 * This function will clear out the connection tracked flag if the concurrent
566 * count of the entry is above 0 so if those connections end up being seen by
567 * this subsystem, we won't try to decrement the counter for a new geoip entry
568 * that might have been added after this call for the same address. */
570 dos_geoip_entry_about_to_free(const clientmap_entry_t
*geoip_ent
)
572 tor_assert(geoip_ent
);
574 /* The count is down to 0 meaning no connections right now, we can safely
575 * clear the geoip entry from the cache. */
576 if (geoip_ent
->dos_stats
.concurrent_count
== 0) {
580 /* For each connection matching the geoip entry address, we'll clear the
581 * tracked flag because the entry is about to get removed from the geoip
582 * cache. We do not try to decrement if the flag is not set. */
583 SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t
*, conn
) {
584 if (conn
->type
== CONN_TYPE_OR
) {
585 or_connection_t
*or_conn
= TO_OR_CONN(conn
);
586 if (!tor_addr_compare(&geoip_ent
->addr
, &or_conn
->real_addr
,
588 or_conn
->tracked_for_dos_mitigation
= 0;
591 } SMARTLIST_FOREACH_END(conn
);
597 /* Note down that we've just refused a single hop client. This increments a
598 * counter later used for the heartbeat. */
600 dos_note_refuse_single_hop_client(void)
602 num_single_hop_client_refused
++;
605 /* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should
608 dos_should_refuse_single_hop_client(void)
610 /* If we aren't a public relay, this shouldn't apply to anything. */
611 if (!public_server_mode(get_options())) {
615 if (get_options()->DoSRefuseSingleHopClientRendezvous
!= -1) {
616 return get_options()->DoSRefuseSingleHopClientRendezvous
;
619 return (int) networkstatus_get_param(NULL
,
620 "DoSRefuseSingleHopClientRendezvous",
621 0 /* default */, 0, 1);
624 /* Log a heartbeat message with some statistics. */
626 dos_log_heartbeat(void)
628 char *conn_msg
= NULL
;
630 char *single_hop_client_msg
= NULL
;
631 char *circ_stats_msg
= NULL
;
633 /* Stats number coming from relay.c append_cell_to_circuit_queue(). */
634 tor_asprintf(&circ_stats_msg
,
635 " %" PRIu64
" circuits killed with too many cells.",
636 stats_n_circ_max_cell_reached
);
638 if (dos_cc_enabled
) {
639 tor_asprintf(&cc_msg
,
640 " %" PRIu64
" circuits rejected,"
641 " %" PRIu32
" marked addresses.",
642 cc_num_rejected_cells
, cc_num_marked_addrs
);
645 if (dos_conn_enabled
) {
646 tor_asprintf(&conn_msg
,
647 " %" PRIu64
" connections closed.",
648 conn_num_addr_rejected
);
651 if (dos_should_refuse_single_hop_client()) {
652 tor_asprintf(&single_hop_client_msg
,
653 " %" PRIu64
" single hop clients refused.",
654 num_single_hop_client_refused
);
657 log_notice(LD_HEARTBEAT
,
658 "DoS mitigation since startup:%s%s%s%s",
660 (cc_msg
!= NULL
) ? cc_msg
: " [cc not enabled]",
661 (conn_msg
!= NULL
) ? conn_msg
: " [conn not enabled]",
662 (single_hop_client_msg
!= NULL
) ? single_hop_client_msg
: "");
666 tor_free(single_hop_client_msg
);
667 tor_free(circ_stats_msg
);
671 /* Called when a new client connection has been established on the given
674 dos_new_client_conn(or_connection_t
*or_conn
)
676 clientmap_entry_t
*entry
;
680 /* Past that point, we know we have at least one DoS detection subsystem
681 * enabled so we'll start allocating stuff. */
682 if (!dos_is_enabled()) {
686 /* We ignore any known address meaning an address of a known relay. The
687 * reason to do so is because network reentry is possible where a client
688 * connection comes from an Exit node. Even when we'll fix reentry, this is
689 * a robust defense to keep in place. */
690 if (nodelist_probably_contains_address(&or_conn
->real_addr
)) {
694 /* We are only interested in client connection from the geoip cache. */
695 entry
= geoip_lookup_client(&or_conn
->real_addr
, NULL
,
696 GEOIP_CLIENT_CONNECT
);
697 if (BUG(entry
== NULL
)) {
698 /* Should never happen because we note down the address in the geoip
699 * cache before this is called. */
703 entry
->dos_stats
.concurrent_count
++;
704 or_conn
->tracked_for_dos_mitigation
= 1;
705 log_debug(LD_DOS
, "Client address %s has now %u concurrent connections.",
706 fmt_addr(&or_conn
->real_addr
),
707 entry
->dos_stats
.concurrent_count
);
713 /* Called when a client connection for the given IP address has been closed. */
715 dos_close_client_conn(const or_connection_t
*or_conn
)
717 clientmap_entry_t
*entry
;
721 /* We have to decrement the count on tracked connection only even if the
722 * subsystem has been disabled at runtime because it might be re-enabled
723 * after and we need to keep a synchronized counter at all time. */
724 if (!or_conn
->tracked_for_dos_mitigation
) {
728 /* We are only interested in client connection from the geoip cache. */
729 entry
= geoip_lookup_client(&or_conn
->real_addr
, NULL
,
730 GEOIP_CLIENT_CONNECT
);
732 /* This can happen because we can close a connection before the channel
733 * got to be noted down in the geoip cache. */
737 /* Extra super duper safety. Going below 0 means an underflow which could
738 * lead to most likely a false positive. In theory, this should never happen
739 * but lets be extra safe. */
740 if (BUG(entry
->dos_stats
.concurrent_count
== 0)) {
744 entry
->dos_stats
.concurrent_count
--;
745 log_debug(LD_DOS
, "Client address %s has lost a connection. Concurrent "
746 "connections are now at %u",
747 fmt_addr(&or_conn
->real_addr
),
748 entry
->dos_stats
.concurrent_count
);
754 /* Called when the consensus has changed. We might have new consensus
755 * parameters to look at. */
757 dos_consensus_has_changed(const networkstatus_t
*ns
)
759 /* There are two ways to configure this subsystem, one at startup through
760 * dos_init() which is called when the options are parsed. And this one
761 * through the consensus. We don't want to enable any DoS mitigation if we
762 * aren't a public relay. */
763 if (!public_server_mode(get_options())) {
767 cc_consensus_has_changed(ns
);
768 conn_consensus_has_changed(ns
);
770 /* We were already enabled or we just became enabled but either way, set the
771 * consensus parameters for all subsystems. */
772 set_dos_parameters(ns
);
775 /* Return true iff the DoS mitigation subsystem is enabled. */
779 return dos_is_enabled();
782 /* Free everything from the Denial of Service subsystem. */
786 /* Free the circuit creation mitigation subsystem. It is safe to do this
787 * even if it wasn't initialized. */
790 /* Free the connection mitigation subsystem. It is safe to do this even if
791 * it wasn't initialized. */
795 /* Initialize the Denial of Service subsystem. */
799 /* To initialize, we only need to get the parameters. */
800 set_dos_parameters(NULL
);