]> granicus.if.org Git - pdns/commitdiff
New 'clean' version of dnsdist with my modifications.
authorSeth Ornstein <sornstein@globalcyberalliance.org>
Tue, 30 May 2017 21:57:00 +0000 (17:57 -0400)
committerNick Saika <nicksaika@gmail.com>
Wed, 2 Aug 2017 15:06:43 +0000 (11:06 -0400)
Commented line around new code segments has key words 'GCA' and 'Seth' for text searching.
Commands don't have XXX suffix anymore.
Timestamp for the setProtobufResponseType() function is supplied by lua now and not done in C++.
Current commands are: setTag, getTagArray, setTagArray, setProtobufResponseType

pdns/dnsdist-lua.cc
pdns/dnsdist-lua2.cc
pdns/dnsdist.hh
pdns/protobuf.cc
pdns/protobuf.hh

index 2a87d38f28a931bc98f49b9365388347036234c2..99c4c5b9a68e7b54d51428a50d19a4fcb0cb4994 100644 (file)
@@ -1586,6 +1586,38 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       }
     });
 
+
+  // --------------------------------------------------------------------------
+  // GCA - Seth Ornstein added lua callable functions - 5/30/2017
+  // DNSQuestion - setTag, getTagMatch, getTagArray
+
+    g_lua.registerFunction<void(DNSQuestion::*)(std::string, std::string)>("setTag", [](DNSQuestion& dq, const std::string& strLabel, const std::string& strValue) {
+
+       dq.qTag.add(strLabel, strValue);
+
+    });
+
+
+     g_lua.registerFunction<string(DNSQuestion::*)(std::string)>("getTagMatch", [](const DNSQuestion& dq, const std::string& strLabel) {
+
+        std::string strValue = dq.qTag.getMatch(strLabel);
+        return(strValue);
+
+     });
+
+
+     g_lua.registerFunction<std::unordered_map<string, string>(DNSQuestion::*)(void)>("getTagArray", [](const DNSQuestion& dq) {
+
+        setLuaNoSideEffect();
+
+        return dq.qTag.tagData;
+      });
+
+// --------------------------------------------------------------------------
+
+
+
+
   /* DNSQuestion bindings */
   /* PowerDNS DNSQuestion compat */
   g_lua.registerMember<const ComboAddress (DNSQuestion::*)>("localaddr", [](const DNSQuestion& dq) -> const ComboAddress { return *dq.local; }, [](DNSQuestion& dq, const ComboAddress newLocal) { (void) newLocal; });
index b299c83ea815c22048effca5c4b35a290744952a..2a4b47f0d444c71fd077bd206249233f61fb8a53 100644 (file)
@@ -831,6 +831,39 @@ void moreLua(bool client)
 #endif
       });
 
+
+// --------------------------------------------------------------------------
+// GCA - Seth Ornstein added lua callable functions - 5/30/2017
+// DNSDistProtoBufMessage - setTagArray, setProtobufResponseType
+
+
+     g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(vector<pair<string, string>>)>("setTagArray", [](DNSDistProtoBufMessage& message, const vector<pair<string, string>>&tags) {
+
+      setLuaSideEffect();
+
+      for (const auto& tag : tags)
+        {
+          message.addTags(tag.first, tag.second);               // add a tag to store text - not used by dnsdist at present?
+        }
+     });
+
+     g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&, time_t sec, uint uSec)>("setProtobufResponseType", [](DNSDistProtoBufMessage& message, const std::string& strQueryName, time_t sec, uint uSec) {
+
+        message.setType(DNSProtoBufMessage::Response);          // set protobuf type to be response - not query
+
+#ifdef TRASH
+        struct timespec ts;                                     // set protobuf query time - lua can't do microsec
+        gettime(&ts, true);
+        message.setQueryTime(ts.tv_sec, ts.tv_nsec / 1000);
+#endif
+        message.setQueryTime(sec, uSec);                        // seconds and microseconds
+
+        message.addRRs(strQueryName);                           // add a RR to the response
+     });
+
+// --------------------------------------------------------------------------
+
+
     g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const Netmask&)>("setEDNSSubnet", [](DNSDistProtoBufMessage& message, const Netmask& subnet) { message.setEDNSSubnet(subnet); });
     g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const DNSName&, uint16_t, uint16_t)>("setQuestion", [](DNSDistProtoBufMessage& message, const DNSName& qname, uint16_t qtype, uint16_t qclass) { message.setQuestion(qname, qtype, qclass); });
     g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(size_t)>("setBytes", [](DNSDistProtoBufMessage& message, size_t bytes) { message.setBytes(bytes); });
index 2d2094cf50bfe4546bd449cc4b848e4a8458e33f..e59908bca6c6a14c80ddd09ae348c6738ad0ad16 100644 (file)
 #include "dnsdist-dynbpf.hh"
 #include "bpf-filter.hh"
 
+// ----------------------------------------------------------------------------
+// GCA - Seth Ornstein - 5/30/2017 - for new extra class in DNSQuestion struct
+
+#include <string>
+#include <unordered_map>
+// ----------------------------------------------------------------------------
+
+
 #ifdef HAVE_PROTOBUF
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_generators.hpp>
@@ -51,6 +59,123 @@ extern uint16_t g_ECSSourcePrefixV4;
 extern uint16_t g_ECSSourcePrefixV6;
 extern bool g_ECSOverride;
 
+
+
+// ----------------------------------------------------------------------------
+// GCA - Seth Ornstein - 5/30/2017 - new extra class in DNSQuestion struct
+
+class QTag
+{
+
+public:
+
+// ----------------------------------------------------------------------------
+// constructor
+// ----------------------------------------------------------------------------
+QTag()
+{
+}
+
+// ----------------------------------------------------------------------------
+// destructor - verify for debugging that it is called as this is how tags become freed
+// ----------------------------------------------------------------------------
+~QTag()
+{
+}
+
+// ----------------------------------------------------------------------------
+// add() - add a label and value to the tags
+// ----------------------------------------------------------------------------
+bool add(std::string strLabel, std::string strValue)
+{
+bool bStatus = true;
+
+   tagData.insert( {strLabel, strValue});
+//   tagData[strLabel] = strValue;
+   return(bStatus);
+}
+
+// ----------------------------------------------------------------------------
+// getMatch() - return the matching tag value
+// ----------------------------------------------------------------------------
+std::string getMatch(const std::string& strLabel)  const
+{
+
+    std::unordered_map<std::string, std::string>::const_iterator got =tagData.find (strLabel);
+    if(got == tagData.end())
+      {
+       return("");
+      }
+    else
+      {
+       return(got->second);
+      }
+}
+
+
+// ----------------------------------------------------------------------------
+// getEntry() - return the specified tag entry
+// ----------------------------------------------------------------------------
+std::string getEntry(int iEntry) const
+{
+std::string strEntry;
+int iCounter = 0;
+
+   std::unordered_map<std::string, std::string>::const_iterator itr;
+   for (itr =tagData.begin(); itr != tagData.end(); itr++)
+      {
+        iCounter++;
+        if(iCounter == iEntry)
+          {
+           strEntry = itr->first;
+           strEntry += strSep;
+           strEntry += itr->second;
+           break;
+          }
+      }
+   return(strEntry);
+
+}
+
+// ----------------------------------------------------------------------------
+// count() - return number of tag entries
+// ----------------------------------------------------------------------------
+int count() const
+{
+   return(tagData.size());
+}
+
+// ----------------------------------------------------------------------------
+// dumpString() - return string with all the tag entries
+// ----------------------------------------------------------------------------
+std::string dumpString() const
+{
+std::string strRet;
+
+    std::unordered_map<std::string, std::string>::const_iterator itr;
+    for (itr =tagData.begin(); itr != tagData.end(); itr++)
+       {
+        strRet += itr->first;
+        strRet += strSep;
+        strRet += itr->second;
+        strRet += "\n";
+       }
+    return(strRet);
+}
+
+public:
+    std::unordered_map<std::string, std::string>tagData;    // try this public....
+
+private:
+
+    const char *strSep = "\t";                      // separation character
+};
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+
+
+
 struct DNSQuestion
 {
   DNSQuestion(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, struct dnsheader* header, size_t bufferSize, uint16_t queryLen, bool isTcp): qname(name), qtype(type), qclass(class_), local(lc), remote(rem), dh(header), size(bufferSize), len(queryLen), ecsPrefixLength(rem->sin4.sin_family == AF_INET ? g_ECSSourcePrefixV4 : g_ECSSourcePrefixV6), tcp(isTcp), ecsOverride(g_ECSOverride) { }
@@ -71,6 +196,7 @@ struct DNSQuestion
   bool skipCache{false};
   bool ecsOverride;
   bool useECS{true};    
+  QTag qTag;                        // GCA - Seth Ornstein - extra class for tags 5/30/2017
 };
 
 struct DNSResponse : DNSQuestion
index c7241ad0f20c1edf47fd3b8d24e8148fdc48942f..76dca48ea5b3e31c90f16d82eb5c3c89ab4ea333 100644 (file)
@@ -97,6 +97,57 @@ void DNSProtoBufMessage::setEDNSSubnet(const Netmask& subnet, uint8_t mask)
 #endif /* HAVE_PROTOBUF */
 }
 
+// ----------------------------------------------------------------------------
+// GCA - Seth Ornstein - 5/30/2017 - extra protobuf information
+// ----------------------------------------------------------------------------
+
+void DNSProtoBufMessage::addTags(const std::string& strLabel, const std::string& strValue)
+{
+#ifdef HAVE_PROTOBUF
+
+  PBDNSMessage_DNSResponse* response = d_message.mutable_response();
+  if (!response)
+    return;
+
+  std::string strTag;
+  strTag  = strLabel;
+  strTag += ",";                           // comma separator between label and value
+  strTag += strValue;
+
+  response->add_tags(strTag);
+
+#endif /* HAVE_PROTOBUF */
+}
+
+void DNSProtoBufMessage::addRRs(const std::string& strName)
+{
+#ifdef HAVE_PROTOBUF
+
+  PBDNSMessage_DNSResponse* response = d_message.mutable_response();
+  if (!response)
+    return;
+
+  PBDNSMessage_DNSResponse_DNSRR* rr = response->add_rrs();
+      if (rr) {
+        string blob;
+        rr->set_name(strName.c_str());
+        rr->set_type(1);
+        rr->set_class_(1);
+        rr->set_ttl(123);
+        char cTemp[4];
+        cTemp[0] = 127;
+        cTemp[1] = 0;
+        cTemp[2] = 0;
+        cTemp[3] = 1;
+        rr->set_rdata(cTemp, 4);
+      }
+
+#endif /* HAVE_PROTOBUF */
+}
+// ----------------------------------------------------------------------------
+
+
+
 void DNSProtoBufMessage::addRRsFromPacket(const char* packet, const size_t len, bool includeCNAME)
 {
 #ifdef HAVE_PROTOBUF
index 776bc10a7fffd9b5813ebcf0ba719574748f7f99..02385d1c73e97382f9ef12be77a47d321c1fe9d9 100644 (file)
@@ -71,6 +71,16 @@ public:
   void setRequestorId(const std::string& requestorId);
   std::string toDebugString() const;
 
+// ----------------------------------------------------------------------------
+// GCA - Seth Ornstein - Extra protobuf information - 5/30/2017
+// ----------------------------------------------------------------------------
+
+  void addTags(const std::string& strLabel, const std::string& strValue);
+  void addRRs(const std::string& strName);
+
+// ----------------------------------------------------------------------------
+
+
 #ifdef HAVE_PROTOBUF
   DNSProtoBufMessage(DNSProtoBufMessage::DNSProtoBufMessageType type, const boost::uuids::uuid& uuid, const ComboAddress* requestor, const ComboAddress* responder, const DNSName& domain, int qtype, uint16_t qclass, uint16_t qid, bool isTCP, size_t bytes);
   void update(const boost::uuids::uuid& uuid, const ComboAddress* requestor, const ComboAddress* responder, bool isTCP, uint16_t id);