diff --git a/dnscrypt-proxy/config.go b/dnscrypt-proxy/config.go index 07e38610..7aaca97c 100644 --- a/dnscrypt-proxy/config.go +++ b/dnscrypt-proxy/config.go @@ -33,6 +33,8 @@ type Config struct { Cache bool CacheSize int `toml:"cache_size"` CacheNegTTL uint32 `toml:"cache_neg_ttl"` + CacheNegMinTTL uint32 `toml:"cache_neg_min_ttl"` + CacheNegMaxTTL uint32 `toml:"cache_neg_max_ttl"` CacheMinTTL uint32 `toml:"cache_min_ttl"` CacheMaxTTL uint32 `toml:"cache_max_ttl"` QueryLog QueryLogConfig `toml:"query_log"` @@ -73,7 +75,9 @@ func newConfig() Config { EphemeralKeys: false, Cache: true, CacheSize: 512, - CacheNegTTL: 60, + CacheNegTTL: 0, + CacheNegMinTTL: 60, + CacheNegMaxTTL: 600, CacheMinTTL: 60, CacheMaxTTL: 8600, SourceRequireNoLog: true, @@ -265,7 +269,15 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error { proxy.pluginBlockIPv6 = config.BlockIPv6 proxy.cache = config.Cache proxy.cacheSize = config.CacheSize - proxy.cacheNegTTL = config.CacheNegTTL + + if config.CacheNegTTL > 0 { + proxy.cacheNegMinTTL = config.CacheNegTTL + proxy.cacheNegMaxTTL = config.CacheNegTTL + } else { + proxy.cacheNegMinTTL = config.CacheNegMinTTL + proxy.cacheNegMaxTTL = config.CacheNegMaxTTL + } + proxy.cacheMinTTL = config.CacheMinTTL proxy.cacheMaxTTL = config.CacheMaxTTL diff --git a/dnscrypt-proxy/dnsutils.go b/dnscrypt-proxy/dnsutils.go index 75cee609..098770c1 100644 --- a/dnscrypt-proxy/dnsutils.go +++ b/dnscrypt-proxy/dnsutils.go @@ -71,18 +71,37 @@ func StripTrailingDot(str string) string { return str } -func getMinTTL(msg *dns.Msg, minTTL uint32, maxTTL uint32, negCacheMinTTL uint32) time.Duration { - if msg.Rcode != dns.RcodeSuccess || len(msg.Answer) <= 0 { - return time.Duration(negCacheMinTTL) * time.Second +func getMinTTL(msg *dns.Msg, minTTL uint32, maxTTL uint32, cacheNegMinTTL uint32, cacheNegMaxTTL uint32) time.Duration { + if (msg.Rcode != dns.RcodeSuccess && msg.Rcode != dns.RcodeNameError) || (len(msg.Answer) <= 0 && len(msg.Ns) <= 0) { + return time.Duration(cacheNegMinTTL) * time.Second } - ttl := uint32(maxTTL) - for _, rr := range msg.Answer { - if rr.Header().Ttl < ttl { - ttl = rr.Header().Ttl + var ttl uint32 + if msg.Rcode == dns.RcodeSuccess { + ttl = uint32(maxTTL) + } else { + ttl = uint32(cacheNegMaxTTL) + } + if len(msg.Answer) > 0 { + for _, rr := range msg.Answer { + if rr.Header().Ttl < ttl { + ttl = rr.Header().Ttl + } + } + } else { + for _, rr := range msg.Ns { + if rr.Header().Ttl < ttl { + ttl = rr.Header().Ttl + } } } - if ttl < minTTL { - ttl = minTTL + if msg.Rcode == dns.RcodeSuccess { + if ttl < minTTL { + ttl = minTTL + } + } else { + if ttl < cacheNegMinTTL { + ttl = cacheNegMinTTL + } } return time.Duration(ttl) * time.Second } diff --git a/dnscrypt-proxy/example-dnscrypt-proxy.toml b/dnscrypt-proxy/example-dnscrypt-proxy.toml index 411852a9..8d015b7e 100644 --- a/dnscrypt-proxy/example-dnscrypt-proxy.toml +++ b/dnscrypt-proxy/example-dnscrypt-proxy.toml @@ -238,9 +238,14 @@ cache_min_ttl = 600 cache_max_ttl = 86400 -## TTL for negatively cached entries +## Minimum TTL for negatively cached entries -cache_neg_ttl = 60 +cache_neg_min_ttl = 60 + + +## Maximum TTL for negatively cached entries + +cache_neg_max_ttl = 600 diff --git a/dnscrypt-proxy/plugin_cache.go b/dnscrypt-proxy/plugin_cache.go index 3c4f6b58..84b70bb1 100644 --- a/dnscrypt-proxy/plugin_cache.go +++ b/dnscrypt-proxy/plugin_cache.go @@ -56,7 +56,7 @@ func (plugin *PluginCacheResponse) Eval(pluginsState *PluginsState, msg *dns.Msg if err != nil { return err } - ttl := getMinTTL(msg, pluginsState.cacheMinTTL, pluginsState.cacheMaxTTL, pluginsState.cacheNegTTL) + ttl := getMinTTL(msg, pluginsState.cacheMinTTL, pluginsState.cacheMaxTTL, pluginsState.cacheNegMinTTL, pluginsState.cacheNegMaxTTL) cachedResponse := CachedResponse{ expiration: time.Now().Add(ttl), msg: *msg, diff --git a/dnscrypt-proxy/plugins.go b/dnscrypt-proxy/plugins.go index 329dced4..5c7c892b 100644 --- a/dnscrypt-proxy/plugins.go +++ b/dnscrypt-proxy/plugins.go @@ -35,7 +35,8 @@ type PluginsState struct { synthResponse *dns.Msg dnssec bool cacheSize int - cacheNegTTL uint32 + cacheNegMinTTL uint32 + cacheNegMaxTTL uint32 cacheMinTTL uint32 cacheMaxTTL uint32 } @@ -107,7 +108,8 @@ func NewPluginsState(proxy *Proxy, clientProto string, clientAddr *net.Addr) Plu clientProto: clientProto, clientAddr: clientAddr, cacheSize: proxy.cacheSize, - cacheNegTTL: proxy.cacheNegTTL, + cacheNegMinTTL: proxy.cacheNegMinTTL, + cacheNegMaxTTL: proxy.cacheNegMaxTTL, cacheMinTTL: proxy.cacheMinTTL, cacheMaxTTL: proxy.cacheMaxTTL, } diff --git a/dnscrypt-proxy/proxy.go b/dnscrypt-proxy/proxy.go index 0ab658d1..bf66a379 100644 --- a/dnscrypt-proxy/proxy.go +++ b/dnscrypt-proxy/proxy.go @@ -30,7 +30,8 @@ type Proxy struct { pluginBlockIPv6 bool cache bool cacheSize int - cacheNegTTL uint32 + cacheNegMinTTL uint32 + cacheNegMaxTTL uint32 cacheMinTTL uint32 cacheMaxTTL uint32 queryLogFile string