dos.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. /* Copyright (c) 2018, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /*
  4. * \file dos.c
  5. * \brief Implement Denial of Service mitigation subsystem.
  6. */
  7. #define DOS_PRIVATE
  8. #include "or.h"
  9. #include "channel.h"
  10. #include "config.h"
  11. #include "geoip.h"
  12. #include "main.h"
  13. #include "networkstatus.h"
  14. #include "dos.h"
  15. /*
  16. * Circuit creation denial of service mitigation.
  17. *
  18. * Namespace used for this mitigation framework is "dos_cc_" where "cc" is for
  19. * Circuit Creation.
  20. */
  21. /* Is the circuit creation DoS mitigation enabled? */
  22. static unsigned int dos_cc_enabled = 0;
  23. /* Consensus parameters. They can be changed when a new consensus arrives.
  24. * They are initialized with the hardcoded default values. */
  25. static uint32_t dos_cc_min_concurrent_conn;
  26. static uint32_t dos_cc_circuit_rate_tenths;
  27. static uint32_t dos_cc_circuit_burst;
  28. static dos_cc_defense_type_t dos_cc_defense_type;
  29. static int32_t dos_cc_defense_time_period;
  30. /* Keep some stats for the heartbeat so we can report out. */
  31. static uint64_t cc_num_rejected_cells;
  32. static uint32_t cc_num_marked_addrs;
  33. /*
  34. * Concurrent connection denial of service mitigation.
  35. *
  36. * Namespace used for this mitigation framework is "dos_conn_".
  37. */
  38. /* Is the connection DoS mitigation enabled? */
  39. static unsigned int dos_conn_enabled = 0;
  40. /* Consensus parameters. They can be changed when a new consensus arrives.
  41. * They are initialized with the hardcoded default values. */
  42. static uint32_t dos_conn_max_concurrent_count;
  43. static dos_conn_defense_type_t dos_conn_defense_type;
  44. /* Keep some stats for the heartbeat so we can report out. */
  45. static uint64_t conn_num_addr_rejected;
  46. /*
  47. * General interface of the denial of service mitigation subsystem.
  48. */
  49. /* Return true iff the circuit creation mitigation is enabled. We look at the
  50. * consensus for this else a default value is returned. */
  51. MOCK_IMPL(STATIC unsigned int,
  52. get_param_cc_enabled, (const networkstatus_t *ns))
  53. {
  54. if (get_options()->DoSCircuitCreationEnabled != -1) {
  55. return get_options()->DoSCircuitCreationEnabled;
  56. }
  57. return !!networkstatus_get_param(ns, "DoSCircuitCreationEnabled",
  58. DOS_CC_ENABLED_DEFAULT, 0, 1);
  59. }
  60. /* Return the parameter for the minimum concurrent connection at which we'll
  61. * start counting circuit for a specific client address. */
  62. STATIC uint32_t
  63. get_param_cc_min_concurrent_connection(const networkstatus_t *ns)
  64. {
  65. if (get_options()->DoSCircuitCreationMinConnections) {
  66. return get_options()->DoSCircuitCreationMinConnections;
  67. }
  68. return networkstatus_get_param(ns, "DoSCircuitCreationMinConnections",
  69. DOS_CC_MIN_CONCURRENT_CONN_DEFAULT,
  70. 1, INT32_MAX);
  71. }
  72. /* Return the parameter for the time rate that is how many circuits over this
  73. * time span. */
  74. static uint32_t
  75. get_param_cc_circuit_rate_tenths(const networkstatus_t *ns)
  76. {
  77. /* This is in seconds. */
  78. if (get_options()->DoSCircuitCreationRateTenths) {
  79. return get_options()->DoSCircuitCreationRateTenths;
  80. }
  81. return networkstatus_get_param(ns, "DoSCircuitCreationRateTenths",
  82. DOS_CC_CIRCUIT_RATE_TENTHS_DEFAULT,
  83. 1, INT32_MAX);
  84. }
  85. /* Return the parameter for the maximum circuit count for the circuit time
  86. * rate. */
  87. STATIC uint32_t
  88. get_param_cc_circuit_burst(const networkstatus_t *ns)
  89. {
  90. if (get_options()->DoSCircuitCreationBurst) {
  91. return get_options()->DoSCircuitCreationBurst;
  92. }
  93. return networkstatus_get_param(ns, "DoSCircuitCreationBurst",
  94. DOS_CC_CIRCUIT_BURST_DEFAULT,
  95. 1, INT32_MAX);
  96. }
  97. /* Return the consensus parameter of the circuit creation defense type. */
  98. static uint32_t
  99. get_param_cc_defense_type(const networkstatus_t *ns)
  100. {
  101. if (get_options()->DoSCircuitCreationDefenseType) {
  102. return get_options()->DoSCircuitCreationDefenseType;
  103. }
  104. return networkstatus_get_param(ns, "DoSCircuitCreationDefenseType",
  105. DOS_CC_DEFENSE_TYPE_DEFAULT,
  106. DOS_CC_DEFENSE_NONE, DOS_CC_DEFENSE_MAX);
  107. }
  108. /* Return the consensus parameter of the defense time period which is how much
  109. * time should we defend against a malicious client address. */
  110. static int32_t
  111. get_param_cc_defense_time_period(const networkstatus_t *ns)
  112. {
  113. /* Time in seconds. */
  114. if (get_options()->DoSCircuitCreationDefenseTimePeriod) {
  115. return get_options()->DoSCircuitCreationDefenseTimePeriod;
  116. }
  117. return networkstatus_get_param(ns, "DoSCircuitCreationDefenseTimePeriod",
  118. DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT,
  119. 0, INT32_MAX);
  120. }
  121. /* Return true iff connection mitigation is enabled. We look at the consensus
  122. * for this else a default value is returned. */
  123. MOCK_IMPL(STATIC unsigned int,
  124. get_param_conn_enabled, (const networkstatus_t *ns))
  125. {
  126. if (get_options()->DoSConnectionEnabled != -1) {
  127. return get_options()->DoSConnectionEnabled;
  128. }
  129. return !!networkstatus_get_param(ns, "DoSConnectionEnabled",
  130. DOS_CONN_ENABLED_DEFAULT, 0, 1);
  131. }
  132. /* Return the consensus parameter for the maximum concurrent connection
  133. * allowed. */
  134. STATIC uint32_t
  135. get_param_conn_max_concurrent_count(const networkstatus_t *ns)
  136. {
  137. if (get_options()->DoSConnectionMaxConcurrentCount) {
  138. return get_options()->DoSConnectionMaxConcurrentCount;
  139. }
  140. return networkstatus_get_param(ns, "DoSConnectionMaxConcurrentCount",
  141. DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT,
  142. 1, INT32_MAX);
  143. }
  144. /* Return the consensus parameter of the connection defense type. */
  145. static uint32_t
  146. get_param_conn_defense_type(const networkstatus_t *ns)
  147. {
  148. if (get_options()->DoSConnectionDefenseType) {
  149. return get_options()->DoSConnectionDefenseType;
  150. }
  151. return networkstatus_get_param(ns, "DoSConnectionDefenseType",
  152. DOS_CONN_DEFENSE_TYPE_DEFAULT,
  153. DOS_CONN_DEFENSE_NONE, DOS_CONN_DEFENSE_MAX);
  154. }
  155. /* Set circuit creation parameters located in the consensus or their default
  156. * if none are present. Called at initialization or when the consensus
  157. * changes. */
  158. static void
  159. set_dos_parameters(const networkstatus_t *ns)
  160. {
  161. /* Get the default consensus param values. */
  162. dos_cc_enabled = get_param_cc_enabled(ns);
  163. dos_cc_min_concurrent_conn = get_param_cc_min_concurrent_connection(ns);
  164. dos_cc_circuit_rate_tenths = get_param_cc_circuit_rate_tenths(ns);
  165. dos_cc_circuit_burst = get_param_cc_circuit_burst(ns);
  166. dos_cc_defense_time_period = get_param_cc_defense_time_period(ns);
  167. dos_cc_defense_type = get_param_cc_defense_type(ns);
  168. /* Connection detection. */
  169. dos_conn_enabled = get_param_conn_enabled(ns);
  170. dos_conn_max_concurrent_count = get_param_conn_max_concurrent_count(ns);
  171. dos_conn_defense_type = get_param_conn_defense_type(ns);
  172. }
  173. /* Free everything for the circuit creation DoS mitigation subsystem. */
  174. static void
  175. cc_free_all(void)
  176. {
  177. /* If everything is freed, the circuit creation subsystem is not enabled. */
  178. dos_cc_enabled = 0;
  179. }
  180. /* Called when the consensus has changed. Do appropriate actions for the
  181. * circuit creation subsystem. */
  182. static void
  183. cc_consensus_has_changed(const networkstatus_t *ns)
  184. {
  185. /* Looking at the consensus, is the circuit creation subsystem enabled? If
  186. * not and it was enabled before, clean it up. */
  187. if (dos_cc_enabled && !get_param_cc_enabled(ns)) {
  188. cc_free_all();
  189. }
  190. }
  191. /** Return the number of circuits we allow per second under the current
  192. * configuration. */
  193. STATIC uint32_t
  194. get_circuit_rate_per_second(void)
  195. {
  196. int64_t circ_rate;
  197. /* We take the burst divided by the rate which is in tenths of a second so
  198. * convert to get a circuit rate per second. */
  199. circ_rate = dos_cc_circuit_rate_tenths / 10;
  200. if (circ_rate < 0) {
  201. /* Safety check, never allow it to go below 0 else the bucket will always
  202. * be empty resulting in every address to be detected. */
  203. circ_rate = 1;
  204. }
  205. /* Clamp it down to a 32 bit value because a rate of 2^32 circuits per
  206. * second is just too much in any circumstances. */
  207. if (circ_rate > UINT32_MAX) {
  208. circ_rate = UINT32_MAX;
  209. }
  210. return (uint32_t) circ_rate;
  211. }
  212. /* Given the circuit creation client statistics object, refill the circuit
  213. * bucket if needed. This also works if the bucket was never filled in the
  214. * first place. The addr is only used for logging purposes. */
  215. STATIC void
  216. cc_stats_refill_bucket(cc_client_stats_t *stats, const tor_addr_t *addr)
  217. {
  218. uint32_t new_circuit_bucket_count, circuit_rate = 0, num_token;
  219. time_t now, elapsed_time_last_refill;
  220. tor_assert(stats);
  221. tor_assert(addr);
  222. now = approx_time();
  223. /* We've never filled the bucket so fill it with the maximum being the burst
  224. * and we are done. */
  225. if (stats->last_circ_bucket_refill_ts == 0) {
  226. num_token = dos_cc_circuit_burst;
  227. goto end;
  228. }
  229. /* At this point, we know we might need to add token to the bucket. We'll
  230. * first compute the circuit rate that is how many circuit are we allowed to
  231. * do per second. */
  232. circuit_rate = get_circuit_rate_per_second();
  233. /* How many seconds have elapsed between now and the last refill? */
  234. elapsed_time_last_refill = now - stats->last_circ_bucket_refill_ts;
  235. /* If the elapsed time is below 0 it means our clock jumped backward so in
  236. * that case, lets be safe and fill it up to the maximum. Not filling it
  237. * could trigger a detection for a valid client. Also, if the clock jumped
  238. * negative but we didn't notice until the elapsed time became positive
  239. * again, then we potentially spent many seconds not refilling the bucket
  240. * when we should have been refilling it. But the fact that we didn't notice
  241. * until now means that no circuit creation requests came in during that
  242. * time, so the client doesn't end up punished that much from this hopefully
  243. * rare situation.*/
  244. if (elapsed_time_last_refill < 0) {
  245. /* Dividing the burst by the circuit rate gives us the time span that will
  246. * give us the maximum allowed value of token. */
  247. elapsed_time_last_refill = (dos_cc_circuit_burst / circuit_rate);
  248. }
  249. /* Compute how many circuits we are allowed in that time frame which we'll
  250. * add to the bucket. This can be big but it is cap to a maximum after. */
  251. num_token = elapsed_time_last_refill * circuit_rate;
  252. end:
  253. /* We cap the bucket to the burst value else this could grow to infinity
  254. * over time. */
  255. new_circuit_bucket_count = MIN(stats->circuit_bucket + num_token,
  256. dos_cc_circuit_burst);
  257. log_debug(LD_DOS, "DoS address %s has its circuit bucket value: %" PRIu32
  258. ". Filling it to %" PRIu32 ". Circuit rate is %" PRIu32,
  259. fmt_addr(addr), stats->circuit_bucket, new_circuit_bucket_count,
  260. circuit_rate);
  261. stats->circuit_bucket = new_circuit_bucket_count;
  262. stats->last_circ_bucket_refill_ts = now;
  263. return;
  264. }
  265. /* Return true iff the circuit bucket is down to 0 and the number of
  266. * concurrent connections is greater or equal the minimum threshold set the
  267. * consensus parameter. */
  268. static int
  269. cc_has_exhausted_circuits(const dos_client_stats_t *stats)
  270. {
  271. tor_assert(stats);
  272. return stats->cc_stats.circuit_bucket == 0 &&
  273. stats->concurrent_count >= dos_cc_min_concurrent_conn;
  274. }
  275. /* Mark client address by setting a timestamp in the stats object which tells
  276. * us until when it is marked as positively detected. */
  277. static void
  278. cc_mark_client(cc_client_stats_t *stats)
  279. {
  280. tor_assert(stats);
  281. /* We add a random offset of a maximum of half the defense time so it is
  282. * less predictable. */
  283. stats->marked_until_ts =
  284. approx_time() + dos_cc_defense_time_period +
  285. crypto_rand_int_range(1, dos_cc_defense_time_period / 2);
  286. }
  287. /* Return true iff the given channel address is marked as malicious. This is
  288. * called a lot and part of the fast path of handling cells. It has to remain
  289. * as fast as we can. */
  290. static int
  291. cc_channel_addr_is_marked(channel_t *chan)
  292. {
  293. time_t now;
  294. tor_addr_t addr;
  295. clientmap_entry_t *entry;
  296. cc_client_stats_t *stats = NULL;
  297. if (chan == NULL) {
  298. goto end;
  299. }
  300. /* Must be a client connection else we ignore. */
  301. if (!channel_is_client(chan)) {
  302. goto end;
  303. }
  304. /* Without an IP address, nothing can work. */
  305. if (!channel_get_addr_if_possible(chan, &addr)) {
  306. goto end;
  307. }
  308. /* We are only interested in client connection from the geoip cache. */
  309. entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
  310. if (entry == NULL) {
  311. /* We can have a connection creating circuits but not tracked by the geoip
  312. * cache. Once this DoS subsystem is enabled, we can end up here with no
  313. * entry for the channel. */
  314. goto end;
  315. }
  316. now = approx_time();
  317. stats = &entry->dos_stats.cc_stats;
  318. end:
  319. return stats && stats->marked_until_ts >= now;
  320. }
  321. /* Concurrent connection private API. */
  322. /* Free everything for the connection DoS mitigation subsystem. */
  323. static void
  324. conn_free_all(void)
  325. {
  326. dos_conn_enabled = 0;
  327. }
  328. /* Called when the consensus has changed. Do appropriate actions for the
  329. * connection mitigation subsystem. */
  330. static void
  331. conn_consensus_has_changed(const networkstatus_t *ns)
  332. {
  333. /* Looking at the consensus, is the connection mitigation subsystem enabled?
  334. * If not and it was enabled before, clean it up. */
  335. if (dos_conn_enabled && !get_param_conn_enabled(ns)) {
  336. conn_free_all();
  337. }
  338. }
  339. /* General private API */
  340. /* Return true iff we have at least one DoS detection enabled. This is used to
  341. * decide if we need to allocate any kind of high level DoS object. */
  342. static inline int
  343. dos_is_enabled(void)
  344. {
  345. return (dos_cc_enabled || dos_conn_enabled);
  346. }
  347. /* Circuit creation public API. */
  348. /* Called when a CREATE cell is received from the given channel. */
  349. void
  350. dos_cc_new_create_cell(channel_t *chan)
  351. {
  352. tor_addr_t addr;
  353. clientmap_entry_t *entry;
  354. tor_assert(chan);
  355. /* Skip everything if not enabled. */
  356. if (!dos_cc_enabled) {
  357. goto end;
  358. }
  359. /* Must be a client connection else we ignore. */
  360. if (!channel_is_client(chan)) {
  361. goto end;
  362. }
  363. /* Without an IP address, nothing can work. */
  364. if (!channel_get_addr_if_possible(chan, &addr)) {
  365. goto end;
  366. }
  367. /* We are only interested in client connection from the geoip cache. */
  368. entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
  369. if (entry == NULL) {
  370. /* We can have a connection creating circuits but not tracked by the geoip
  371. * cache. Once this DoS subsystem is enabled, we can end up here with no
  372. * entry for the channel. */
  373. goto end;
  374. }
  375. /* General comment. Even though the client can already be marked as
  376. * malicious, we continue to track statistics. If it keeps going above
  377. * threshold while marked, the defense period time will grow longer. There
  378. * is really no point at unmarking a client that keeps DoSing us. */
  379. /* First of all, we'll try to refill the circuit bucket opportunistically
  380. * before we assess. */
  381. cc_stats_refill_bucket(&entry->dos_stats.cc_stats, &addr);
  382. /* Take a token out of the circuit bucket if we are above 0 so we don't
  383. * underflow the bucket. */
  384. if (entry->dos_stats.cc_stats.circuit_bucket > 0) {
  385. entry->dos_stats.cc_stats.circuit_bucket--;
  386. }
  387. /* This is the detection. Assess at every CREATE cell if the client should
  388. * get marked as malicious. This should be kept as fast as possible. */
  389. if (cc_has_exhausted_circuits(&entry->dos_stats)) {
  390. /* If this is the first time we mark this entry, log it a info level.
  391. * Under heavy DDoS, logging each time we mark would results in lots and
  392. * lots of logs. */
  393. if (entry->dos_stats.cc_stats.marked_until_ts == 0) {
  394. log_debug(LD_DOS, "Detected circuit creation DoS by address: %s",
  395. fmt_addr(&addr));
  396. cc_num_marked_addrs++;
  397. }
  398. cc_mark_client(&entry->dos_stats.cc_stats);
  399. }
  400. end:
  401. return;
  402. }
  403. /* Return the defense type that should be used for this circuit.
  404. *
  405. * This is part of the fast path and called a lot. */
  406. dos_cc_defense_type_t
  407. dos_cc_get_defense_type(channel_t *chan)
  408. {
  409. tor_assert(chan);
  410. /* Skip everything if not enabled. */
  411. if (!dos_cc_enabled) {
  412. goto end;
  413. }
  414. /* On an OR circuit, we'll check if the previous channel is a marked client
  415. * connection detected by our DoS circuit creation mitigation subsystem. */
  416. if (cc_channel_addr_is_marked(chan)) {
  417. /* We've just assess that this circuit should trigger a defense for the
  418. * cell it just seen. Note it down. */
  419. cc_num_rejected_cells++;
  420. return dos_cc_defense_type;
  421. }
  422. end:
  423. return DOS_CC_DEFENSE_NONE;
  424. }
  425. /* Concurrent connection detection public API. */
  426. /* Return true iff the given address is permitted to open another connection.
  427. * A defense value is returned for the caller to take appropriate actions. */
  428. dos_conn_defense_type_t
  429. dos_conn_addr_get_defense_type(const tor_addr_t *addr)
  430. {
  431. clientmap_entry_t *entry;
  432. tor_assert(addr);
  433. /* Skip everything if not enabled. */
  434. if (!dos_conn_enabled) {
  435. goto end;
  436. }
  437. /* We are only interested in client connection from the geoip cache. */
  438. entry = geoip_lookup_client(addr, NULL, GEOIP_CLIENT_CONNECT);
  439. if (entry == NULL) {
  440. goto end;
  441. }
  442. /* Need to be above the maximum concurrent connection count to trigger a
  443. * defense. */
  444. if (entry->dos_stats.concurrent_count > dos_conn_max_concurrent_count) {
  445. conn_num_addr_rejected++;
  446. return dos_conn_defense_type;
  447. }
  448. end:
  449. return DOS_CONN_DEFENSE_NONE;
  450. }
  451. /* General API */
  452. /* Called when a new client connection has been established on the given
  453. * address. */
  454. void
  455. dos_new_client_conn(or_connection_t *or_conn)
  456. {
  457. clientmap_entry_t *entry;
  458. tor_assert(or_conn);
  459. /* Past that point, we know we have at least one DoS detection subsystem
  460. * enabled so we'll start allocating stuff. */
  461. if (!dos_is_enabled()) {
  462. goto end;
  463. }
  464. /* We are only interested in client connection from the geoip cache. */
  465. entry = geoip_lookup_client(&or_conn->real_addr, NULL,
  466. GEOIP_CLIENT_CONNECT);
  467. if (BUG(entry == NULL)) {
  468. /* Should never happen because we note down the address in the geoip
  469. * cache before this is called. */
  470. goto end;
  471. }
  472. entry->dos_stats.concurrent_count++;
  473. or_conn->tracked_for_dos_mitigation = 1;
  474. log_debug(LD_DOS, "Client address %s has now %u concurrent connections.",
  475. fmt_addr(&or_conn->real_addr),
  476. entry->dos_stats.concurrent_count);
  477. end:
  478. return;
  479. }
  480. /* Called when a client connection for the given IP address has been closed. */
  481. void
  482. dos_close_client_conn(const or_connection_t *or_conn)
  483. {
  484. clientmap_entry_t *entry;
  485. tor_assert(or_conn);
  486. /* We have to decrement the count on tracked connection only even if the
  487. * subsystem has been disabled at runtime because it might be re-enabled
  488. * after and we need to keep a synchronized counter at all time. */
  489. if (!or_conn->tracked_for_dos_mitigation) {
  490. goto end;
  491. }
  492. /* We are only interested in client connection from the geoip cache. */
  493. entry = geoip_lookup_client(&or_conn->real_addr, NULL,
  494. GEOIP_CLIENT_CONNECT);
  495. if (entry == NULL) {
  496. /* This can happen because we can close a connection before the channel
  497. * got to be noted down in the geoip cache. */
  498. goto end;
  499. }
  500. /* Extra super duper safety. Going below 0 means an underflow which could
  501. * lead to most likely a false positive. In theory, this should never happen
  502. * but lets be extra safe. */
  503. if (BUG(entry->dos_stats.concurrent_count == 0)) {
  504. goto end;
  505. }
  506. entry->dos_stats.concurrent_count--;
  507. log_debug(LD_DOS, "Client address %s has lost a connection. Concurrent "
  508. "connections are now at %u",
  509. fmt_addr(&or_conn->real_addr),
  510. entry->dos_stats.concurrent_count);
  511. end:
  512. return;
  513. }
  514. /* Called when the consensus has changed. We might have new consensus
  515. * parameters to look at. */
  516. void
  517. dos_consensus_has_changed(const networkstatus_t *ns)
  518. {
  519. cc_consensus_has_changed(ns);
  520. conn_consensus_has_changed(ns);
  521. /* We were already enabled or we just became enabled but either way, set the
  522. * consensus parameters for all subsystems. */
  523. set_dos_parameters(ns);
  524. }
  525. /* Return true iff the DoS mitigation subsystem is enabled. */
  526. int
  527. dos_enabled(void)
  528. {
  529. return dos_is_enabled();
  530. }
  531. /* Free everything from the Denial of Service subsystem. */
  532. void
  533. dos_free_all(void)
  534. {
  535. /* Free the circuit creation mitigation subsystem. It is safe to do this
  536. * even if it wasn't initialized. */
  537. cc_free_all();
  538. /* Free the connection mitigation subsystem. It is safe to do this even if
  539. * it wasn't initialized. */
  540. conn_free_all();
  541. }
  542. /* Initialize the Denial of Service subsystem. */
  543. void
  544. dos_init(void)
  545. {
  546. /* To initialize, we only need to get the parameters. */
  547. set_dos_parameters(NULL);
  548. }