tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

dos.c (40706B)


      1 /* Copyright (c) 2018-2021, 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"
     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"
     24 #include "lib/time/compat_time.h"
     25 
     26 #include "core/or/dos.h"
     27 #include "core/or/dos_sys.h"
     28 
     29 #include "core/or/dos_options_st.h"
     30 #include "core/or/or_connection_st.h"
     31 
     32 /*
     33 * Circuit creation denial of service mitigation.
     34 *
     35 * Namespace used for this mitigation framework is "dos_cc_" where "cc" is for
     36 * Circuit Creation.
     37 */
     38 
     39 /* Is the circuit creation DoS mitigation enabled? */
     40 static unsigned int dos_cc_enabled = 0;
     41 
     42 /* Consensus parameters. They can be changed when a new consensus arrives.
     43 * They are initialized with the hardcoded default values. */
     44 static uint32_t dos_cc_min_concurrent_conn;
     45 static uint32_t dos_cc_circuit_rate;
     46 static uint32_t dos_cc_circuit_burst;
     47 static dos_cc_defense_type_t dos_cc_defense_type;
     48 static int32_t dos_cc_defense_time_period;
     49 
     50 /* Keep some stats for the heartbeat so we can report out. */
     51 static uint64_t cc_num_rejected_cells;
     52 static uint32_t cc_num_marked_addrs;
     53 static uint32_t cc_num_marked_addrs_max_queue;
     54 
     55 /*
     56 * Concurrent connection denial of service mitigation.
     57 *
     58 * Namespace used for this mitigation framework is "dos_conn_".
     59 */
     60 
     61 /* Is the connection DoS mitigation enabled? */
     62 static unsigned int dos_conn_enabled = 0;
     63 
     64 /* Consensus parameters. They can be changed when a new consensus arrives.
     65 * They are initialized with the hardcoded default values. */
     66 static uint32_t dos_conn_max_concurrent_count;
     67 static dos_conn_defense_type_t dos_conn_defense_type;
     68 static uint32_t dos_conn_connect_rate = DOS_CONN_CONNECT_RATE_DEFAULT;
     69 static uint32_t dos_conn_connect_burst = DOS_CONN_CONNECT_BURST_DEFAULT;
     70 static int32_t dos_conn_connect_defense_time_period =
     71  DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_DEFAULT;
     72 
     73 /* Keep some stats for the heartbeat so we can report out. */
     74 static uint64_t conn_num_addr_rejected;
     75 static uint64_t conn_num_addr_connect_rejected;
     76 
     77 /** Consensus parameter: How many times a client IP is allowed to hit the
     78 * circ_max_cell_queue_size_out limit before being marked. */
     79 static uint32_t dos_num_circ_max_outq;
     80 
     81 /*
     82 * Stream denial of service mitigation.
     83 *
     84 * Namespace used for this mitigation framework is "dos_stream_".
     85 */
     86 
     87 /* Is the connection DoS mitigation enabled? */
     88 static unsigned int dos_stream_enabled = 0;
     89 
     90 /* Consensus parameters. They can be changed when a new consensus arrives.
     91 * They are initialized with the hardcoded default values. */
     92 static dos_stream_defense_type_t dos_stream_defense_type;
     93 static uint32_t dos_stream_rate = DOS_STREAM_RATE_DEFAULT;
     94 static uint32_t dos_stream_burst = DOS_STREAM_BURST_DEFAULT;
     95 
     96 /* Keep some stats for the heartbeat so we can report out. */
     97 static uint64_t stream_num_rejected;
     98 
     99 /*
    100 * General interface of the denial of service mitigation subsystem.
    101 */
    102 
    103 /* Keep stats for the heartbeat. */
    104 static uint64_t num_single_hop_client_refused;
    105 
    106 /** Return the consensus parameter for the outbound circ_max_cell_queue_size
    107 * limit. */
    108 static uint32_t
    109 get_param_dos_num_circ_max_outq(const networkstatus_t *ns)
    110 {
    111 #define DOS_NUM_CIRC_MAX_OUTQ_DEFAULT 3
    112 #define DOS_NUM_CIRC_MAX_OUTQ_MIN 0
    113 #define DOS_NUM_CIRC_MAX_OUTQ_MAX INT32_MAX
    114 
    115  /* Update the circuit max cell queue size from the consensus. */
    116  return networkstatus_get_param(ns, "dos_num_circ_max_outq",
    117                                 DOS_NUM_CIRC_MAX_OUTQ_DEFAULT,
    118                                 DOS_NUM_CIRC_MAX_OUTQ_MIN,
    119                                 DOS_NUM_CIRC_MAX_OUTQ_MAX);
    120 }
    121 
    122 /* Return true iff the circuit creation mitigation is enabled. We look at the
    123 * consensus for this else a default value is returned. */
    124 MOCK_IMPL(STATIC unsigned int,
    125 get_param_cc_enabled, (const networkstatus_t *ns))
    126 {
    127  if (dos_get_options()->DoSCircuitCreationEnabled != -1) {
    128    return dos_get_options()->DoSCircuitCreationEnabled;
    129  }
    130 
    131  return !!networkstatus_get_param(ns, "DoSCircuitCreationEnabled",
    132                                   DOS_CC_ENABLED_DEFAULT, 0, 1);
    133 }
    134 
    135 /* Return the parameter for the minimum concurrent connection at which we'll
    136 * start counting circuit for a specific client address. */
    137 STATIC uint32_t
    138 get_param_cc_min_concurrent_connection(const networkstatus_t *ns)
    139 {
    140  if (dos_get_options()->DoSCircuitCreationMinConnections) {
    141    return dos_get_options()->DoSCircuitCreationMinConnections;
    142  }
    143  return networkstatus_get_param(ns, "DoSCircuitCreationMinConnections",
    144                                 DOS_CC_MIN_CONCURRENT_CONN_DEFAULT,
    145                                 1, INT32_MAX);
    146 }
    147 
    148 /* Return the parameter for the time rate that is how many circuits over this
    149 * time span. */
    150 static uint32_t
    151 get_param_cc_circuit_rate(const networkstatus_t *ns)
    152 {
    153  /* This is in seconds. */
    154  if (dos_get_options()->DoSCircuitCreationRate) {
    155    return dos_get_options()->DoSCircuitCreationRate;
    156  }
    157  return networkstatus_get_param(ns, "DoSCircuitCreationRate",
    158                                 DOS_CC_CIRCUIT_RATE_DEFAULT,
    159                                 1, INT32_MAX);
    160 }
    161 
    162 /* Return the parameter for the maximum circuit count for the circuit time
    163 * rate. */
    164 STATIC uint32_t
    165 get_param_cc_circuit_burst(const networkstatus_t *ns)
    166 {
    167  if (dos_get_options()->DoSCircuitCreationBurst) {
    168    return dos_get_options()->DoSCircuitCreationBurst;
    169  }
    170  return networkstatus_get_param(ns, "DoSCircuitCreationBurst",
    171                                 DOS_CC_CIRCUIT_BURST_DEFAULT,
    172                                 1, INT32_MAX);
    173 }
    174 
    175 /* Return the consensus parameter of the circuit creation defense type. */
    176 static uint32_t
    177 get_param_cc_defense_type(const networkstatus_t *ns)
    178 {
    179  if (dos_get_options()->DoSCircuitCreationDefenseType) {
    180    return dos_get_options()->DoSCircuitCreationDefenseType;
    181  }
    182  return networkstatus_get_param(ns, "DoSCircuitCreationDefenseType",
    183                                 DOS_CC_DEFENSE_TYPE_DEFAULT,
    184                                 DOS_CC_DEFENSE_NONE, DOS_CC_DEFENSE_MAX);
    185 }
    186 
    187 /* Return the consensus parameter of the defense time period which is how much
    188 * time should we defend against a malicious client address. */
    189 static int32_t
    190 get_param_cc_defense_time_period(const networkstatus_t *ns)
    191 {
    192  /* Time in seconds. */
    193  if (dos_get_options()->DoSCircuitCreationDefenseTimePeriod) {
    194    return dos_get_options()->DoSCircuitCreationDefenseTimePeriod;
    195  }
    196  return networkstatus_get_param(ns, "DoSCircuitCreationDefenseTimePeriod",
    197                                 DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT,
    198                                 0, INT32_MAX);
    199 }
    200 
    201 /* Return true iff connection mitigation is enabled. We look at the consensus
    202 * for this else a default value is returned. */
    203 MOCK_IMPL(STATIC unsigned int,
    204 get_param_conn_enabled, (const networkstatus_t *ns))
    205 {
    206  if (dos_get_options()->DoSConnectionEnabled != -1) {
    207    return dos_get_options()->DoSConnectionEnabled;
    208  }
    209  return !!networkstatus_get_param(ns, "DoSConnectionEnabled",
    210                                   DOS_CONN_ENABLED_DEFAULT, 0, 1);
    211 }
    212 
    213 /* Return the consensus parameter for the maximum concurrent connection
    214 * allowed. */
    215 STATIC uint32_t
    216 get_param_conn_max_concurrent_count(const networkstatus_t *ns)
    217 {
    218  if (dos_get_options()->DoSConnectionMaxConcurrentCount) {
    219    return dos_get_options()->DoSConnectionMaxConcurrentCount;
    220  }
    221  return networkstatus_get_param(ns, "DoSConnectionMaxConcurrentCount",
    222                                 DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT,
    223                                 1, INT32_MAX);
    224 }
    225 
    226 /* Return the consensus parameter of the connection defense type. */
    227 static uint32_t
    228 get_param_conn_defense_type(const networkstatus_t *ns)
    229 {
    230  if (dos_get_options()->DoSConnectionDefenseType) {
    231    return dos_get_options()->DoSConnectionDefenseType;
    232  }
    233  return networkstatus_get_param(ns, "DoSConnectionDefenseType",
    234                                 DOS_CONN_DEFENSE_TYPE_DEFAULT,
    235                                 DOS_CONN_DEFENSE_NONE, DOS_CONN_DEFENSE_MAX);
    236 }
    237 
    238 /* Return the connection connect rate parameters either from the configuration
    239 * file or, if not found, consensus parameter. */
    240 static uint32_t
    241 get_param_conn_connect_rate(const networkstatus_t *ns)
    242 {
    243  if (dos_get_options()->DoSConnectionConnectRate) {
    244    return dos_get_options()->DoSConnectionConnectRate;
    245  }
    246  return networkstatus_get_param(ns, "DoSConnectionConnectRate",
    247                                 DOS_CONN_CONNECT_RATE_DEFAULT,
    248                                 1, INT32_MAX);
    249 }
    250 
    251 /* Return the connection connect burst parameters either from the
    252 * configuration file or, if not found, consensus parameter. */
    253 STATIC uint32_t
    254 get_param_conn_connect_burst(const networkstatus_t *ns)
    255 {
    256  if (dos_get_options()->DoSConnectionConnectBurst) {
    257    return dos_get_options()->DoSConnectionConnectBurst;
    258  }
    259  return networkstatus_get_param(ns, "DoSConnectionConnectBurst",
    260                                 DOS_CONN_CONNECT_BURST_DEFAULT,
    261                                 1, INT32_MAX);
    262 }
    263 
    264 /* Return the connection connect defense time period from the configuration
    265 * file or, if not found, the consensus parameter. */
    266 static int32_t
    267 get_param_conn_connect_defense_time_period(const networkstatus_t *ns)
    268 {
    269  /* Time in seconds. */
    270  if (dos_get_options()->DoSConnectionConnectDefenseTimePeriod) {
    271    return dos_get_options()->DoSConnectionConnectDefenseTimePeriod;
    272  }
    273  return networkstatus_get_param(ns, "DoSConnectionConnectDefenseTimePeriod",
    274                                 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_DEFAULT,
    275                                 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_MIN,
    276                                 INT32_MAX);
    277 }
    278 
    279 /* Return true iff the stream creation mitigation is enabled. We look at the
    280 * consensus for this else a default value is returned. */
    281 MOCK_IMPL(STATIC unsigned int,
    282 get_param_stream_enabled, (const networkstatus_t *ns))
    283 {
    284  if (dos_get_options()->DoSStreamCreationEnabled != -1) {
    285    return dos_get_options()->DoSStreamCreationEnabled;
    286  }
    287 
    288  return !!networkstatus_get_param(ns, "DoSStreamCreationEnabled",
    289                                   DOS_STREAM_ENABLED_DEFAULT, 0, 1);
    290 }
    291 
    292 /* Return the parameter for the time rate that is how many stream per circuit
    293 * over this time span. */
    294 static uint32_t
    295 get_param_stream_rate(const networkstatus_t *ns)
    296 {
    297  /* This is in seconds. */
    298  if (dos_get_options()->DoSStreamCreationRate) {
    299    return dos_get_options()->DoSStreamCreationRate;
    300  }
    301  return networkstatus_get_param(ns, "DoSStreamCreationRate",
    302                                 DOS_STREAM_RATE_DEFAULT,
    303                                 1, INT32_MAX);
    304 }
    305 
    306 /* Return the parameter for the maximum circuit count for the circuit time
    307 * rate. */
    308 static uint32_t
    309 get_param_stream_burst(const networkstatus_t *ns)
    310 {
    311  if (dos_get_options()->DoSStreamCreationBurst) {
    312    return dos_get_options()->DoSStreamCreationBurst;
    313  }
    314  return networkstatus_get_param(ns, "DoSStreamCreationBurst",
    315                                 DOS_STREAM_BURST_DEFAULT,
    316                                 1, INT32_MAX);
    317 }
    318 
    319 /* Return the consensus parameter of the circuit creation defense type. */
    320 static uint32_t
    321 get_param_stream_defense_type(const networkstatus_t *ns)
    322 {
    323  if (dos_get_options()->DoSStreamCreationDefenseType) {
    324    return dos_get_options()->DoSStreamCreationDefenseType;
    325  }
    326  return networkstatus_get_param(ns, "DoSStreamCreationDefenseType",
    327                                 DOS_STREAM_DEFENSE_TYPE_DEFAULT,
    328                                 DOS_STREAM_DEFENSE_NONE,
    329                                 DOS_STREAM_DEFENSE_MAX);
    330 }
    331 
    332 /* Set circuit creation parameters located in the consensus or their default
    333 * if none are present. Called at initialization or when the consensus
    334 * changes. */
    335 static void
    336 set_dos_parameters(const networkstatus_t *ns)
    337 {
    338  /* Get the default consensus param values. */
    339  dos_cc_enabled = get_param_cc_enabled(ns);
    340  dos_cc_min_concurrent_conn = get_param_cc_min_concurrent_connection(ns);
    341  dos_cc_circuit_rate = get_param_cc_circuit_rate(ns);
    342  dos_cc_circuit_burst = get_param_cc_circuit_burst(ns);
    343  dos_cc_defense_time_period = get_param_cc_defense_time_period(ns);
    344  dos_cc_defense_type = get_param_cc_defense_type(ns);
    345 
    346  /* Connection detection. */
    347  dos_conn_enabled = get_param_conn_enabled(ns);
    348  dos_conn_max_concurrent_count = get_param_conn_max_concurrent_count(ns);
    349  dos_conn_defense_type = get_param_conn_defense_type(ns);
    350  dos_conn_connect_rate = get_param_conn_connect_rate(ns);
    351  dos_conn_connect_burst = get_param_conn_connect_burst(ns);
    352  dos_conn_connect_defense_time_period =
    353    get_param_conn_connect_defense_time_period(ns);
    354 
    355  /* Circuit. */
    356  dos_num_circ_max_outq = get_param_dos_num_circ_max_outq(ns);
    357 
    358  /* Stream. */
    359  dos_stream_enabled = get_param_stream_enabled(ns);
    360  dos_stream_defense_type = get_param_stream_defense_type(ns);
    361  dos_stream_rate = get_param_stream_rate(ns);
    362  dos_stream_burst = get_param_stream_burst(ns);
    363 }
    364 
    365 /* Free everything for the circuit creation DoS mitigation subsystem. */
    366 static void
    367 cc_free_all(void)
    368 {
    369  /* If everything is freed, the circuit creation subsystem is not enabled. */
    370  dos_cc_enabled = 0;
    371 }
    372 
    373 /* Called when the consensus has changed. Do appropriate actions for the
    374 * circuit creation subsystem. */
    375 static void
    376 cc_consensus_has_changed(const networkstatus_t *ns)
    377 {
    378  /* Looking at the consensus, is the circuit creation subsystem enabled? If
    379   * not and it was enabled before, clean it up. */
    380  if (dos_cc_enabled && !get_param_cc_enabled(ns)) {
    381    cc_free_all();
    382  }
    383 }
    384 
    385 /** Return the number of circuits we allow per second under the current
    386 *  configuration. */
    387 STATIC uint64_t
    388 get_circuit_rate_per_second(void)
    389 {
    390  return dos_cc_circuit_rate;
    391 }
    392 
    393 /* Given the circuit creation client statistics object, refill the circuit
    394 * bucket if needed. This also works if the bucket was never filled in the
    395 * first place. The addr is only used for logging purposes. */
    396 STATIC void
    397 cc_stats_refill_bucket(cc_client_stats_t *stats, const tor_addr_t *addr)
    398 {
    399  uint32_t new_circuit_bucket_count;
    400  uint64_t num_token, elapsed_time_last_refill = 0, circuit_rate = 0;
    401  time_t now;
    402  int64_t last_refill_ts;
    403 
    404  tor_assert(stats);
    405  tor_assert(addr);
    406 
    407  now = approx_time();
    408  last_refill_ts = (int64_t)stats->last_circ_bucket_refill_ts;
    409 
    410  /* If less than a second has elapsed, don't add any tokens.
    411   * Note: If a relay's clock is ever 0, any new clients won't get a refill
    412   * until the next second. But a relay that thinks it is 1970 will never
    413   * validate the public consensus. */
    414  if ((int64_t)now == last_refill_ts) {
    415    goto done;
    416  }
    417 
    418  /* At this point, we know we might need to add token to the bucket. We'll
    419   * first get the circuit rate that is how many circuit are we allowed to do
    420   * per second. */
    421  circuit_rate = get_circuit_rate_per_second();
    422 
    423  /* We've never filled the bucket so fill it with the maximum being the burst
    424   * and we are done.
    425   * Note: If a relay's clock is ever 0, all clients that were last refilled
    426   * in that zero second will get a full refill here. */
    427  if (last_refill_ts == 0) {
    428    num_token = dos_cc_circuit_burst;
    429    goto end;
    430  }
    431 
    432  /* Our clock jumped backward so fill it up to the maximum. Not filling it
    433   * could trigger a detection for a valid client. Also, if the clock jumped
    434   * negative but we didn't notice until the elapsed time became positive
    435   * again, then we potentially spent many seconds not refilling the bucket
    436   * when we should have been refilling it. But the fact that we didn't notice
    437   * until now means that no circuit creation requests came in during that
    438   * time, so the client doesn't end up punished that much from this hopefully
    439   * rare situation.*/
    440  if ((int64_t)now < last_refill_ts) {
    441    /* Use the maximum allowed value of token. */
    442    num_token = dos_cc_circuit_burst;
    443    goto end;
    444  }
    445 
    446  /* How many seconds have elapsed between now and the last refill?
    447   * This subtraction can't underflow, because now >= last_refill_ts.
    448   * And it can't overflow, because INT64_MAX - (-INT64_MIN) == UINT64_MAX. */
    449  elapsed_time_last_refill = (uint64_t)now - last_refill_ts;
    450 
    451  /* If the elapsed time is very large, it means our clock jumped forward.
    452   * If the multiplication would overflow, use the maximum allowed value. */
    453  if (elapsed_time_last_refill > UINT32_MAX) {
    454    num_token = dos_cc_circuit_burst;
    455    goto end;
    456  }
    457 
    458  /* Compute how many circuits we are allowed in that time frame which we'll
    459   * add to the bucket. This can't overflow, because both multiplicands
    460   * are less than or equal to UINT32_MAX, and num_token is uint64_t. */
    461  num_token = elapsed_time_last_refill * circuit_rate;
    462 
    463 end:
    464  /* If the sum would overflow, use the maximum allowed value. */
    465  if (num_token > UINT32_MAX - stats->circuit_bucket) {
    466    new_circuit_bucket_count = dos_cc_circuit_burst;
    467  } else {
    468    /* We cap the bucket to the burst value else this could overflow uint32_t
    469     * over time. */
    470    new_circuit_bucket_count = MIN(stats->circuit_bucket + (uint32_t)num_token,
    471                                   dos_cc_circuit_burst);
    472  }
    473 
    474  /* This function is not allowed to make the bucket count larger than the
    475   * burst value */
    476  tor_assert_nonfatal(new_circuit_bucket_count <= dos_cc_circuit_burst);
    477  /* This function is not allowed to make the bucket count smaller, unless it
    478   * is decreasing it to a newly configured, lower burst value. We allow the
    479   * bucket to stay the same size, in case the circuit rate is zero. */
    480  tor_assert_nonfatal(new_circuit_bucket_count >= stats->circuit_bucket ||
    481                      new_circuit_bucket_count == dos_cc_circuit_burst);
    482 
    483  log_debug(LD_DOS, "DoS address %s has its circuit bucket value: %" PRIu32
    484                    ". Filling it to %" PRIu32 ". Circuit rate is %" PRIu64
    485                    ". Elapsed time is %" PRIi64,
    486            fmt_addr(addr), stats->circuit_bucket, new_circuit_bucket_count,
    487            circuit_rate, (int64_t)elapsed_time_last_refill);
    488 
    489  stats->circuit_bucket = new_circuit_bucket_count;
    490  stats->last_circ_bucket_refill_ts = now;
    491 
    492 done:
    493  return;
    494 }
    495 
    496 /* Return true iff the circuit bucket is down to 0 and the number of
    497 * concurrent connections is greater or equal the minimum threshold set the
    498 * consensus parameter. */
    499 static int
    500 cc_has_exhausted_circuits(const dos_client_stats_t *stats)
    501 {
    502  tor_assert(stats);
    503  return stats->cc_stats.circuit_bucket == 0 &&
    504         stats->conn_stats.concurrent_count >= dos_cc_min_concurrent_conn;
    505 }
    506 
    507 /* Mark client address by setting a timestamp in the stats object which tells
    508 * us until when it is marked as positively detected. */
    509 static void
    510 cc_mark_client(cc_client_stats_t *stats)
    511 {
    512  tor_assert(stats);
    513  /* We add a random offset of a maximum of half the defense time so it is
    514   * less predictable. */
    515  stats->marked_until_ts =
    516    approx_time() + dos_cc_defense_time_period +
    517    crypto_rand_int_range(1, dos_cc_defense_time_period / 2);
    518 }
    519 
    520 /* Return true iff the given channel address is marked as malicious. This is
    521 * called a lot and part of the fast path of handling cells. It has to remain
    522 * as fast as we can. */
    523 static int
    524 cc_channel_addr_is_marked(channel_t *chan)
    525 {
    526  time_t now;
    527  tor_addr_t addr;
    528  clientmap_entry_t *entry;
    529  cc_client_stats_t *stats = NULL;
    530 
    531  if (chan == NULL) {
    532    goto end;
    533  }
    534  /* Must be a client connection else we ignore. */
    535  if (!channel_is_client(chan)) {
    536    goto end;
    537  }
    538  /* Without an IP address, nothing can work. */
    539  if (!channel_get_addr_if_possible(chan, &addr)) {
    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    /* We can have a connection creating circuits but not tracked by the geoip
    547     * cache. Once this DoS subsystem is enabled, we can end up here with no
    548     * entry for the channel. */
    549    goto end;
    550  }
    551  now = approx_time();
    552  stats = &entry->dos_stats.cc_stats;
    553 
    554 end:
    555  return stats && stats->marked_until_ts >= now;
    556 }
    557 
    558 /* Concurrent connection private API. */
    559 
    560 /* Mark client connection stats by setting a timestamp which tells us until
    561 * when it is marked as positively detected. */
    562 static void
    563 conn_mark_client(conn_client_stats_t *stats)
    564 {
    565  tor_assert(stats);
    566 
    567  /* We add a random offset of a maximum of half the defense time so it is
    568   * less predictable and thus more difficult to game. */
    569  stats->marked_until_ts =
    570    approx_time() + dos_conn_connect_defense_time_period +
    571    crypto_rand_int_range(1, dos_conn_connect_defense_time_period / 2);
    572 }
    573 
    574 /* Free everything for the connection DoS mitigation subsystem. */
    575 static void
    576 conn_free_all(void)
    577 {
    578  dos_conn_enabled = 0;
    579 }
    580 
    581 /* Called when the consensus has changed. Do appropriate actions for the
    582 * connection mitigation subsystem. */
    583 static void
    584 conn_consensus_has_changed(const networkstatus_t *ns)
    585 {
    586  /* Looking at the consensus, is the connection mitigation subsystem enabled?
    587   * If not and it was enabled before, clean it up. */
    588  if (dos_conn_enabled && !get_param_conn_enabled(ns)) {
    589    conn_free_all();
    590  }
    591 }
    592 
    593 /** Called when a new client connection has arrived. The following will update
    594 * the client connection statistics.
    595 *
    596 * The addr is used for logging purposes only.
    597 *
    598 * If the connect counter reaches its limit, it is marked. */
    599 static void
    600 conn_update_on_connect(conn_client_stats_t *stats, const tor_addr_t *addr)
    601 {
    602  tor_assert(stats);
    603  tor_assert(addr);
    604 
    605  /* Update concurrent count for this new connect. */
    606  stats->concurrent_count++;
    607 
    608  /* Refill connect connection count. */
    609  token_bucket_ctr_refill(&stats->connect_count,
    610                          (uint32_t) monotime_coarse_absolute_sec());
    611 
    612  /* Decrement counter for this new connection. */
    613  if (token_bucket_ctr_get(&stats->connect_count) > 0) {
    614    token_bucket_ctr_dec(&stats->connect_count, 1);
    615  }
    616 
    617  /* Assess connect counter. Mark it if counter is down to 0 and we haven't
    618   * marked it before or it was reset. This is to avoid to re-mark it over and
    619   * over again extending continuously the blocked time. */
    620  if (token_bucket_ctr_get(&stats->connect_count) == 0 &&
    621      stats->marked_until_ts == 0) {
    622    conn_mark_client(stats);
    623  }
    624 
    625  log_debug(LD_DOS, "Client address %s has now %u concurrent connections. "
    626                    "Remaining %" TOR_PRIuSZ "/sec connections are allowed.",
    627            fmt_addr(addr), stats->concurrent_count,
    628            token_bucket_ctr_get(&stats->connect_count));
    629 }
    630 
    631 /** Called when a client connection is closed. The following will update
    632 * the client connection statistics.
    633 *
    634 * The addr is used for logging purposes only. */
    635 static void
    636 conn_update_on_close(conn_client_stats_t *stats, const tor_addr_t *addr)
    637 {
    638  /* Extra super duper safety. Going below 0 means an underflow which could
    639   * lead to most likely a false positive. In theory, this should never happen
    640   * but let's be extra safe. */
    641  if (BUG(stats->concurrent_count == 0)) {
    642    return;
    643  }
    644 
    645  stats->concurrent_count--;
    646  log_debug(LD_DOS, "Client address %s has lost a connection. Concurrent "
    647                    "connections are now at %u",
    648            fmt_addr(addr), stats->concurrent_count);
    649 }
    650 
    651 /* General private API */
    652 
    653 /* Return true iff we have at least one DoS detection enabled. This is used to
    654 * decide if we need to allocate any kind of high level DoS object. */
    655 static inline int
    656 dos_is_enabled(void)
    657 {
    658  return (dos_cc_enabled || dos_conn_enabled);
    659 }
    660 
    661 /* Circuit creation public API. */
    662 
    663 /** Return the number of rejected circuits. */
    664 uint64_t
    665 dos_get_num_cc_rejected(void)
    666 {
    667  return cc_num_rejected_cells;
    668 }
    669 
    670 /** Return the number of marked addresses. */
    671 uint32_t
    672 dos_get_num_cc_marked_addr(void)
    673 {
    674  return cc_num_marked_addrs;
    675 }
    676 
    677 /** Return the number of marked addresses due to max queue limit reached. */
    678 uint32_t
    679 dos_get_num_cc_marked_addr_maxq(void)
    680 {
    681  return cc_num_marked_addrs_max_queue;
    682 }
    683 
    684 /** Return number of concurrent connections rejected. */
    685 uint64_t
    686 dos_get_num_conn_addr_rejected(void)
    687 {
    688  return conn_num_addr_rejected;
    689 }
    690 
    691 /** Return the number of connection rejected. */
    692 uint64_t
    693 dos_get_num_conn_addr_connect_rejected(void)
    694 {
    695  return conn_num_addr_connect_rejected;
    696 }
    697 
    698 /** Return the number of single hop refused. */
    699 uint64_t
    700 dos_get_num_single_hop_refused(void)
    701 {
    702  return num_single_hop_client_refused;
    703 }
    704 
    705 /* Called when a CREATE cell is received from the given channel. */
    706 void
    707 dos_cc_new_create_cell(channel_t *chan)
    708 {
    709  tor_addr_t addr;
    710  clientmap_entry_t *entry;
    711 
    712  tor_assert(chan);
    713 
    714  /* Skip everything if not enabled. */
    715  if (!dos_cc_enabled) {
    716    goto end;
    717  }
    718 
    719  /* Must be a client connection else we ignore. */
    720  if (!channel_is_client(chan)) {
    721    goto end;
    722  }
    723  /* Without an IP address, nothing can work. */
    724  if (!channel_get_addr_if_possible(chan, &addr)) {
    725    goto end;
    726  }
    727 
    728  /* We are only interested in client connection from the geoip cache. */
    729  entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
    730  if (entry == NULL) {
    731    /* We can have a connection creating circuits but not tracked by the geoip
    732     * cache. Once this DoS subsystem is enabled, we can end up here with no
    733     * entry for the channel. */
    734    goto end;
    735  }
    736 
    737  /* General comment. Even though the client can already be marked as
    738   * malicious, we continue to track statistics. If it keeps going above
    739   * threshold while marked, the defense period time will grow longer. There
    740   * is really no point at unmarking a client that keeps DoSing us. */
    741 
    742  /* First of all, we'll try to refill the circuit bucket opportunistically
    743   * before we assess. */
    744  cc_stats_refill_bucket(&entry->dos_stats.cc_stats, &addr);
    745 
    746  /* Take a token out of the circuit bucket if we are above 0 so we don't
    747   * underflow the bucket. */
    748  if (entry->dos_stats.cc_stats.circuit_bucket > 0) {
    749    entry->dos_stats.cc_stats.circuit_bucket--;
    750  }
    751 
    752  /* This is the detection. Assess at every CREATE cell if the client should
    753   * get marked as malicious. This should be kept as fast as possible. */
    754  if (cc_has_exhausted_circuits(&entry->dos_stats)) {
    755    /* If this is the first time we mark this entry, log it.
    756     * Under heavy DDoS, logging each time we mark would results in lots and
    757     * lots of logs. */
    758    if (entry->dos_stats.cc_stats.marked_until_ts == 0) {
    759      log_debug(LD_DOS, "Detected circuit creation DoS by address: %s",
    760                fmt_addr(&addr));
    761      cc_num_marked_addrs++;
    762    }
    763    cc_mark_client(&entry->dos_stats.cc_stats);
    764  }
    765 
    766 end:
    767  return;
    768 }
    769 
    770 /* Return the defense type that should be used for this circuit.
    771 *
    772 * This is part of the fast path and called a lot. */
    773 dos_cc_defense_type_t
    774 dos_cc_get_defense_type(channel_t *chan)
    775 {
    776  tor_assert(chan);
    777 
    778  /* Skip everything if not enabled. */
    779  if (!dos_cc_enabled) {
    780    goto end;
    781  }
    782 
    783  /* On an OR circuit, we'll check if the previous channel is a marked client
    784   * connection detected by our DoS circuit creation mitigation subsystem. */
    785  if (cc_channel_addr_is_marked(chan)) {
    786    /* We've just assess that this circuit should trigger a defense for the
    787     * cell it just seen. Note it down. */
    788    cc_num_rejected_cells++;
    789    return dos_cc_defense_type;
    790  }
    791 
    792 end:
    793  return DOS_CC_DEFENSE_NONE;
    794 }
    795 
    796 /* Concurrent connection detection public API. */
    797 
    798 /* Return true iff the given address is permitted to open another connection.
    799 * A defense value is returned for the caller to take appropriate actions. */
    800 dos_conn_defense_type_t
    801 dos_conn_addr_get_defense_type(const tor_addr_t *addr)
    802 {
    803  clientmap_entry_t *entry;
    804 
    805  tor_assert(addr);
    806 
    807  /* Skip everything if not enabled. */
    808  if (!dos_conn_enabled) {
    809    goto end;
    810  }
    811 
    812  /* We are only interested in client connection from the geoip cache. */
    813  entry = geoip_lookup_client(addr, NULL, GEOIP_CLIENT_CONNECT);
    814  if (entry == NULL) {
    815    goto end;
    816  }
    817 
    818  /* Is this address marked as making too many client connections? */
    819  if (entry->dos_stats.conn_stats.marked_until_ts >= approx_time()) {
    820    conn_num_addr_connect_rejected++;
    821    return dos_conn_defense_type;
    822  }
    823  /* Reset it to 0 here so that if the marked timestamp has expired that is
    824   * we've gone beyond it, we have to reset it so the detection can mark it
    825   * again in the future. */
    826  entry->dos_stats.conn_stats.marked_until_ts = 0;
    827 
    828  /* Need to be above the maximum concurrent connection count to trigger a
    829   * defense. */
    830  if (entry->dos_stats.conn_stats.concurrent_count >
    831      dos_conn_max_concurrent_count) {
    832    conn_num_addr_rejected++;
    833    return dos_conn_defense_type;
    834  }
    835 
    836 end:
    837  return DOS_CONN_DEFENSE_NONE;
    838 }
    839 
    840 /* Stream creation public API. */
    841 
    842 /** Return the number of rejected stream and resolve. */
    843 uint64_t
    844 dos_get_num_stream_rejected(void)
    845 {
    846  return stream_num_rejected;
    847 }
    848 
    849 /* Return the action to take against a BEGIN or RESOLVE cell. Return
    850 *  DOS_STREAM_DEFENSE_NONE when no action should be taken.
    851 *  Increment the appropriate counter when the cell was found to go over a
    852 *  limit. */
    853 dos_stream_defense_type_t
    854 dos_stream_new_begin_or_resolve_cell(or_circuit_t *circ)
    855 {
    856  if (!dos_stream_enabled || circ == NULL)
    857    return DOS_STREAM_DEFENSE_NONE;
    858 
    859  token_bucket_ctr_refill(&circ->stream_limiter,
    860                          (uint32_t) monotime_coarse_absolute_sec());
    861 
    862  if (token_bucket_ctr_get(&circ->stream_limiter) > 0) {
    863    token_bucket_ctr_dec(&circ->stream_limiter, 1);
    864    return DOS_STREAM_DEFENSE_NONE;
    865  }
    866  /* if defense type is DOS_STREAM_DEFENSE_NONE but DoSStreamEnabled is true,
    867   * we count offending cells as rejected, despite them being actually
    868   * accepted. */
    869  ++stream_num_rejected;
    870  return dos_stream_defense_type;
    871 }
    872 
    873 /* Initialize the token bucket for stream rate limit on a circuit. */
    874 void
    875 dos_stream_init_circ_tbf(or_circuit_t *circ)
    876 {
    877  token_bucket_ctr_init(&circ->stream_limiter, dos_stream_rate,
    878                        dos_stream_burst,
    879                        (uint32_t) monotime_coarse_absolute_sec());
    880 }
    881 
    882 /* General API */
    883 
    884 /* Take any appropriate actions for the given geoip entry that is about to get
    885 * freed. This is called for every entry that is being freed.
    886 *
    887 * This function will clear out the connection tracked flag if the concurrent
    888 * count of the entry is above 0 so if those connections end up being seen by
    889 * this subsystem, we won't try to decrement the counter for a new geoip entry
    890 * that might have been added after this call for the same address. */
    891 void
    892 dos_geoip_entry_about_to_free(const clientmap_entry_t *geoip_ent)
    893 {
    894  tor_assert(geoip_ent);
    895 
    896  /* The count is down to 0 meaning no connections right now, we can safely
    897   * clear the geoip entry from the cache. */
    898  if (geoip_ent->dos_stats.conn_stats.concurrent_count == 0) {
    899    goto end;
    900  }
    901 
    902  /* For each connection matching the geoip entry address, we'll clear the
    903   * tracked flag because the entry is about to get removed from the geoip
    904   * cache. We do not try to decrement if the flag is not set. */
    905  SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
    906    if (conn->type == CONN_TYPE_OR) {
    907      or_connection_t *or_conn = TO_OR_CONN(conn);
    908      if (!tor_addr_compare(&geoip_ent->addr, &TO_CONN(or_conn)->addr,
    909                            CMP_EXACT)) {
    910        or_conn->tracked_for_dos_mitigation = 0;
    911      }
    912    }
    913  } SMARTLIST_FOREACH_END(conn);
    914 
    915 end:
    916  return;
    917 }
    918 
    919 /** A new geoip client entry has been allocated, initialize its DoS object. */
    920 void
    921 dos_geoip_entry_init(clientmap_entry_t *geoip_ent)
    922 {
    923  tor_assert(geoip_ent);
    924 
    925  /* Initialize the connection count counter with the rate and burst
    926   * parameters taken either from configuration or consensus.
    927   *
    928   * We do this even if the DoS connection detection is not enabled because it
    929   * can be enabled at runtime and these counters need to be valid. */
    930  token_bucket_ctr_init(&geoip_ent->dos_stats.conn_stats.connect_count,
    931                        dos_conn_connect_rate, dos_conn_connect_burst,
    932                        (uint32_t) monotime_coarse_absolute_sec());
    933 }
    934 
    935 /** Note that the given channel has sent outbound the maximum amount of cell
    936 * allowed on the next channel. */
    937 void
    938 dos_note_circ_max_outq(const channel_t *chan)
    939 {
    940  tor_addr_t addr;
    941  clientmap_entry_t *entry;
    942 
    943  tor_assert(chan);
    944 
    945  /* Skip everything if circuit creation defense is disabled. */
    946  if (!dos_cc_enabled) {
    947    goto end;
    948  }
    949 
    950  /* Must be a client connection else we ignore. */
    951  if (!channel_is_client(chan)) {
    952    goto end;
    953  }
    954  /* Without an IP address, nothing can work. */
    955  if (!channel_get_addr_if_possible(chan, &addr)) {
    956    goto end;
    957  }
    958 
    959  /* We are only interested in client connection from the geoip cache. */
    960  entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
    961  if (entry == NULL) {
    962    goto end;
    963  }
    964 
    965  /* Is the client marked? If yes, just ignore. */
    966  if (entry->dos_stats.cc_stats.marked_until_ts >= approx_time()) {
    967    goto end;
    968  }
    969 
    970  /* If max outq parameter is 0, it means disabled, just ignore. */
    971  if (dos_num_circ_max_outq == 0) {
    972    goto end;
    973  }
    974 
    975  entry->dos_stats.num_circ_max_cell_queue_size++;
    976 
    977  /* This is the detection. If we have reached the maximum amount of times a
    978   * client IP is allowed to reach this limit, mark client. */
    979  if (entry->dos_stats.num_circ_max_cell_queue_size >=
    980      dos_num_circ_max_outq) {
    981    /* Only account for this marked address if this is the first time we block
    982     * it else our counter is inflated with non unique entries. */
    983    if (entry->dos_stats.cc_stats.marked_until_ts == 0) {
    984      cc_num_marked_addrs_max_queue++;
    985    }
    986    log_info(LD_DOS, "Detected outbound max circuit queue from addr: %s",
    987             fmt_addr(&addr));
    988    cc_mark_client(&entry->dos_stats.cc_stats);
    989 
    990    /* Reset after being marked so once unmarked, we start back clean. */
    991    entry->dos_stats.num_circ_max_cell_queue_size = 0;
    992  }
    993 
    994 end:
    995  return;
    996 }
    997 
    998 /* Note down that we've just refused a single hop client. This increments a
    999 * counter later used for the heartbeat. */
   1000 void
   1001 dos_note_refuse_single_hop_client(void)
   1002 {
   1003  num_single_hop_client_refused++;
   1004 }
   1005 
   1006 /* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should
   1007 * be refused. */
   1008 int
   1009 dos_should_refuse_single_hop_client(void)
   1010 {
   1011  /* If we aren't a public relay, this shouldn't apply to anything. */
   1012  if (!public_server_mode(get_options())) {
   1013    return 0;
   1014  }
   1015 
   1016  if (dos_get_options()->DoSRefuseSingleHopClientRendezvous != -1) {
   1017    return dos_get_options()->DoSRefuseSingleHopClientRendezvous;
   1018  }
   1019 
   1020  return (int) networkstatus_get_param(NULL,
   1021                                       "DoSRefuseSingleHopClientRendezvous",
   1022                                       0 /* default */, 0, 1);
   1023 }
   1024 
   1025 /* Log a heartbeat message with some statistics. */
   1026 void
   1027 dos_log_heartbeat(void)
   1028 {
   1029  smartlist_t *elems = smartlist_new();
   1030 
   1031  /* Stats number coming from relay.c append_cell_to_circuit_queue(). */
   1032  smartlist_add_asprintf(elems,
   1033                         "%" PRIu64 " circuits killed with too many cells",
   1034                         stats_n_circ_max_cell_reached);
   1035 
   1036  if (dos_cc_enabled) {
   1037    smartlist_add_asprintf(elems,
   1038                           "%" PRIu64 " circuits rejected, "
   1039                           "%" PRIu32 " marked addresses, "
   1040                           "%" PRIu32 " marked addresses for max queue",
   1041                           cc_num_rejected_cells, cc_num_marked_addrs,
   1042                           cc_num_marked_addrs_max_queue);
   1043  } else {
   1044    smartlist_add_asprintf(elems, "[DoSCircuitCreationEnabled disabled]");
   1045  }
   1046 
   1047  if (dos_conn_enabled) {
   1048    smartlist_add_asprintf(elems,
   1049                           "%" PRIu64 " same address concurrent "
   1050                           "connections rejected", conn_num_addr_rejected);
   1051    smartlist_add_asprintf(elems,
   1052                           "%" PRIu64 " connections rejected",
   1053                           conn_num_addr_connect_rejected);
   1054  } else {
   1055    smartlist_add_asprintf(elems, "[DoSConnectionEnabled disabled]");
   1056  }
   1057 
   1058  if (dos_should_refuse_single_hop_client()) {
   1059    smartlist_add_asprintf(elems,
   1060                           "%" PRIu64 " single hop clients refused",
   1061                           num_single_hop_client_refused);
   1062  } else {
   1063    smartlist_add_asprintf(elems,
   1064                           "[DoSRefuseSingleHopClientRendezvous disabled]");
   1065  }
   1066 
   1067  if (dos_stream_enabled) {
   1068    smartlist_add_asprintf(elems,
   1069                           "%" PRIu64 " stream rejected",
   1070                           stream_num_rejected);
   1071  } else {
   1072    smartlist_add_asprintf(elems, "[DoSStreamCreationEnabled disabled]");
   1073  }
   1074 
   1075  /* HS DoS stats. */
   1076  smartlist_add_asprintf(elems,
   1077                         "%" PRIu64 " INTRODUCE2 rejected",
   1078                         hs_dos_get_intro2_rejected_count());
   1079 
   1080  char *msg = smartlist_join_strings(elems, ", ", 0, NULL);
   1081 
   1082  log_notice(LD_HEARTBEAT,
   1083             "Heartbeat: DoS mitigation since startup: %s.", msg);
   1084 
   1085  tor_free(msg);
   1086  SMARTLIST_FOREACH(elems, char *, e, tor_free(e));
   1087  smartlist_free(elems);
   1088 }
   1089 
   1090 /* Called when a new client connection has been established on the given
   1091 * address. */
   1092 void
   1093 dos_new_client_conn(or_connection_t *or_conn, const char *transport_name)
   1094 {
   1095  clientmap_entry_t *entry;
   1096 
   1097  tor_assert(or_conn);
   1098  tor_assert_nonfatal(!or_conn->tracked_for_dos_mitigation);
   1099 
   1100  /* Past that point, we know we have at least one DoS detection subsystem
   1101   * enabled so we'll start allocating stuff. */
   1102  if (!dos_is_enabled()) {
   1103    goto end;
   1104  }
   1105 
   1106  /* We are only interested in client connection from the geoip cache. */
   1107  entry = geoip_lookup_client(&TO_CONN(or_conn)->addr, transport_name,
   1108                              GEOIP_CLIENT_CONNECT);
   1109  if (BUG(entry == NULL)) {
   1110    /* Should never happen because we note down the address in the geoip
   1111     * cache before this is called. */
   1112    goto end;
   1113  }
   1114 
   1115  /* Update stats from this new connect. */
   1116  conn_update_on_connect(&entry->dos_stats.conn_stats,
   1117                         &TO_CONN(or_conn)->addr);
   1118 
   1119  or_conn->tracked_for_dos_mitigation = 1;
   1120 
   1121 end:
   1122  return;
   1123 }
   1124 
   1125 /* Called when a client connection for the given IP address has been closed. */
   1126 void
   1127 dos_close_client_conn(const or_connection_t *or_conn)
   1128 {
   1129  clientmap_entry_t *entry;
   1130 
   1131  tor_assert(or_conn);
   1132 
   1133  /* We have to decrement the count on tracked connection only even if the
   1134   * subsystem has been disabled at runtime because it might be re-enabled
   1135   * after and we need to keep a synchronized counter at all time. */
   1136  if (!or_conn->tracked_for_dos_mitigation) {
   1137    goto end;
   1138  }
   1139 
   1140  /* We are only interested in client connection from the geoip cache. */
   1141  entry = geoip_lookup_client(&TO_CONN(or_conn)->addr, NULL,
   1142                              GEOIP_CLIENT_CONNECT);
   1143  if (entry == NULL) {
   1144    /* This can happen because we can close a connection before the channel
   1145     * got to be noted down in the geoip cache. */
   1146    goto end;
   1147  }
   1148 
   1149  /* Update stats from this new close. */
   1150  conn_update_on_close(&entry->dos_stats.conn_stats, &TO_CONN(or_conn)->addr);
   1151 
   1152 end:
   1153  return;
   1154 }
   1155 
   1156 /* Called when the consensus has changed. We might have new consensus
   1157 * parameters to look at. */
   1158 void
   1159 dos_consensus_has_changed(const networkstatus_t *ns)
   1160 {
   1161  /* There are two ways to configure this subsystem, one at startup through
   1162   * dos_init() which is called when the options are parsed. And this one
   1163   * through the consensus. We don't want to enable any DoS mitigation if we
   1164   * aren't a public relay. */
   1165  if (!public_server_mode(get_options())) {
   1166    return;
   1167  }
   1168 
   1169  cc_consensus_has_changed(ns);
   1170  conn_consensus_has_changed(ns);
   1171 
   1172  /* We were already enabled or we just became enabled but either way, set the
   1173   * consensus parameters for all subsystems. */
   1174  set_dos_parameters(ns);
   1175 }
   1176 
   1177 /* Return true iff the DoS mitigation subsystem is enabled. */
   1178 int
   1179 dos_enabled(void)
   1180 {
   1181  return dos_is_enabled();
   1182 }
   1183 
   1184 /* Free everything from the Denial of Service subsystem. */
   1185 void
   1186 dos_free_all(void)
   1187 {
   1188  /* Free the circuit creation mitigation subsystem. It is safe to do this
   1189   * even if it wasn't initialized. */
   1190  cc_free_all();
   1191 
   1192  /* Free the connection mitigation subsystem. It is safe to do this even if
   1193   * it wasn't initialized. */
   1194  conn_free_all();
   1195 }
   1196 
   1197 /* Initialize the Denial of Service subsystem. */
   1198 void
   1199 dos_init(void)
   1200 {
   1201  /* To initialize, we only need to get the parameters. */
   1202  set_dos_parameters(NULL);
   1203 }