From: Seth Ornstein Date: Tue, 30 May 2017 21:57:00 +0000 (-0400) Subject: New 'clean' version of dnsdist with my modifications. X-Git-Tag: dnsdist-1.2.0~39^2~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=26a6373de0ce3dccedb34259d91defdb947c7767;p=pdns 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 --- diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 2a87d38f2..99c4c5b9a 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 b299c83ea..2a4b47f0d 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 2d2094cf5..e59908bca 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 c7241ad0f..76dca48ea 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 776bc10a7..02385d1c7 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);