mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Merge remote-tracking branch 'tor-github/pr/239'
This commit is contained in:
commit
b7ed61167f
5
changes/bug18642
Normal file
5
changes/bug18642
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
o Minor features (denial-of-service avoidance):
|
||||||
|
- Make our OOM handler aware of the DNS cache so that it doesn't fill up
|
||||||
|
the memory. This check is important for our DoS mitigation subsystem.
|
||||||
|
Closes ticket 18642. Patch by Neel Chauhan
|
||||||
|
|
@ -64,6 +64,7 @@
|
|||||||
#include "lib/crypt_ops/crypto_rand.h"
|
#include "lib/crypt_ops/crypto_rand.h"
|
||||||
#include "lib/crypt_ops/crypto_util.h"
|
#include "lib/crypt_ops/crypto_util.h"
|
||||||
#include "feature/dircache/directory.h"
|
#include "feature/dircache/directory.h"
|
||||||
|
#include "feature/relay/dns.h"
|
||||||
#include "feature/stats/geoip.h"
|
#include "feature/stats/geoip.h"
|
||||||
#include "feature/hs/hs_cache.h"
|
#include "feature/hs/hs_cache.h"
|
||||||
#include "core/mainloop/main.h"
|
#include "core/mainloop/main.h"
|
||||||
@ -2538,6 +2539,8 @@ cell_queues_check_size(void)
|
|||||||
const size_t geoip_client_cache_total =
|
const size_t geoip_client_cache_total =
|
||||||
geoip_client_cache_total_allocation();
|
geoip_client_cache_total_allocation();
|
||||||
alloc += geoip_client_cache_total;
|
alloc += geoip_client_cache_total;
|
||||||
|
const size_t dns_cache_total = dns_cache_total_allocation();
|
||||||
|
alloc += dns_cache_total;
|
||||||
if (alloc >= get_options()->MaxMemInQueues_low_threshold) {
|
if (alloc >= get_options()->MaxMemInQueues_low_threshold) {
|
||||||
last_time_under_memory_pressure = approx_time();
|
last_time_under_memory_pressure = approx_time();
|
||||||
if (alloc >= get_options()->MaxMemInQueues) {
|
if (alloc >= get_options()->MaxMemInQueues) {
|
||||||
@ -2555,6 +2558,11 @@ cell_queues_check_size(void)
|
|||||||
(size_t)(get_options()->MaxMemInQueues / 10);
|
(size_t)(get_options()->MaxMemInQueues / 10);
|
||||||
alloc -= geoip_client_cache_handle_oom(now, bytes_to_remove);
|
alloc -= geoip_client_cache_handle_oom(now, bytes_to_remove);
|
||||||
}
|
}
|
||||||
|
if (dns_cache_total > get_options()->MaxMemInQueues / 5) {
|
||||||
|
const size_t bytes_to_remove =
|
||||||
|
dns_cache_total - (size_t)(get_options()->MaxMemInQueues / 10);
|
||||||
|
alloc -= dns_cache_handle_oom(now, bytes_to_remove);
|
||||||
|
}
|
||||||
circuits_handle_oom(alloc);
|
circuits_handle_oom(alloc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2076,14 +2076,21 @@ dns_cache_entry_count(void)
|
|||||||
return HT_SIZE(&cache_root);
|
return HT_SIZE(&cache_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the total size in bytes of the DNS cache. */
|
||||||
|
size_t
|
||||||
|
dns_cache_total_allocation(void)
|
||||||
|
{
|
||||||
|
return sizeof(struct cached_resolve_t) * dns_cache_entry_count() +
|
||||||
|
HT_MEM_USAGE(&cache_root);
|
||||||
|
}
|
||||||
|
|
||||||
/** Log memory information about our internal DNS cache at level 'severity'. */
|
/** Log memory information about our internal DNS cache at level 'severity'. */
|
||||||
void
|
void
|
||||||
dump_dns_mem_usage(int severity)
|
dump_dns_mem_usage(int severity)
|
||||||
{
|
{
|
||||||
/* This should never be larger than INT_MAX. */
|
/* This should never be larger than INT_MAX. */
|
||||||
int hash_count = dns_cache_entry_count();
|
int hash_count = dns_cache_entry_count();
|
||||||
size_t hash_mem = sizeof(struct cached_resolve_t) * hash_count;
|
size_t hash_mem = dns_cache_total_allocation();
|
||||||
hash_mem += HT_MEM_USAGE(&cache_root);
|
|
||||||
|
|
||||||
/* Print out the count and estimated size of our &cache_root. It undercounts
|
/* Print out the count and estimated size of our &cache_root. It undercounts
|
||||||
hostnames in cached reverse resolves.
|
hostnames in cached reverse resolves.
|
||||||
@ -2093,6 +2100,36 @@ dump_dns_mem_usage(int severity)
|
|||||||
(unsigned)hash_mem);
|
(unsigned)hash_mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do a round of OOM cleanup on all DNS entries. Return the amount of removed
|
||||||
|
* bytes. It is possible that the returned value is lower than min_remove_bytes
|
||||||
|
* if the caches get emptied out so the caller should be aware of this. */
|
||||||
|
size_t
|
||||||
|
dns_cache_handle_oom(time_t now, size_t min_remove_bytes)
|
||||||
|
{
|
||||||
|
time_t time_inc = 0;
|
||||||
|
size_t total_bytes_removed = 0;
|
||||||
|
size_t current_size = dns_cache_total_allocation();
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* If no DNS entries left, break loop. */
|
||||||
|
if (!dns_cache_entry_count())
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Get cutoff interval and remove entries. */
|
||||||
|
time_t cutoff = now + time_inc;
|
||||||
|
purge_expired_resolves(cutoff);
|
||||||
|
|
||||||
|
/* Update amount of bytes removed and array size. */
|
||||||
|
size_t bytes_removed = current_size - dns_cache_total_allocation();
|
||||||
|
current_size -= bytes_removed;
|
||||||
|
total_bytes_removed += bytes_removed;
|
||||||
|
|
||||||
|
time_inc += 3600; /* Increase time_inc by 1 hour. */
|
||||||
|
} while (total_bytes_removed < min_remove_bytes);
|
||||||
|
|
||||||
|
return total_bytes_removed;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DNS_CACHE
|
#ifdef DEBUG_DNS_CACHE
|
||||||
/** Exit with an assertion if the DNS cache is corrupt. */
|
/** Exit with an assertion if the DNS cache is corrupt. */
|
||||||
static void
|
static void
|
||||||
|
@ -38,7 +38,9 @@ void dns_launch_correctness_checks(void);
|
|||||||
int dns_seems_to_be_broken(void);
|
int dns_seems_to_be_broken(void);
|
||||||
int dns_seems_to_be_broken_for_ipv6(void);
|
int dns_seems_to_be_broken_for_ipv6(void);
|
||||||
void dns_reset_correctness_checks(void);
|
void dns_reset_correctness_checks(void);
|
||||||
|
size_t dns_cache_total_allocation(void);
|
||||||
void dump_dns_mem_usage(int severity);
|
void dump_dns_mem_usage(int severity);
|
||||||
|
size_t dns_cache_handle_oom(time_t now, size_t min_remove_bytes);
|
||||||
|
|
||||||
#ifdef DNS_PRIVATE
|
#ifdef DNS_PRIVATE
|
||||||
#include "feature/relay/dns_structs.h"
|
#include "feature/relay/dns_structs.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user