From fd8898fbb51d8068127ff2fffd6a5f2e9f60be33 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Tue, 12 Mar 2019 11:27:53 +0100 Subject: [PATCH] implement a configurable ECS cache limit, defaulting to /24 and /56 of IPv6. So a /25 response will not get cached. (cherry picked from commit 1dab554571edc88ae625c3997294dbcfb1c3507e) --- pdns/pdns_recursor.cc | 4 ++++ pdns/recursor_cache.cc | 6 ++++++ pdns/syncres.cc | 2 ++ pdns/syncres.hh | 2 ++ 4 files changed, 14 insertions(+) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index b8d1f8ade5..d4619922d6 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -3655,6 +3655,8 @@ static int serviceMain(int argc, char*argv[]) SyncRes::s_ecsipv4limit = ::arg().asNum("ecs-ipv4-bits"); SyncRes::s_ecsipv6limit = ::arg().asNum("ecs-ipv6-bits"); SyncRes::clearECSStats(); + SyncRes::s_ecsipv4cachelimit = ::arg().asNum("ecs-ipv4-cache-bits"); + SyncRes::s_ecsipv6cachelimit = ::arg().asNum("ecs-ipv6-cache-bits"); if (!::arg().isEmpty("ecs-scope-zero-address")) { ComboAddress scopeZero(::arg()["ecs-scope-zero-address"]); @@ -4262,7 +4264,9 @@ int main(int argc, char **argv) ::arg().set("latency-statistic-size","Number of latency values to calculate the qa-latency average")="10000"; ::arg().setSwitch( "disable-packetcache", "Disable packetcache" )= "no"; ::arg().set("ecs-ipv4-bits", "Number of bits of IPv4 address to pass for EDNS Client Subnet")="24"; + ::arg().set("ecs-ipv4-cache-bits", "Maximum number of bits of IPv4 mask to cache ECS response")="24"; ::arg().set("ecs-ipv6-bits", "Number of bits of IPv6 address to pass for EDNS Client Subnet")="56"; + ::arg().set("ecs-ipv6-cache-bits", "Maximum number of bits of IPv6 mask to cache ECS response")="56"; ::arg().set("ecs-minimum-ttl-override", "Set under adverse conditions, a minimum TTL for records in ECS-specific answers")="0"; ::arg().set("edns-subnet-whitelist", "List of netmasks and domains that we should enable EDNS subnet for")=""; ::arg().set("ecs-add-for", "List of client netmasks for which EDNS Client Subnet will be added")="0.0.0.0/0, ::/0, " LOCAL_NETS_INVERSE; diff --git a/pdns/recursor_cache.cc b/pdns/recursor_cache.cc index 7e0bf054ce..d3563ab80b 100644 --- a/pdns/recursor_cache.cc +++ b/pdns/recursor_cache.cc @@ -238,6 +238,12 @@ int32_t MemRecursorCache::get(time_t now, const DNSName &qname, const QType& qt, void MemRecursorCache::replace(time_t now, const DNSName &qname, const QType& qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, boost::optional ednsmask, vState state) { + if(ednsmask) { + if(ednsmask->isIpv4() && ednsmask->getBits() > SyncRes::s_ecsipv4cachelimit) + return; + if(ednsmask->isIpv6() && ednsmask->getBits() > SyncRes::s_ecsipv6cachelimit) + return; + } d_cachecachevalid = false; // cerr<<"Replacing "<toString() : "everyone") << endl; auto key = boost::make_tuple(qname, qt.getCode(), ednsmask ? *ednsmask : Netmask()); diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 7686b4f677..f01ed298d3 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -78,6 +78,8 @@ std::map> SyncRes::s_ecsResponsesBySubnetSize6; uint8_t SyncRes::s_ecsipv4limit; uint8_t SyncRes::s_ecsipv6limit; +uint8_t SyncRes::s_ecsipv4cachelimit; +uint8_t SyncRes::s_ecsipv6cachelimit; bool SyncRes::s_doIPv6; bool SyncRes::s_nopacketcache; bool SyncRes::s_rootNXTrust; diff --git a/pdns/syncres.hh b/pdns/syncres.hh index d808668b49..c3b057757f 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -718,6 +718,8 @@ public: static unsigned int s_serverdownthrottletime; static uint8_t s_ecsipv4limit; static uint8_t s_ecsipv6limit; + static uint8_t s_ecsipv4cachelimit; + static uint8_t s_ecsipv6cachelimit; static bool s_doIPv6; static bool s_noEDNSPing; static bool s_noEDNS; -- 2.47.2