dos.c 24 KB

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