]> granicus.if.org Git - pdns/commitdiff
add ecs-ipv4-bits and ecs-ipv6-bits tunables for EDNS Client Subnet & document them...
authorbert hubert <bert.hubert@powerdns.com>
Wed, 18 Jan 2017 15:18:46 +0000 (16:18 +0100)
committerbert hubert <bert.hubert@powerdns.com>
Wed, 18 Jan 2017 15:18:46 +0000 (16:18 +0100)
docs/markdown/recursor/settings.md
pdns/pdns_recursor.cc
pdns/recursordist/Makefile.am
pdns/recursordist/ecs.cc [new file with mode: 0644]
pdns/syncres.hh

index 95f4b57aa598f8883c330ad77eabc58825ea62f3..64d54d69f4cd889dc325654dea204c4323564235 100644 (file)
@@ -225,6 +225,20 @@ your network, and may even be a security risk. Therefore, since version 3.1.5,
 the PowerDNS recursor by default does not query private space IP addresses.
 This setting can be used to expand or reduce the limitations.
 
+## `ecs-ipv4-bits`
+* Integer
+* Default: 24
+* Available since 4.1
+
+Number of bits of client IPv4 address to pass when sending EDNS Client Subnet address information.
+
+## `ecs-ipv6-bits`
+* Integer
+* Default: 56
+* Available since 4.1
+
+Number of bits of client IPv6 address to pass when sending EDNS Client Subnet address information.
+
 ## `edns-outgoing-bufsize`
 * Integer
 * Default: 1680
index 16c11466733ad0669b10c54379d5585a9428fb16..f38723c4f89d06fe61181b141b6a4405ab8bf7ac 100644 (file)
@@ -111,8 +111,6 @@ __thread shared_ptr<Regex>* t_traceRegex;
 __thread boost::uuids::random_generator* t_uuidGenerator;
 #endif
 
-NetmaskGroup g_ednssubnets;
-SuffixMatchNode g_ednsdomains;
 
 RecursorControlChannel s_rcc; // only active in thread 0
 
@@ -2602,33 +2600,6 @@ void parseACLs()
   l_initialized = true;
 }
 
-boost::optional<Netmask> getEDNSSubnetMask(const ComboAddress& local, const DNSName&dn, const ComboAddress& rem)
-{
-  if(local.sin4.sin_family != AF_INET || local.sin4.sin_addr.s_addr) { // detect unset 'requestor'
-    if(g_ednsdomains.check(dn) || g_ednssubnets.match(rem)) {
-      int bits =local.sin4.sin_family == AF_INET ? 24 : 56;
-      ComboAddress trunc(local);
-      trunc.truncate(bits);
-      return boost::optional<Netmask>(Netmask(trunc, bits));
-    }
-  }
-  return boost::optional<Netmask>();
-}
-
-void  parseEDNSSubnetWhitelist(const std::string& wlist)
-{
-  vector<string> parts;
-  stringtok(parts, wlist, ",; ");
-  for(const auto& a : parts) {
-    try {
-      Netmask nm(a);
-      g_ednssubnets.addMask(nm);
-    }
-    catch(...) {
-      g_ednsdomains.add(DNSName(a));
-    }
-  }
-}
 
 std::unordered_set<DNSName> g_delegationOnly;
 static void setupDelegationOnly()
@@ -3109,6 +3080,8 @@ int main(int argc, char **argv)
     ::arg().set("lua-dns-script", "Filename containing an optional 'lua' script that will be used to modify dns answers")="";
     ::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-ipv6-bits", "Number of bits of IPv6 address to pass for EDNS Client Subnet")="56";
     ::arg().set("edns-subnet-whitelist", "List of netmasks and domains that we should enable EDNS subnet for")="";
     ::arg().setSwitch( "pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads")="";
     ::arg().setSwitch( "root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist")="yes";
index 3b8b402d27ebc19b641408f74ea6a731df4cba1d..90004d7297e426b8368a6ce0cb165bd557163c6f 100644 (file)
@@ -79,6 +79,7 @@ pdns_recursor_SOURCES = \
        dnssecinfra.hh dnssecinfra.cc \
        dnsseckeeper.hh \
        dnswriter.cc dnswriter.hh \
+       ecs.cc \
        ednsoptions.cc ednsoptions.hh \
        ednssubnet.cc ednssubnet.hh \
        filterpo.cc filterpo.hh \
diff --git a/pdns/recursordist/ecs.cc b/pdns/recursordist/ecs.cc
new file mode 100644 (file)
index 0000000..431daf4
--- /dev/null
@@ -0,0 +1,38 @@
+#include "syncres.hh"
+#include "arguments.hh"
+
+NetmaskGroup g_ednssubnets;
+SuffixMatchNode g_ednsdomains;
+
+boost::optional<Netmask> getEDNSSubnetMask(const ComboAddress& local, const DNSName&dn, const ComboAddress& rem)
+{
+  static int l_ipv4limit, l_ipv6limit;
+  if(!l_ipv4limit) {
+    l_ipv4limit = ::arg().asNum("ecs-ipv4-bits");
+    l_ipv6limit = ::arg().asNum("ecs-ipv6-bits");
+  }
+  if(local.sin4.sin_family != AF_INET || local.sin4.sin_addr.s_addr) { // detect unset 'requestor'
+    if(g_ednsdomains.check(dn) || g_ednssubnets.match(rem)) {
+      int bits = local.sin4.sin_family == AF_INET ? l_ipv4limit : l_ipv6limit;
+      ComboAddress trunc(local);
+      trunc.truncate(bits);
+      return boost::optional<Netmask>(Netmask(trunc, bits));
+    }
+  }
+  return boost::optional<Netmask>();
+}
+
+void  parseEDNSSubnetWhitelist(const std::string& wlist)
+{
+  vector<string> parts;
+  stringtok(parts, wlist, ",; ");
+  for(const auto& a : parts) {
+    try {
+      Netmask nm(a);
+      g_ednssubnets.addMask(nm);
+    }
+    catch(...) {
+      g_ednsdomains.add(DNSName(a));
+    }
+  }
+}
index 0bbb9bacc880e5f88ce2fcf096478c69ca21b4ca..fb58b0e74a4fe3a3757c54d4078b67aed127056a 100644 (file)
@@ -741,6 +741,10 @@ void  parseEDNSSubnetWhitelist(const std::string& wlist);
 
 extern __thread struct timeval g_now;
 
+extern NetmaskGroup g_ednssubnets;
+extern SuffixMatchNode g_ednsdomains;
+
+
 #ifdef HAVE_PROTOBUF
 extern __thread boost::uuids::random_generator* t_uuidGenerator;
 #endif