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
}
});
+
+ // --------------------------------------------------------------------------
+ // 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; });
#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); });
#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>
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) { }
bool skipCache{false};
bool ecsOverride;
bool useECS{true};
+ QTag qTag; // GCA - Seth Ornstein - extra class for tags 5/30/2017
};
struct DNSResponse : DNSQuestion
#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
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);