aboutsummaryrefslogtreecommitdiff
path: root/src/feature/relay/dns.c
diff options
context:
space:
mode:
authorNeel Chauhan <neel@neelc.org>2018-07-16 17:36:22 -0400
committerNeel Chauhan <neel@neelc.org>2018-07-17 09:19:27 -0400
commit32db806dfa85b016a2d56d0d5248f17c34b690c4 (patch)
treec503d6ffcd6e160fb4f9deb7e8c6ddbe95d2f0dc /src/feature/relay/dns.c
parentd807ca1b014e27a2808959dba1a37a0c1d53240f (diff)
downloadtor-32db806dfa85b016a2d56d0d5248f17c34b690c4.tar.gz
tor-32db806dfa85b016a2d56d0d5248f17c34b690c4.zip
Teach the OOM handler about the DNS cache
Diffstat (limited to 'src/feature/relay/dns.c')
-rw-r--r--src/feature/relay/dns.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/feature/relay/dns.c b/src/feature/relay/dns.c
index 8a49829d55..48319b47c8 100644
--- a/src/feature/relay/dns.c
+++ b/src/feature/relay/dns.c
@@ -2100,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