Tor  0.4.3.0-alpha-dev
dos.c
1 /* Copyright (c) 2018-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
4 /*
5  * \file dos.c
6  * \brief Implement Denial of Service mitigation subsystem.
7  */
8 
9 #define DOS_PRIVATE
10 
11 #include "core/or/or.h"
12 #include "app/config/config.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"
24 
25 #include "core/or/dos.h"
26 
28 
29 /*
30  * Circuit creation denial of service mitigation.
31  *
32  * Namespace used for this mitigation framework is "dos_cc_" where "cc" is for
33  * Circuit Creation.
34  */
35 
36 /* Is the circuit creation DoS mitigation enabled? */
37 static unsigned int dos_cc_enabled = 0;
38 
39 /* Consensus parameters. They can be changed when a new consensus arrives.
40  * They are initialized with the hardcoded default values. */
41 static uint32_t dos_cc_min_concurrent_conn;
42 static uint32_t dos_cc_circuit_rate;
43 static uint32_t dos_cc_circuit_burst;
44 static dos_cc_defense_type_t dos_cc_defense_type;
45 static int32_t dos_cc_defense_time_period;
46 
47 /* Keep some stats for the heartbeat so we can report out. */
48 static uint64_t cc_num_rejected_cells;
49 static uint32_t cc_num_marked_addrs;
50 
51 /*
52  * Concurrent connection denial of service mitigation.
53  *
54  * Namespace used for this mitigation framework is "dos_conn_".
55  */
56 
57 /* Is the connection DoS mitigation enabled? */
58 static unsigned int dos_conn_enabled = 0;
59 
60 /* Consensus parameters. They can be changed when a new consensus arrives.
61  * They are initialized with the hardcoded default values. */
62 static uint32_t dos_conn_max_concurrent_count;
63 static dos_conn_defense_type_t dos_conn_defense_type;
64 
65 /* Keep some stats for the heartbeat so we can report out. */
66 static uint64_t conn_num_addr_rejected;
67 
68 /*
69  * General interface of the denial of service mitigation subsystem.
70  */
71 
72 /* Keep stats for the heartbeat. */
73 static uint64_t num_single_hop_client_refused;
74 
75 /* Return true iff the circuit creation mitigation is enabled. We look at the
76  * consensus for this else a default value is returned. */
77 MOCK_IMPL(STATIC unsigned int,
78 get_param_cc_enabled, (const networkstatus_t *ns))
79 {
80  if (get_options()->DoSCircuitCreationEnabled != -1) {
82  }
83 
84  return !!networkstatus_get_param(ns, "DoSCircuitCreationEnabled",
85  DOS_CC_ENABLED_DEFAULT, 0, 1);
86 }
87 
88 /* Return the parameter for the minimum concurrent connection at which we'll
89  * start counting circuit for a specific client address. */
90 STATIC uint32_t
91 get_param_cc_min_concurrent_connection(const networkstatus_t *ns)
92 {
93  if (get_options()->DoSCircuitCreationMinConnections) {
95  }
96  return networkstatus_get_param(ns, "DoSCircuitCreationMinConnections",
97  DOS_CC_MIN_CONCURRENT_CONN_DEFAULT,
98  1, INT32_MAX);
99 }
100 
101 /* Return the parameter for the time rate that is how many circuits over this
102  * time span. */
103 static uint32_t
104 get_param_cc_circuit_rate(const networkstatus_t *ns)
105 {
106  /* This is in seconds. */
107  if (get_options()->DoSCircuitCreationRate) {
109  }
110  return networkstatus_get_param(ns, "DoSCircuitCreationRate",
111  DOS_CC_CIRCUIT_RATE_DEFAULT,
112  1, INT32_MAX);
113 }
114 
115 /* Return the parameter for the maximum circuit count for the circuit time
116  * rate. */
117 STATIC uint32_t
118 get_param_cc_circuit_burst(const networkstatus_t *ns)
119 {
120  if (get_options()->DoSCircuitCreationBurst) {
122  }
123  return networkstatus_get_param(ns, "DoSCircuitCreationBurst",
124  DOS_CC_CIRCUIT_BURST_DEFAULT,
125  1, INT32_MAX);
126 }
127 
128 /* Return the consensus parameter of the circuit creation defense type. */
129 static uint32_t
130 get_param_cc_defense_type(const networkstatus_t *ns)
131 {
132  if (get_options()->DoSCircuitCreationDefenseType) {
134  }
135  return networkstatus_get_param(ns, "DoSCircuitCreationDefenseType",
136  DOS_CC_DEFENSE_TYPE_DEFAULT,
137  DOS_CC_DEFENSE_NONE, DOS_CC_DEFENSE_MAX);
138 }
139 
140 /* Return the consensus parameter of the defense time period which is how much
141  * time should we defend against a malicious client address. */
142 static int32_t
143 get_param_cc_defense_time_period(const networkstatus_t *ns)
144 {
145  /* Time in seconds. */
146  if (get_options()->DoSCircuitCreationDefenseTimePeriod) {
148  }
149  return networkstatus_get_param(ns, "DoSCircuitCreationDefenseTimePeriod",
150  DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT,
151  0, INT32_MAX);
152 }
153 
154 /* Return true iff connection mitigation is enabled. We look at the consensus
155  * for this else a default value is returned. */
156 MOCK_IMPL(STATIC unsigned int,
157 get_param_conn_enabled, (const networkstatus_t *ns))
158 {
159  if (get_options()->DoSConnectionEnabled != -1) {
161  }
162  return !!networkstatus_get_param(ns, "DoSConnectionEnabled",
163  DOS_CONN_ENABLED_DEFAULT, 0, 1);
164 }
165 
166 /* Return the consensus parameter for the maximum concurrent connection
167  * allowed. */
168 STATIC uint32_t
169 get_param_conn_max_concurrent_count(const networkstatus_t *ns)
170 {
171  if (get_options()->DoSConnectionMaxConcurrentCount) {
173  }
174  return networkstatus_get_param(ns, "DoSConnectionMaxConcurrentCount",
175  DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT,
176  1, INT32_MAX);
177 }
178 
179 /* Return the consensus parameter of the connection defense type. */
180 static uint32_t
181 get_param_conn_defense_type(const networkstatus_t *ns)
182 {
183  if (get_options()->DoSConnectionDefenseType) {
185  }
186  return networkstatus_get_param(ns, "DoSConnectionDefenseType",
187  DOS_CONN_DEFENSE_TYPE_DEFAULT,
188  DOS_CONN_DEFENSE_NONE, DOS_CONN_DEFENSE_MAX);
189 }
190 
191 /* Set circuit creation parameters located in the consensus or their default
192  * if none are present. Called at initialization or when the consensus
193  * changes. */
194 static void
195 set_dos_parameters(const networkstatus_t *ns)
196 {
197  /* Get the default consensus param values. */
198  dos_cc_enabled = get_param_cc_enabled(ns);
199  dos_cc_min_concurrent_conn = get_param_cc_min_concurrent_connection(ns);
200  dos_cc_circuit_rate = get_param_cc_circuit_rate(ns);
201  dos_cc_circuit_burst = get_param_cc_circuit_burst(ns);
202  dos_cc_defense_time_period = get_param_cc_defense_time_period(ns);
203  dos_cc_defense_type = get_param_cc_defense_type(ns);
204 
205  /* Connection detection. */
206  dos_conn_enabled = get_param_conn_enabled(ns);
207  dos_conn_max_concurrent_count = get_param_conn_max_concurrent_count(ns);
208  dos_conn_defense_type = get_param_conn_defense_type(ns);
209 }
210 
211 /* Free everything for the circuit creation DoS mitigation subsystem. */
212 static void
213 cc_free_all(void)
214 {
215  /* If everything is freed, the circuit creation subsystem is not enabled. */
216  dos_cc_enabled = 0;
217 }
218 
219 /* Called when the consensus has changed. Do appropriate actions for the
220  * circuit creation subsystem. */
221 static void
222 cc_consensus_has_changed(const networkstatus_t *ns)
223 {
224  /* Looking at the consensus, is the circuit creation subsystem enabled? If
225  * not and it was enabled before, clean it up. */
226  if (dos_cc_enabled && !get_param_cc_enabled(ns)) {
227  cc_free_all();
228  }
229 }
230 
231 /** Return the number of circuits we allow per second under the current
232  * configuration. */
233 STATIC uint64_t
234 get_circuit_rate_per_second(void)
235 {
236  return dos_cc_circuit_rate;
237 }
238 
239 /* Given the circuit creation client statistics object, refill the circuit
240  * bucket if needed. This also works if the bucket was never filled in the
241  * first place. The addr is only used for logging purposes. */
242 STATIC void
243 cc_stats_refill_bucket(cc_client_stats_t *stats, const tor_addr_t *addr)
244 {
245  uint32_t new_circuit_bucket_count;
246  uint64_t num_token, elapsed_time_last_refill = 0, circuit_rate = 0;
247  time_t now;
248  int64_t last_refill_ts;
249 
250  tor_assert(stats);
251  tor_assert(addr);
252 
253  now = approx_time();
254  last_refill_ts = (int64_t)stats->last_circ_bucket_refill_ts;
255 
256  /* If less than a second has elapsed, don't add any tokens.
257  * Note: If a relay's clock is ever 0, any new clients won't get a refill
258  * until the next second. But a relay that thinks it is 1970 will never
259  * validate the public consensus. */
260  if ((int64_t)now == last_refill_ts) {
261  goto done;
262  }
263 
264  /* At this point, we know we might need to add token to the bucket. We'll
265  * first get the circuit rate that is how many circuit are we allowed to do
266  * per second. */
267  circuit_rate = get_circuit_rate_per_second();
268 
269  /* We've never filled the bucket so fill it with the maximum being the burst
270  * and we are done.
271  * Note: If a relay's clock is ever 0, all clients that were last refilled
272  * in that zero second will get a full refill here. */
273  if (last_refill_ts == 0) {
274  num_token = dos_cc_circuit_burst;
275  goto end;
276  }
277 
278  /* Our clock jumped backward so fill it up to the maximum. Not filling it
279  * could trigger a detection for a valid client. Also, if the clock jumped
280  * negative but we didn't notice until the elapsed time became positive
281  * again, then we potentially spent many seconds not refilling the bucket
282  * when we should have been refilling it. But the fact that we didn't notice
283  * until now means that no circuit creation requests came in during that
284  * time, so the client doesn't end up punished that much from this hopefully
285  * rare situation.*/
286  if ((int64_t)now < last_refill_ts) {
287  /* Use the maximum allowed value of token. */
288  num_token = dos_cc_circuit_burst;
289  goto end;
290  }
291 
292  /* How many seconds have elapsed between now and the last refill?
293  * This subtraction can't underflow, because now >= last_refill_ts.
294  * And it can't overflow, because INT64_MAX - (-INT64_MIN) == UINT64_MAX. */
295  elapsed_time_last_refill = (uint64_t)now - last_refill_ts;
296 
297  /* If the elapsed time is very large, it means our clock jumped forward.
298  * If the multiplication would overflow, use the maximum allowed value. */
299  if (elapsed_time_last_refill > UINT32_MAX) {
300  num_token = dos_cc_circuit_burst;
301  goto end;
302  }
303 
304  /* Compute how many circuits we are allowed in that time frame which we'll
305  * add to the bucket. This can't overflow, because both multiplicands
306  * are less than or equal to UINT32_MAX, and num_token is uint64_t. */
307  num_token = elapsed_time_last_refill * circuit_rate;
308 
309  end:
310  /* If the sum would overflow, use the maximum allowed value. */
311  if (num_token > UINT32_MAX - stats->circuit_bucket) {
312  new_circuit_bucket_count = dos_cc_circuit_burst;
313  } else {
314  /* We cap the bucket to the burst value else this could overflow uint32_t
315  * over time. */
316  new_circuit_bucket_count = MIN(stats->circuit_bucket + (uint32_t)num_token,
317  dos_cc_circuit_burst);
318  }
319 
320  /* This function is not allowed to make the bucket count larger than the
321  * burst value */
322  tor_assert_nonfatal(new_circuit_bucket_count <= dos_cc_circuit_burst);
323  /* This function is not allowed to make the bucket count smaller, unless it
324  * is decreasing it to a newly configured, lower burst value. We allow the
325  * bucket to stay the same size, in case the circuit rate is zero. */
326  tor_assert_nonfatal(new_circuit_bucket_count >= stats->circuit_bucket ||
327  new_circuit_bucket_count == dos_cc_circuit_burst);
328 
329  log_debug(LD_DOS, "DoS address %s has its circuit bucket value: %" PRIu32
330  ". Filling it to %" PRIu32 ". Circuit rate is %" PRIu64
331  ". Elapsed time is %" PRIi64,
332  fmt_addr(addr), stats->circuit_bucket, new_circuit_bucket_count,
333  circuit_rate, (int64_t)elapsed_time_last_refill);
334 
335  stats->circuit_bucket = new_circuit_bucket_count;
336  stats->last_circ_bucket_refill_ts = now;
337 
338  done:
339  return;
340 }
341 
342 /* Return true iff the circuit bucket is down to 0 and the number of
343  * concurrent connections is greater or equal the minimum threshold set the
344  * consensus parameter. */
345 static int
346 cc_has_exhausted_circuits(const dos_client_stats_t *stats)
347 {
348  tor_assert(stats);
349  return stats->cc_stats.circuit_bucket == 0 &&
350  stats->concurrent_count >= dos_cc_min_concurrent_conn;
351 }
352 
353 /* Mark client address by setting a timestamp in the stats object which tells
354  * us until when it is marked as positively detected. */
355 static void
356 cc_mark_client(cc_client_stats_t *stats)
357 {
358  tor_assert(stats);
359  /* We add a random offset of a maximum of half the defense time so it is
360  * less predictable. */
361  stats->marked_until_ts =
362  approx_time() + dos_cc_defense_time_period +
363  crypto_rand_int_range(1, dos_cc_defense_time_period / 2);
364 }
365 
366 /* Return true iff the given channel address is marked as malicious. This is
367  * called a lot and part of the fast path of handling cells. It has to remain
368  * as fast as we can. */
369 static int
370 cc_channel_addr_is_marked(channel_t *chan)
371 {
372  time_t now;
373  tor_addr_t addr;
374  clientmap_entry_t *entry;
375  cc_client_stats_t *stats = NULL;
376 
377  if (chan == NULL) {
378  goto end;
379  }
380  /* Must be a client connection else we ignore. */
381  if (!channel_is_client(chan)) {
382  goto end;
383  }
384  /* Without an IP address, nothing can work. */
385  if (!channel_get_addr_if_possible(chan, &addr)) {
386  goto end;
387  }
388 
389  /* We are only interested in client connection from the geoip cache. */
390  entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
391  if (entry == NULL) {
392  /* We can have a connection creating circuits but not tracked by the geoip
393  * cache. Once this DoS subsystem is enabled, we can end up here with no
394  * entry for the channel. */
395  goto end;
396  }
397  now = approx_time();
398  stats = &entry->dos_stats.cc_stats;
399 
400  end:
401  return stats && stats->marked_until_ts >= now;
402 }
403 
404 /* Concurrent connection private API. */
405 
406 /* Free everything for the connection DoS mitigation subsystem. */
407 static void
408 conn_free_all(void)
409 {
410  dos_conn_enabled = 0;
411 }
412 
413 /* Called when the consensus has changed. Do appropriate actions for the
414  * connection mitigation subsystem. */
415 static void
416 conn_consensus_has_changed(const networkstatus_t *ns)
417 {
418  /* Looking at the consensus, is the connection mitigation subsystem enabled?
419  * If not and it was enabled before, clean it up. */
420  if (dos_conn_enabled && !get_param_conn_enabled(ns)) {
421  conn_free_all();
422  }
423 }
424 
425 /* General private API */
426 
427 /* Return true iff we have at least one DoS detection enabled. This is used to
428  * decide if we need to allocate any kind of high level DoS object. */
429 static inline int
430 dos_is_enabled(void)
431 {
432  return (dos_cc_enabled || dos_conn_enabled);
433 }
434 
435 /* Circuit creation public API. */
436 
437 /* Called when a CREATE cell is received from the given channel. */
438 void
439 dos_cc_new_create_cell(channel_t *chan)
440 {
441  tor_addr_t addr;
442  clientmap_entry_t *entry;
443 
444  tor_assert(chan);
445 
446  /* Skip everything if not enabled. */
447  if (!dos_cc_enabled) {
448  goto end;
449  }
450 
451  /* Must be a client connection else we ignore. */
452  if (!channel_is_client(chan)) {
453  goto end;
454  }
455  /* Without an IP address, nothing can work. */
456  if (!channel_get_addr_if_possible(chan, &addr)) {
457  goto end;
458  }
459 
460  /* We are only interested in client connection from the geoip cache. */
461  entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
462  if (entry == NULL) {
463  /* We can have a connection creating circuits but not tracked by the geoip
464  * cache. Once this DoS subsystem is enabled, we can end up here with no
465  * entry for the channel. */
466  goto end;
467  }
468 
469  /* General comment. Even though the client can already be marked as
470  * malicious, we continue to track statistics. If it keeps going above
471  * threshold while marked, the defense period time will grow longer. There
472  * is really no point at unmarking a client that keeps DoSing us. */
473 
474  /* First of all, we'll try to refill the circuit bucket opportunistically
475  * before we assess. */
476  cc_stats_refill_bucket(&entry->dos_stats.cc_stats, &addr);
477 
478  /* Take a token out of the circuit bucket if we are above 0 so we don't
479  * underflow the bucket. */
480  if (entry->dos_stats.cc_stats.circuit_bucket > 0) {
481  entry->dos_stats.cc_stats.circuit_bucket--;
482  }
483 
484  /* This is the detection. Assess at every CREATE cell if the client should
485  * get marked as malicious. This should be kept as fast as possible. */
486  if (cc_has_exhausted_circuits(&entry->dos_stats)) {
487  /* If this is the first time we mark this entry, log it a info level.
488  * Under heavy DDoS, logging each time we mark would results in lots and
489  * lots of logs. */
490  if (entry->dos_stats.cc_stats.marked_until_ts == 0) {
491  log_debug(LD_DOS, "Detected circuit creation DoS by address: %s",
492  fmt_addr(&addr));
493  cc_num_marked_addrs++;
494  }
495  cc_mark_client(&entry->dos_stats.cc_stats);
496  }
497 
498  end:
499  return;
500 }
501 
502 /* Return the defense type that should be used for this circuit.
503  *
504  * This is part of the fast path and called a lot. */
505 dos_cc_defense_type_t
506 dos_cc_get_defense_type(channel_t *chan)
507 {
508  tor_assert(chan);
509 
510  /* Skip everything if not enabled. */
511  if (!dos_cc_enabled) {
512  goto end;
513  }
514 
515  /* On an OR circuit, we'll check if the previous channel is a marked client
516  * connection detected by our DoS circuit creation mitigation subsystem. */
517  if (cc_channel_addr_is_marked(chan)) {
518  /* We've just assess that this circuit should trigger a defense for the
519  * cell it just seen. Note it down. */
520  cc_num_rejected_cells++;
521  return dos_cc_defense_type;
522  }
523 
524  end:
525  return DOS_CC_DEFENSE_NONE;
526 }
527 
528 /* Concurrent connection detection public API. */
529 
530 /* Return true iff the given address is permitted to open another connection.
531  * A defense value is returned for the caller to take appropriate actions. */
532 dos_conn_defense_type_t
533 dos_conn_addr_get_defense_type(const tor_addr_t *addr)
534 {
535  clientmap_entry_t *entry;
536 
537  tor_assert(addr);
538 
539  /* Skip everything if not enabled. */
540  if (!dos_conn_enabled) {
541  goto end;
542  }
543 
544  /* We are only interested in client connection from the geoip cache. */
545  entry = geoip_lookup_client(addr, NULL, GEOIP_CLIENT_CONNECT);
546  if (entry == NULL) {
547  goto end;
548  }
549 
550  /* Need to be above the maximum concurrent connection count to trigger a
551  * defense. */
552  if (entry->dos_stats.concurrent_count > dos_conn_max_concurrent_count) {
553  conn_num_addr_rejected++;
554  return dos_conn_defense_type;
555  }
556 
557  end:
558  return DOS_CONN_DEFENSE_NONE;
559 }
560 
561 /* General API */
562 
563 /* Take any appropriate actions for the given geoip entry that is about to get
564  * freed. This is called for every entry that is being freed.
565  *
566  * This function will clear out the connection tracked flag if the concurrent
567  * count of the entry is above 0 so if those connections end up being seen by
568  * this subsystem, we won't try to decrement the counter for a new geoip entry
569  * that might have been added after this call for the same address. */
570 void
571 dos_geoip_entry_about_to_free(const clientmap_entry_t *geoip_ent)
572 {
573  tor_assert(geoip_ent);
574 
575  /* The count is down to 0 meaning no connections right now, we can safely
576  * clear the geoip entry from the cache. */
577  if (geoip_ent->dos_stats.concurrent_count == 0) {
578  goto end;
579  }
580 
581  /* For each connection matching the geoip entry address, we'll clear the
582  * tracked flag because the entry is about to get removed from the geoip
583  * cache. We do not try to decrement if the flag is not set. */
585  if (conn->type == CONN_TYPE_OR) {
586  or_connection_t *or_conn = TO_OR_CONN(conn);
587  if (!tor_addr_compare(&geoip_ent->addr, &or_conn->real_addr,
588  CMP_EXACT)) {
589  or_conn->tracked_for_dos_mitigation = 0;
590  }
591  }
592  } SMARTLIST_FOREACH_END(conn);
593 
594  end:
595  return;
596 }
597 
598 /* Note down that we've just refused a single hop client. This increments a
599  * counter later used for the heartbeat. */
600 void
601 dos_note_refuse_single_hop_client(void)
602 {
603  num_single_hop_client_refused++;
604 }
605 
606 /* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should
607  * be refused. */
608 int
609 dos_should_refuse_single_hop_client(void)
610 {
611  /* If we aren't a public relay, this shouldn't apply to anything. */
613  return 0;
614  }
615 
616  if (get_options()->DoSRefuseSingleHopClientRendezvous != -1) {
618  }
619 
620  return (int) networkstatus_get_param(NULL,
621  "DoSRefuseSingleHopClientRendezvous",
622  0 /* default */, 0, 1);
623 }
624 
625 /* Log a heartbeat message with some statistics. */
626 void
627 dos_log_heartbeat(void)
628 {
629  char *conn_msg = NULL;
630  char *cc_msg = NULL;
631  char *single_hop_client_msg = NULL;
632  char *circ_stats_msg = NULL;
633  char *hs_dos_intro2_msg = NULL;
634 
635  /* Stats number coming from relay.c append_cell_to_circuit_queue(). */
636  tor_asprintf(&circ_stats_msg,
637  " %" PRIu64 " circuits killed with too many cells.",
639 
640  if (dos_cc_enabled) {
641  tor_asprintf(&cc_msg,
642  " %" PRIu64 " circuits rejected,"
643  " %" PRIu32 " marked addresses.",
644  cc_num_rejected_cells, cc_num_marked_addrs);
645  }
646 
647  if (dos_conn_enabled) {
648  tor_asprintf(&conn_msg,
649  " %" PRIu64 " connections closed.",
650  conn_num_addr_rejected);
651  }
652 
653  if (dos_should_refuse_single_hop_client()) {
654  tor_asprintf(&single_hop_client_msg,
655  " %" PRIu64 " single hop clients refused.",
656  num_single_hop_client_refused);
657  }
658 
659  /* HS DoS stats. */
660  tor_asprintf(&hs_dos_intro2_msg,
661  " %" PRIu64 " INTRODUCE2 rejected.",
663 
664  log_notice(LD_HEARTBEAT,
665  "DoS mitigation since startup:%s%s%s%s%s",
666  circ_stats_msg,
667  (cc_msg != NULL) ? cc_msg : " [cc not enabled]",
668  (conn_msg != NULL) ? conn_msg : " [conn not enabled]",
669  (single_hop_client_msg != NULL) ? single_hop_client_msg : "",
670  (hs_dos_intro2_msg != NULL) ? hs_dos_intro2_msg : "");
671 
672  tor_free(conn_msg);
673  tor_free(cc_msg);
674  tor_free(single_hop_client_msg);
675  tor_free(circ_stats_msg);
676  tor_free(hs_dos_intro2_msg);
677  return;
678 }
679 
680 /* Called when a new client connection has been established on the given
681  * address. */
682 void
683 dos_new_client_conn(or_connection_t *or_conn)
684 {
685  clientmap_entry_t *entry;
686 
687  tor_assert(or_conn);
688 
689  /* Past that point, we know we have at least one DoS detection subsystem
690  * enabled so we'll start allocating stuff. */
691  if (!dos_is_enabled()) {
692  goto end;
693  }
694 
695  /* We ignore any known address meaning an address of a known relay. The
696  * reason to do so is because network reentry is possible where a client
697  * connection comes from an Exit node. Even when we'll fix reentry, this is
698  * a robust defense to keep in place. */
700  goto end;
701  }
702 
703  /* We are only interested in client connection from the geoip cache. */
704  entry = geoip_lookup_client(&or_conn->real_addr, NULL,
706  if (BUG(entry == NULL)) {
707  /* Should never happen because we note down the address in the geoip
708  * cache before this is called. */
709  goto end;
710  }
711 
712  entry->dos_stats.concurrent_count++;
713  or_conn->tracked_for_dos_mitigation = 1;
714  log_debug(LD_DOS, "Client address %s has now %u concurrent connections.",
715  fmt_addr(&or_conn->real_addr),
716  entry->dos_stats.concurrent_count);
717 
718  end:
719  return;
720 }
721 
722 /* Called when a client connection for the given IP address has been closed. */
723 void
724 dos_close_client_conn(const or_connection_t *or_conn)
725 {
726  clientmap_entry_t *entry;
727 
728  tor_assert(or_conn);
729 
730  /* We have to decrement the count on tracked connection only even if the
731  * subsystem has been disabled at runtime because it might be re-enabled
732  * after and we need to keep a synchronized counter at all time. */
733  if (!or_conn->tracked_for_dos_mitigation) {
734  goto end;
735  }
736 
737  /* We are only interested in client connection from the geoip cache. */
738  entry = geoip_lookup_client(&or_conn->real_addr, NULL,
740  if (entry == NULL) {
741  /* This can happen because we can close a connection before the channel
742  * got to be noted down in the geoip cache. */
743  goto end;
744  }
745 
746  /* Extra super duper safety. Going below 0 means an underflow which could
747  * lead to most likely a false positive. In theory, this should never happen
748  * but lets be extra safe. */
749  if (BUG(entry->dos_stats.concurrent_count == 0)) {
750  goto end;
751  }
752 
753  entry->dos_stats.concurrent_count--;
754  log_debug(LD_DOS, "Client address %s has lost a connection. Concurrent "
755  "connections are now at %u",
756  fmt_addr(&or_conn->real_addr),
757  entry->dos_stats.concurrent_count);
758 
759  end:
760  return;
761 }
762 
763 /* Called when the consensus has changed. We might have new consensus
764  * parameters to look at. */
765 void
766 dos_consensus_has_changed(const networkstatus_t *ns)
767 {
768  /* There are two ways to configure this subsystem, one at startup through
769  * dos_init() which is called when the options are parsed. And this one
770  * through the consensus. We don't want to enable any DoS mitigation if we
771  * aren't a public relay. */
773  return;
774  }
775 
776  cc_consensus_has_changed(ns);
777  conn_consensus_has_changed(ns);
778 
779  /* We were already enabled or we just became enabled but either way, set the
780  * consensus parameters for all subsystems. */
781  set_dos_parameters(ns);
782 }
783 
784 /* Return true iff the DoS mitigation subsystem is enabled. */
785 int
786 dos_enabled(void)
787 {
788  return dos_is_enabled();
789 }
790 
791 /* Free everything from the Denial of Service subsystem. */
792 void
793 dos_free_all(void)
794 {
795  /* Free the circuit creation mitigation subsystem. It is safe to do this
796  * even if it wasn't initialized. */
797  cc_free_all();
798 
799  /* Free the connection mitigation subsystem. It is safe to do this even if
800  * it wasn't initialized. */
801  conn_free_all();
802 }
803 
804 /* Initialize the Denial of Service subsystem. */
805 void
806 dos_init(void)
807 {
808  /* To initialize, we only need to get the parameters. */
809  set_dos_parameters(NULL);
810 }
Header file containing denial of service defenses for the HS subsystem for all versions.
int channel_is_client(const channel_t *chan)
Definition: channel.c:2901
int channel_get_addr_if_possible(channel_t *chan, tor_addr_t *addr_out)
Definition: channel.c:2841
smartlist_t * get_connection_array(void)
Definition: mainloop.c:452
Common functions for using (pseudo-)random number generators.
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Header file for geoip_stats.c.
Header file for connection.c.
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2, tor_addr_comparison_t how)
Definition: address.c:954
Header file for nodelist.c.
OR connection structure.
int DoSRefuseSingleHopClientRendezvous
Header file for config.c.
#define CONN_TYPE_OR
Definition: connection.h:42
const or_options_t * get_options(void)
Definition: config.c:926
#define tor_assert(expr)
Definition: util_bug.h:102
int DoSCircuitCreationRate
int crypto_rand_int_range(unsigned int min, unsigned int max)
#define tor_free(p)
Definition: malloc.h:52
Header file for mainloop.c.
uint64_t stats_n_circ_max_cell_reached
Definition: relay.c:132
#define STATIC
Definition: testsupport.h:32
or_connection_t * TO_OR_CONN(connection_t *c)
Header file for channel.c.
int DoSConnectionEnabled
Header file for routermode.c.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
Master header file for Tor-specific functionality.
uint64_t hs_dos_get_intro2_rejected_count(void)
Definition: hs_dos.c:211
unsigned int tracked_for_dos_mitigation
int DoSCircuitCreationMinConnections
tor_addr_t real_addr
int DoSCircuitCreationDefenseType
Definition: geoip_stats.h:79
#define LD_DOS
Definition: log.h:113
Header file for relay.c.
int DoSCircuitCreationEnabled
int DoSCircuitCreationDefenseTimePeriod
#define fmt_addr(a)
Definition: address.h:211
time_t approx_time(void)
Definition: approx_time.c:32
int public_server_mode(const or_options_t *options)
Definition: routermode.c:43
int DoSConnectionMaxConcurrentCount
Header file for connection_or.c.
int DoSConnectionDefenseType
int nodelist_probably_contains_address(const tor_addr_t *addr)
Definition: nodelist.c:477
#define LD_HEARTBEAT
Definition: log.h:103
int DoSCircuitCreationBurst
Header file for networkstatus.c.