]> granicus.if.org Git - pdns/commitdiff
give gettag the ednssubnetmask too. Fix up logger to actualy log our enum.
authorbert hubert <bert.hubert@netherlabs.nl>
Sat, 5 Mar 2016 11:34:46 +0000 (12:34 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Sat, 5 Mar 2016 11:34:46 +0000 (12:34 +0100)
pdns/ednssubnet.cc
pdns/ednssubnet.hh
pdns/lua-recursor4.cc
pdns/lua-recursor4.hh
pdns/pdns_recursor.cc

index 92d9d2a1787c6201123cd0dcd3628df41b08c094..f804c60a3a27f030391a0ed79b2a3ebb719ce55e 100644 (file)
@@ -36,35 +36,38 @@ namespace {
 
 }
 
-
 bool getEDNSSubnetOptsFromString(const string& options, EDNSSubnetOpts* eso)
+{
+  return getEDNSSubnetOptsFromString(options.c_str(), options.length(), eso);
+}
+bool getEDNSSubnetOptsFromString(const char* options, unsigned int len, EDNSSubnetOpts* eso)
 {
   //cerr<<"options.size:"<<options.size()<<endl;
-  if(options.size() <= 4)
+  if(len <= 4)
     return false;  
   EDNSSubnetOptsWire esow;
-  memcpy(&esow, options.c_str(), sizeof(esow));
+  memcpy(&esow, options, sizeof(esow));
   esow.family = ntohs(esow.family);
   //cerr<<"Family when parsing from string: "<<esow.family<<endl;
   ComboAddress address;
   unsigned int octetsin = ((esow.sourceMask - 1)>> 3)+1;
   //cerr<<"octetsin:"<<octetsin<<endl;
   if(esow.family == 1) {
-    if(options.size() != 4+octetsin)
+    if(len != 4+octetsin)
       return false;
     if(octetsin > 4)
       return false;
     memset(&address, 0, sizeof(address));
     address.sin4.sin_family = AF_INET;
-    memcpy(&address.sin4.sin_addr.s_addr, options.c_str()+4, octetsin);
+    memcpy(&address.sin4.sin_addr.s_addr, options+4, octetsin);
   } else if(esow.family == 2) {
-    if(options.size() != 4+octetsin)
+    if(len != 4+octetsin)
       return false;
     if(octetsin > 16)
       return false;
     memset(&address, 0, sizeof(address));
     address.sin4.sin_family = AF_INET6;
-    memcpy(&address.sin6.sin6_addr.s6_addr, options.c_str()+4, octetsin);
+    memcpy(&address.sin6.sin6_addr.s6_addr, options+4, octetsin);
   }
   else
     return false;
index 08483201019a925dd99f43bdefe1f67219cca437..4c4b4c41253328c4170732a8672c65e1603ac102 100644 (file)
@@ -1,6 +1,6 @@
 /*
     PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2011  Netherlabs Computer Consulting BV
+    Copyright (C) 2011 - 2016  Netherlabs Computer Consulting BV
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as 
@@ -35,5 +35,6 @@ struct EDNSSubnetOpts
 };
 
 bool getEDNSSubnetOptsFromString(const string& options, EDNSSubnetOpts* eso);
+bool getEDNSSubnetOptsFromString(const char* options, unsigned int len, EDNSSubnetOpts* eso);
 string makeEDNSSubnetOptsString(const EDNSSubnetOpts& eso);
 #endif
index df22aca8f0ec7fb08ca847c9307e0fb24ceb25b4..2c27519c26872ddfaeee4d701583e16009584932 100644 (file)
@@ -45,7 +45,7 @@ bool RecursorLua4::ipfilter(const ComboAddress& remote, const ComboAddress& loca
   return false;
 }
 
-int RecursorLua4::gettag(const ComboAddress& remote, const ComboAddress& local, const DNSName& qname, uint16_t qtype)
+int RecursorLua4::gettag(const ComboAddress& remote, const EDNSSubnet& subnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype)
 {
   return 0;
 }
@@ -277,6 +277,7 @@ RecursorLua4::RecursorLua4(const std::string& fname)
 
   d_lw->registerFunction<ComboAddress(Netmask::*)()>("getNetwork", [](const Netmask& nm) { return nm.getNetwork(); } ); // const reference makes this necessary
   d_lw->registerFunction("toString", &Netmask::toString);
+  d_lw->registerFunction("empty", &Netmask::empty);
 
   d_lw->writeFunction("newNMG", []() { return NetmaskGroup(); });
   d_lw->registerFunction<void(NetmaskGroup::*)(const std::string&mask)>("addMask", [](NetmaskGroup&nmg, const std::string& mask)
@@ -340,7 +341,7 @@ RecursorLua4::RecursorLua4(const std::string& fname)
 
 
   d_lw->writeFunction("pdnslog", [](const std::string& msg, boost::optional<int> loglevel) {
-      theL() << loglevel.get_value_or(Logger::Warning) << msg<<endl;
+      theL() << (Logger::Urgency)loglevel.get_value_or(Logger::Warning) << msg<<endl;
     });
   typedef vector<pair<string, int> > in_t;
   vector<pair<string, boost::variant<int, in_t, struct timeval* > > >  pd{
@@ -426,10 +427,10 @@ bool RecursorLua4::ipfilter(const ComboAddress& remote, const ComboAddress& loca
   return false; // don't block
 }
 
-int RecursorLua4::gettag(const ComboAddress& remote, const ComboAddress& local, const DNSName& qname, uint16_t qtype)
+int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype)
 {
   if(d_gettag)
-    return d_gettag(remote, local, qname, qtype);
+    return d_gettag(remote, ednssubnet, local, qname, qtype);
   return 0;
 }
 
index 12e622e84a52f91a7f64f54253adbd1bc6306777..9ff7aa278b16076cc2415873e5f8c05f02c4bdc6 100644 (file)
@@ -20,9 +20,9 @@ public:
   bool preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, vector<DNSRecord>& res, int& ret);
   bool ipfilter(const ComboAddress& remote, const ComboAddress& local, const struct dnsheader&);
 
-  int gettag(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, uint16_t qtype);
+  int gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& query, uint16_t qtype);
 
-  typedef std::function<int(ComboAddress,ComboAddress, DNSName, uint16_t)> gettag_t;
+  typedef std::function<int(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t;
   gettag_t d_gettag; // public so you can query if we have this hooked
 
 private:
index e0eda04b9b23857a193a380820d9334de9ba1d74..b59fd66bbfbc9c7c9305f1836e8f253ad7d68b23 100644 (file)
@@ -1157,7 +1157,19 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr
       uint16_t qtype=0;
       try {
         DNSName qname(question.c_str(), question.length(), sizeof(dnsheader), false, &qtype, 0, &consumed);
-        ctag=(*t_pdl)->gettag(fromaddr, destaddr, qname, qtype);
+        Netmask ednssubnet;
+        auto pos= sizeof(dnsheader)+consumed+4;        
+        if(dh->arcount && question.length() > pos + 16) { // this code can extract one (1) EDNS Subnet option
+          uint16_t optlen=0x100*question.at(pos+9)+question.at(pos+10);
+          uint16_t optcode=0x100*question.at(pos+11)+question.at(pos+12);
+          if(question.at(pos)==0 && question.at(pos+1)==0 && question.at(pos+2)==QType::OPT && optlen && optcode==8) {
+            EDNSSubnetOpts eso;
+            if(getEDNSSubnetOptsFromString(question.c_str()+pos+15, question.length()-15-pos, &eso)) {
+              ednssubnet=eso.source;
+            }
+          }
+        }
+        ctag=(*t_pdl)->gettag(fromaddr, ednssubnet, destaddr, qname, qtype);
       }
       catch(std::exception& e)
       {