aboutsummaryrefslogtreecommitdiff
path: root/src/feature/relay
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-08-10 12:35:06 -0400
committerNick Mathewson <nickm@torproject.org>2018-08-10 12:35:06 -0400
commitb7ed61167fb3ed9d3b623d008bf3360a3ffa95c4 (patch)
treef5d05295ceddc4f01e4accb33ec94a37bce35b11 /src/feature/relay
parent5980cb8a19e87b6d8b471de55eb659004fa97b59 (diff)
parenta207511bb0cc86b20a5ed682898a74660efdd5b2 (diff)
downloadtor-b7ed61167fb3ed9d3b623d008bf3360a3ffa95c4.tar.gz
tor-b7ed61167fb3ed9d3b623d008bf3360a3ffa95c4.zip
Merge remote-tracking branch 'tor-github/pr/239'
Diffstat (limited to 'src/feature/relay')
-rw-r--r--src/feature/relay/dns.c41
-rw-r--r--src/feature/relay/dns.h2
2 files changed, 41 insertions, 2 deletions
diff --git a/src/feature/relay/dns.c b/src/feature/relay/dns.c
index f4e39dfd3d..48319b47c8 100644
--- a/src/feature/relay/dns.c
+++ b/src/feature/relay/dns.c
@@ -2076,14 +2076,21 @@ dns_cache_entry_count(void)
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'. */
void
dump_dns_mem_usage(int severity)
{
/* This should never be larger than INT_MAX. */
int hash_count = dns_cache_entry_count();
- size_t hash_mem = sizeof(struct cached_resolve_t) * hash_count;
- hash_mem += HT_MEM_USAGE(&cache_root);
+ size_t hash_mem = dns_cache_total_allocation();
/* Print out the count and estimated size of our &cache_root. It undercounts
hostnames in cached reverse resolves.
@@ -2093,6 +2100,36 @@ dump_dns_mem_usage(int severity)
(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
/** Exit with an assertion if the DNS cache is corrupt. */
static void
diff --git a/src/feature/relay/dns.h b/src/feature/relay/dns.h
index 69c1764b73..1dd6f903d1 100644
--- a/src/feature/relay/dns.h
+++ b/src/feature/relay/dns.h
@@ -38,7 +38,9 @@ void dns_launch_correctness_checks(void);
int dns_seems_to_be_broken(void);
int dns_seems_to_be_broken_for_ipv6(void);
void dns_reset_correctness_checks(void);
+size_t dns_cache_total_allocation(void);
void dump_dns_mem_usage(int severity);
+size_t dns_cache_handle_oom(time_t now, size_t min_remove_bytes);
#ifdef DNS_PRIVATE
#include "feature/relay/dns_structs.h"