From 26a6373de0ce3dccedb34259d91defdb947c7767 Mon Sep 17 00:00:00 2001 From: Seth Ornstein Date: Tue, 30 May 2017 17:57:00 -0400 Subject: [PATCH] New 'clean' version of dnsdist with my modifications. 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 | 32 +++++++++++ pdns/dnsdist-lua2.cc | 33 ++++++++++++ pdns/dnsdist.hh | 126 +++++++++++++++++++++++++++++++++++++++++++ pdns/protobuf.cc | 51 ++++++++++++++++++ pdns/protobuf.hh | 10 ++++ 5 files changed, 252 insertions(+) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 2a87d38f28..99c4c5b9a6 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -1586,6 +1586,38 @@ vector> setupLua(bool client, const std::string& confi } }); + + // -------------------------------------------------------------------------- + // GCA - Seth Ornstein added lua callable functions - 5/30/2017 + // DNSQuestion - setTag, getTagMatch, getTagArray + + g_lua.registerFunction("setTag", [](DNSQuestion& dq, const std::string& strLabel, const std::string& strValue) { + + dq.qTag.add(strLabel, strValue); + + }); + + + g_lua.registerFunction("getTagMatch", [](const DNSQuestion& dq, const std::string& strLabel) { + + std::string strValue = dq.qTag.getMatch(strLabel); + return(strValue); + + }); + + + g_lua.registerFunction(DNSQuestion::*)(void)>("getTagArray", [](const DNSQuestion& dq) { + + setLuaNoSideEffect(); + + return dq.qTag.tagData; + }); + +// -------------------------------------------------------------------------- + + + + /* DNSQuestion bindings */ /* PowerDNS DNSQuestion compat */ g_lua.registerMember("localaddr", [](const DNSQuestion& dq) -> const ComboAddress { return *dq.local; }, [](DNSQuestion& dq, const ComboAddress newLocal) { (void) newLocal; }); diff --git a/pdns/dnsdist-lua2.cc b/pdns/dnsdist-lua2.cc index b299c83ea8..2a4b47f0d4 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -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>)>("setTagArray", [](DNSDistProtoBufMessage& message, const vector>&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("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("setEDNSSubnet", [](DNSDistProtoBufMessage& message, const Netmask& subnet) { message.setEDNSSubnet(subnet); }); g_lua.registerFunction("setQuestion", [](DNSDistProtoBufMessage& message, const DNSName& qname, uint16_t qtype, uint16_t qclass) { message.setQuestion(qname, qtype, qclass); }); g_lua.registerFunction("setBytes", [](DNSDistProtoBufMessage& message, size_t bytes) { message.setBytes(bytes); }); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 2d2094cf50..e59908bca6 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -39,6 +39,14 @@ #include "dnsdist-dynbpf.hh" #include "bpf-filter.hh" +// ---------------------------------------------------------------------------- +// GCA - Seth Ornstein - 5/30/2017 - for new extra class in DNSQuestion struct + +#include +#include +// ---------------------------------------------------------------------------- + + #ifdef HAVE_PROTOBUF #include #include @@ -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::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::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::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_maptagData; // 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 diff --git a/pdns/protobuf.cc b/pdns/protobuf.cc index c7241ad0f2..76dca48ea5 100644 --- a/pdns/protobuf.cc +++ b/pdns/protobuf.cc @@ -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 diff --git a/pdns/protobuf.hh b/pdns/protobuf.hh index 776bc10a7f..02385d1c73 100644 --- a/pdns/protobuf.hh +++ b/pdns/protobuf.hh @@ -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); -- 2.47.2