tor  0.4.0.0-alpha-dev
dos.c
1 /* Copyright (c) 2018-2018, 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"
23 
24 #include "core/or/dos.h"
25 
26 #include "core/or/or_connection_st.h"
27 
28 /*
29  * Circuit creation denial of service mitigation.
30  *
31  * Namespace used for this mitigation framework is "dos_cc_" where "cc" is for
32  * Circuit Creation.
33  */
34 
35 /* Is the circuit creation DoS mitigation enabled? */
36 static unsigned int dos_cc_enabled = 0;
37 
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;
45 
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;
49 
50 /*
51  * Concurrent connection denial of service mitigation.
52  *
53  * Namespace used for this mitigation framework is "dos_conn_".
54  */
55 
56 /* Is the connection DoS mitigation enabled? */
57 static unsigned int dos_conn_enabled = 0;
58 
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;
63 
64 /* Keep some stats for the heartbeat so we can report out. */
65 static uint64_t conn_num_addr_rejected;
66 
67 /*
68  * General interface of the denial of service mitigation subsystem.
69  */
70 
71 /* Keep stats for the heartbeat. */
72 static uint64_t num_single_hop_client_refused;
73 
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))
78 {
79  if (get_options()->DoSCircuitCreationEnabled != -1) {
80  return get_options()->DoSCircuitCreationEnabled;
81  }
82 
83  return !!networkstatus_get_param(ns, "DoSCircuitCreationEnabled",
84  DOS_CC_ENABLED_DEFAULT, 0, 1);
85 }
86 
87 /* Return the parameter for the minimum concurrent connection at which we'll
88  * start counting circuit for a specific client address. */
89 STATIC uint32_t
90 get_param_cc_min_concurrent_connection(const networkstatus_t *ns)
91 {
92  if (get_options()->DoSCircuitCreationMinConnections) {
93  return get_options()->DoSCircuitCreationMinConnections;
94  }
95  return networkstatus_get_param(ns, "DoSCircuitCreationMinConnections",
96  DOS_CC_MIN_CONCURRENT_CONN_DEFAULT,
97  1, INT32_MAX);
98 }
99 
100 /* Return the parameter for the time rate that is how many circuits over this
101  * time span. */
102 static uint32_t
103 get_param_cc_circuit_rate(const networkstatus_t *ns)
104 {
105  /* This is in seconds. */
106  if (get_options()->DoSCircuitCreationRate) {
107  return get_options()->DoSCircuitCreationRate;
108  }
109  return networkstatus_get_param(ns, "DoSCircuitCreationRate",
110  DOS_CC_CIRCUIT_RATE_DEFAULT,
111  1, INT32_MAX);
112 }
113 
114 /* Return the parameter for the maximum circuit count for the circuit time
115  * rate. */
116 STATIC uint32_t
117 get_param_cc_circuit_burst(const networkstatus_t *ns)
118 {
119  if (get_options()->DoSCircuitCreationBurst) {
120  return get_options()->DoSCircuitCreationBurst;
121  }
122  return networkstatus_get_param(ns, "DoSCircuitCreationBurst",
123  DOS_CC_CIRCUIT_BURST_DEFAULT,
124  1, INT32_MAX);
125 }
126 
127 /* Return the consensus parameter of the circuit creation defense type. */
128 static uint32_t
129 get_param_cc_defense_type(const networkstatus_t *ns)
130 {
131  if (get_options()->DoSCircuitCreationDefenseType) {
132  return get_options()->DoSCircuitCreationDefenseType;
133  }
134  return networkstatus_get_param(ns, "DoSCircuitCreationDefenseType",
135  DOS_CC_DEFENSE_TYPE_DEFAULT,
136  DOS_CC_DEFENSE_NONE, DOS_CC_DEFENSE_MAX);
137 }
138 
139 /* Return the consensus parameter of the defense time period which is how much
140  * time should we defend against a malicious client address. */
141 static int32_t
142 get_param_cc_defense_time_period(const networkstatus_t *ns)
143 {
144  /* Time in seconds. */
145  if (get_options()->DoSCircuitCreationDefenseTimePeriod) {
146  return get_options()->DoSCircuitCreationDefenseTimePeriod;
147  }
148  return networkstatus_get_param(ns, "DoSCircuitCreationDefenseTimePeriod",
149  DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT,
150  0, INT32_MAX);
151 }
152 
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))
157 {
158  if (get_options()->DoSConnectionEnabled != -1) {
159  return get_options()->DoSConnectionEnabled;
160  }
161  return !!networkstatus_get_param(ns, "DoSConnectionEnabled",
162  DOS_CONN_ENABLED_DEFAULT, 0, 1);
163 }
164 
165 /* Return the consensus parameter for the maximum concurrent connection
166  * allowed. */
167 STATIC uint32_t
168 get_param_conn_max_concurrent_count(const networkstatus_t *ns)
169 {
170  if (get_options()->DoSConnectionMaxConcurrentCount) {
171  return get_options()->DoSConnectionMaxConcurrentCount;
172  }
173  return networkstatus_get_param(ns, "DoSConnectionMaxConcurrentCount",
174  DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT,
175  1, INT32_MAX);
176 }
177 
178 /* Return the consensus parameter of the connection defense type. */
179 static uint32_t
180 get_param_conn_defense_type(const networkstatus_t *ns)
181 {
182  if (get_options()->DoSConnectionDefenseType) {
183  return get_options()->DoSConnectionDefenseType;
184  }
185  return networkstatus_get_param(ns, "DoSConnectionDefenseType",
186  DOS_CONN_DEFENSE_TYPE_DEFAULT,
187  DOS_CONN_DEFENSE_NONE, DOS_CONN_DEFENSE_MAX);
188 }
189 
190 /* Set circuit creation parameters located in the consensus or their default
191  * if none are present. Called at initialization or when the consensus
192  * changes. */
193 static void
194 set_dos_parameters(const networkstatus_t *ns)
195 {
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);
203 
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);
208 }
209 
210 /* Free everything for the circuit creation DoS mitigation subsystem. */
211 static void
212 cc_free_all(void)
213 {
214  /* If everything is freed, the circuit creation subsystem is not enabled. */
215  dos_cc_enabled = 0;
216 }
217 
218 /* Called when the consensus has changed. Do appropriate actions for the
219  * circuit creation subsystem. */
220 static void
221 cc_consensus_has_changed(const networkstatus_t *ns)
222 {
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)) {
226  cc_free_all();
227  }
228 }
229 
232 STATIC uint64_t
233 get_circuit_rate_per_second(void)
234 {
235  return dos_cc_circuit_rate;
236 }
237 
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. */
241 STATIC void
242 cc_stats_refill_bucket(cc_client_stats_t *stats, const tor_addr_t *addr)
243 {
244  uint32_t new_circuit_bucket_count;
245  uint64_t num_token, elapsed_time_last_refill = 0, circuit_rate = 0;
246  time_t now;
247  int64_t last_refill_ts;
248 
249  tor_assert(stats);
250  tor_assert(addr);
251 
252  now = approx_time();
253  last_refill_ts = (int64_t)stats->last_circ_bucket_refill_ts;
254 
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) {
260  goto done;
261  }
262 
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
265  * per second. */
266  circuit_rate = get_circuit_rate_per_second();
267 
268  /* We've never filled the bucket so fill it with the maximum being the burst
269  * and we are done.
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;
274  goto end;
275  }
276 
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
284  * rare situation.*/
285  if ((int64_t)now < last_refill_ts) {
286  /* Use the maximum allowed value of token. */
287  num_token = dos_cc_circuit_burst;
288  goto end;
289  }
290 
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;
295 
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;
300  goto end;
301  }
302 
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;
307 
308  end:
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;
312  } else {
313  /* We cap the bucket to the burst value else this could overflow uint32_t
314  * over time. */
315  new_circuit_bucket_count = MIN(stats->circuit_bucket + (uint32_t)num_token,
316  dos_cc_circuit_burst);
317  }
318 
319  /* This function is not allowed to make the bucket count larger than the
320  * burst value */
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);
327 
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);
333 
334  stats->circuit_bucket = new_circuit_bucket_count;
335  stats->last_circ_bucket_refill_ts = now;
336 
337  done:
338  return;
339 }
340 
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. */
344 static int
345 cc_has_exhausted_circuits(const dos_client_stats_t *stats)
346 {
347  tor_assert(stats);
348  return stats->cc_stats.circuit_bucket == 0 &&
349  stats->concurrent_count >= dos_cc_min_concurrent_conn;
350 }
351 
352 /* Mark client address by setting a timestamp in the stats object which tells
353  * us until when it is marked as positively detected. */
354 static void
355 cc_mark_client(cc_client_stats_t *stats)
356 {
357  tor_assert(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);
363 }
364 
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. */
368 static int
369 cc_channel_addr_is_marked(channel_t *chan)
370 {
371  time_t now;
372  tor_addr_t addr;
373  clientmap_entry_t *entry;
374  cc_client_stats_t *stats = NULL;
375 
376  if (chan == NULL) {
377  goto end;
378  }
379  /* Must be a client connection else we ignore. */
380  if (!channel_is_client(chan)) {
381  goto end;
382  }
383  /* Without an IP address, nothing can work. */
384  if (!channel_get_addr_if_possible(chan, &addr)) {
385  goto end;
386  }
387 
388  /* We are only interested in client connection from the geoip cache. */
389  entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
390  if (entry == NULL) {
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. */
394  goto end;
395  }
396  now = approx_time();
397  stats = &entry->dos_stats.cc_stats;
398 
399  end:
400  return stats && stats->marked_until_ts >= now;
401 }
402 
403 /* Concurrent connection private API. */
404 
405 /* Free everything for the connection DoS mitigation subsystem. */
406 static void
407 conn_free_all(void)
408 {
409  dos_conn_enabled = 0;
410 }
411 
412 /* Called when the consensus has changed. Do appropriate actions for the
413  * connection mitigation subsystem. */
414 static void
415 conn_consensus_has_changed(const networkstatus_t *ns)
416 {
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)) {
420  conn_free_all();
421  }
422 }
423 
424 /* General private API */
425 
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. */
428 static inline int
429 dos_is_enabled(void)
430 {
431  return (dos_cc_enabled || dos_conn_enabled);
432 }
433 
434 /* Circuit creation public API. */
435 
436 /* Called when a CREATE cell is received from the given channel. */
437 void
438 dos_cc_new_create_cell(channel_t *chan)
439 {
440  tor_addr_t addr;
441  clientmap_entry_t *entry;
442 
443  tor_assert(chan);
444 
445  /* Skip everything if not enabled. */
446  if (!dos_cc_enabled) {
447  goto end;
448  }
449 
450  /* Must be a client connection else we ignore. */
451  if (!channel_is_client(chan)) {
452  goto end;
453  }
454  /* Without an IP address, nothing can work. */
455  if (!channel_get_addr_if_possible(chan, &addr)) {
456  goto end;
457  }
458 
459  /* We are only interested in client connection from the geoip cache. */
460  entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
461  if (entry == NULL) {
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. */
465  goto end;
466  }
467 
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. */
472 
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);
476 
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--;
481  }
482 
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
488  * lots of logs. */
489  if (entry->dos_stats.cc_stats.marked_until_ts == 0) {
490  log_debug(LD_DOS, "Detected circuit creation DoS by address: %s",
491  fmt_addr(&addr));
492  cc_num_marked_addrs++;
493  }
494  cc_mark_client(&entry->dos_stats.cc_stats);
495  }
496 
497  end:
498  return;
499 }
500 
501 /* Return the defense type that should be used for this circuit.
502  *
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)
506 {
507  tor_assert(chan);
508 
509  /* Skip everything if not enabled. */
510  if (!dos_cc_enabled) {
511  goto end;
512  }
513 
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;
521  }
522 
523  end:
524  return DOS_CC_DEFENSE_NONE;
525 }
526 
527 /* Concurrent connection detection public API. */
528 
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)
533 {
534  clientmap_entry_t *entry;
535 
536  tor_assert(addr);
537 
538  /* Skip everything if not enabled. */
539  if (!dos_conn_enabled) {
540  goto end;
541  }
542 
543  /* We are only interested in client connection from the geoip cache. */
544  entry = geoip_lookup_client(addr, NULL, GEOIP_CLIENT_CONNECT);
545  if (entry == NULL) {
546  goto end;
547  }
548 
549  /* Need to be above the maximum concurrent connection count to trigger a
550  * defense. */
551  if (entry->dos_stats.concurrent_count > dos_conn_max_concurrent_count) {
552  conn_num_addr_rejected++;
553  return dos_conn_defense_type;
554  }
555 
556  end:
557  return DOS_CONN_DEFENSE_NONE;
558 }
559 
560 /* General API */
561 
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.
564  *
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. */
569 void
570 dos_geoip_entry_about_to_free(const clientmap_entry_t *geoip_ent)
571 {
572  tor_assert(geoip_ent);
573 
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) {
577  goto end;
578  }
579 
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,
587  CMP_EXACT)) {
588  or_conn->tracked_for_dos_mitigation = 0;
589  }
590  }
591  } SMARTLIST_FOREACH_END(conn);
592 
593  end:
594  return;
595 }
596 
597 /* Note down that we've just refused a single hop client. This increments a
598  * counter later used for the heartbeat. */
599 void
600 dos_note_refuse_single_hop_client(void)
601 {
602  num_single_hop_client_refused++;
603 }
604 
605 /* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should
606  * be refused. */
607 int
608 dos_should_refuse_single_hop_client(void)
609 {
610  /* If we aren't a public relay, this shouldn't apply to anything. */
611  if (!public_server_mode(get_options())) {
612  return 0;
613  }
614 
615  if (get_options()->DoSRefuseSingleHopClientRendezvous != -1) {
616  return get_options()->DoSRefuseSingleHopClientRendezvous;
617  }
618 
619  return (int) networkstatus_get_param(NULL,
620  "DoSRefuseSingleHopClientRendezvous",
621  0 /* default */, 0, 1);
622 }
623 
624 /* Log a heartbeat message with some statistics. */
625 void
626 dos_log_heartbeat(void)
627 {
628  char *conn_msg = NULL;
629  char *cc_msg = NULL;
630  char *single_hop_client_msg = NULL;
631  char *circ_stats_msg = NULL;
632 
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.",
637 
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);
643  }
644 
645  if (dos_conn_enabled) {
646  tor_asprintf(&conn_msg,
647  " %" PRIu64 " connections closed.",
648  conn_num_addr_rejected);
649  }
650 
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);
655  }
656 
657  log_notice(LD_HEARTBEAT,
658  "DoS mitigation since startup:%s%s%s%s",
659  circ_stats_msg,
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 : "");
663 
664  tor_free(conn_msg);
665  tor_free(cc_msg);
666  tor_free(single_hop_client_msg);
667  tor_free(circ_stats_msg);
668  return;
669 }
670 
671 /* Called when a new client connection has been established on the given
672  * address. */
673 void
674 dos_new_client_conn(or_connection_t *or_conn)
675 {
676  clientmap_entry_t *entry;
677 
678  tor_assert(or_conn);
679 
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()) {
683  goto end;
684  }
685 
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. */
691  goto end;
692  }
693 
694  /* We are only interested in client connection from the geoip cache. */
695  entry = geoip_lookup_client(&or_conn->real_addr, NULL,
697  if (BUG(entry == NULL)) {
698  /* Should never happen because we note down the address in the geoip
699  * cache before this is called. */
700  goto end;
701  }
702 
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);
708 
709  end:
710  return;
711 }
712 
713 /* Called when a client connection for the given IP address has been closed. */
714 void
715 dos_close_client_conn(const or_connection_t *or_conn)
716 {
717  clientmap_entry_t *entry;
718 
719  tor_assert(or_conn);
720 
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) {
725  goto end;
726  }
727 
728  /* We are only interested in client connection from the geoip cache. */
729  entry = geoip_lookup_client(&or_conn->real_addr, NULL,
731  if (entry == NULL) {
732  /* This can happen because we can close a connection before the channel
733  * got to be noted down in the geoip cache. */
734  goto end;
735  }
736 
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)) {
741  goto end;
742  }
743 
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);
749 
750  end:
751  return;
752 }
753 
754 /* Called when the consensus has changed. We might have new consensus
755  * parameters to look at. */
756 void
757 dos_consensus_has_changed(const networkstatus_t *ns)
758 {
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())) {
764  return;
765  }
766 
767  cc_consensus_has_changed(ns);
768  conn_consensus_has_changed(ns);
769 
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);
773 }
774 
775 /* Return true iff the DoS mitigation subsystem is enabled. */
776 int
777 dos_enabled(void)
778 {
779  return dos_is_enabled();
780 }
781 
782 /* Free everything from the Denial of Service subsystem. */
783 void
784 dos_free_all(void)
785 {
786  /* Free the circuit creation mitigation subsystem. It is safe to do this
787  * even if it wasn't initialized. */
788  cc_free_all();
789 
790  /* Free the connection mitigation subsystem. It is safe to do this even if
791  * it wasn't initialized. */
792  conn_free_all();
793 }
794 
795 /* Initialize the Denial of Service subsystem. */
796 void
797 dos_init(void)
798 {
799  /* To initialize, we only need to get the parameters. */
800  set_dos_parameters(NULL);
801 }
int channel_is_client(const channel_t *chan)
Definition: channel.c:2913
Common functions for using (pseudo-)random number generators.
tor_addr_t real_addr
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
Header file for geoip_stats.c.
Header file for connection.c.
unsigned int tracked_for_dos_mitigation
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2, tor_addr_comparison_t how)
Definition: address.c:942
Header file for nodelist.c.
Header file for config.c.
#define CONN_TYPE_OR
Definition: connection.h:24
#define tor_free(p)
Definition: malloc.h:52
Header file for mainloop.c.
uint64_t stats_n_circ_max_cell_reached
Definition: relay.c:135
or_connection_t * TO_OR_CONN(connection_t *c)
Header file for channel.c.
tor_assert(buffer)
Header file for routermode.c.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
Master header file for Tor-specific functionality.
int crypto_rand_int_range(unsigned int min, unsigned int max)
Definition: crypto_rand.c:575
Definition: geoip_stats.h:78
#define LD_DOS
Definition: log.h:109
Header file for relay.c.
#define fmt_addr(a)
Definition: address.h:211
time_t approx_time(void)
Definition: approx_time.c:32
Header file for connection_or.c.
int nodelist_probably_contains_address(const tor_addr_t *addr)
Definition: nodelist.c:477
#define LD_HEARTBEAT
Definition: log.h:99
Header file for networkstatus.c.