diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-08-10 12:35:06 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-08-10 12:35:06 -0400 |
commit | b7ed61167fb3ed9d3b623d008bf3360a3ffa95c4 (patch) | |
tree | f5d05295ceddc4f01e4accb33ec94a37bce35b11 /src/feature/relay | |
parent | 5980cb8a19e87b6d8b471de55eb659004fa97b59 (diff) | |
parent | a207511bb0cc86b20a5ed682898a74660efdd5b2 (diff) | |
download | tor-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.c | 41 | ||||
-rw-r--r-- | src/feature/relay/dns.h | 2 |
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" |