From: Remi Gacogne Date: Mon, 21 Mar 2016 17:42:22 +0000 (+0100) Subject: dnsdist: Split query/response actions X-Git-Tag: dnsdist-1.0.0-beta1~67^2~3^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8146444b763b8c3ae28ef2a16c2b08d377133441;p=thirdparty%2Fpdns.git dnsdist: Split query/response actions --- diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 12d51580e5..0ab42a439a 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -134,6 +134,10 @@ vector> setupLua(bool client, const std::string& confi {"Delay", (int)DNSAction::Action::Delay}} ); + g_lua.writeVariable("DNSResponseAction", std::unordered_map{ + {"None",(int)DNSResponseAction::Action::None}} + ); + vector > dd; for(const auto& n : QType::names) dd.push_back({n.first, n.second}); @@ -1321,7 +1325,7 @@ vector> setupLua(bool client, const std::string& confi g_lua.writeFunction("setECSOverride", [](bool override) { g_ECSOverride=override; }); - g_lua.writeFunction("addResponseAction", [](luadnsrule_t var, std::shared_ptr ea) { + g_lua.writeFunction("addResponseAction", [](luadnsrule_t var, std::shared_ptr ea) { setLuaSideEffect(); auto rule=makeRule(var); g_resprulactions.modify([rule, ea](decltype(g_resprulactions)::value_type& rulactions){ diff --git a/pdns/dnsdist-lua2.cc b/pdns/dnsdist-lua2.cc index 9624388600..91553f246a 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -578,7 +578,7 @@ void moreLua(bool client) return std::shared_ptr(new RemoteLogAction(logger)); }); g_lua.writeFunction("RemoteLogResponseAction", [](std::shared_ptr logger) { - return std::shared_ptr(new RemoteLogResponseAction(logger)); + return std::shared_ptr(new RemoteLogResponseAction(logger)); }); g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote) { return std::make_shared(ComboAddress(remote)); diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 432542de21..a6cca5dfbe 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -265,7 +265,7 @@ void* tcpClientThread(int pipefd) struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - if (!processQuery(localDynBlockNMG, localRulactions, blockFilter, dq, ci.remote, poolname, &delayMsec, now)) { + if (!processQuery(localDynBlockNMG, localRulactions, blockFilter, dq, poolname, &delayMsec, now)) { goto drop; } @@ -412,16 +412,12 @@ void* tcpClientThread(int pipefd) break; } - DNSQuestion dr(&rqname, rqtype, rqclass, &ci.cs->local, &ci.remote, dh, responseSize, responseLen, true); + DNSQuestion dr(&qname, qtype, qclass, &ci.cs->local, &ci.remote, dh, responseSize, responseLen, true); #ifdef HAVE_PROTOBUF dr.uniqueId = dq.uniqueId; #endif - for(const auto& lr : *localRespRulactions) { - if(lr.first->matches(&dr)) { - lr.first->d_matches++; - /* for now we only support actions returning None */ - (*lr.second)(&dr, &ruleresult); - } + if (!processResponse(localRespRulactions, dr)) { + break; } if (packetCache && !dq.skipCache) { diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 773a79d055..9883b12a94 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -108,7 +108,7 @@ GlobalStateHolder g_pools; If all downstreams are over QPS, we pick the fastest server */ GlobalStateHolder, std::shared_ptr > > > g_rulactions; -GlobalStateHolder, std::shared_ptr > > > g_resprulactions; +GlobalStateHolder, std::shared_ptr > > > g_resprulactions; Rings g_rings; GlobalStateHolder g_dstates; @@ -341,17 +341,12 @@ void* responderThread(std::shared_ptr state) dh->id = ids->origID; uint16_t addRoom = 0; - DNSQuestion dq(&ids->qname, ids->qtype, ids->qclass, &ids->origDest, &ids->origRemote, dh, sizeof(packet), responseLen, false); + DNSQuestion dr(&ids->qname, ids->qtype, ids->qclass, &ids->origDest, &ids->origRemote, dh, sizeof(packet), responseLen, false); #ifdef HAVE_PROTOBUF - dq.uniqueId = ids->uniqueId; + dr.uniqueId = ids->uniqueId; #endif - string ruleresult; - for(const auto& lr : *localRespRulactions) { - if(lr.first->matches(&dq)) { - lr.first->d_matches++; - /* for now we only support actions returning None */ - (*lr.second)(&dq, &ruleresult); - } + if (!processResponse(localRespRulactions, dr)) { + break; } #ifdef HAVE_DNSCRYPT @@ -665,16 +660,16 @@ void spoofResponseFromString(DNSQuestion& dq, const string& spoofContent) } } -bool processQuery(LocalStateHolder >& localDynBlock, LocalStateHolder, std::shared_ptr > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, const ComboAddress& remote, string& poolname, int* delayMsec, const struct timespec& now) +bool processQuery(LocalStateHolder >& localDynBlock, LocalStateHolder, std::shared_ptr > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, string& poolname, int* delayMsec, const struct timespec& now) { { WriteLock wl(&g_rings.queryLock); - g_rings.queryRing.push_back({now,remote,*dq.qname,dq.len,dq.qtype,*dq.dh}); + g_rings.queryRing.push_back({now,*dq.remote,*dq.qname,dq.len,dq.qtype,*dq.dh}); } - if(auto got=localDynBlock->lookup(remote)) { + if(auto got=localDynBlock->lookup(*dq.remote)) { if(now < got->second.until) { - vinfolog("Query from %s dropped because of dynamic block", remote.toStringWithPort()); + vinfolog("Query from %s dropped because of dynamic block", dq.remote->toStringWithPort()); g_stats.dynBlocked++; got->second.blocks++; return false; @@ -735,6 +730,20 @@ bool processQuery(LocalStateHolder >& localDynBlock, Local return true; } +bool processResponse(LocalStateHolder, std::shared_ptr > > >& localRespRulactions, DNSQuestion& dr) +{ + std::string ruleresult; + for(const auto& lr : *localRespRulactions) { + if(lr.first->matches(&dr)) { + lr.first->d_matches++; + /* for now we only support actions returning None */ + (*lr.second)(&dr, &ruleresult); + } + } + + return true; +} + static ssize_t udpClientSendRequestToBackend(DownstreamState* ss, const int sd, const char* request, const size_t requestLen) { if (ss->sourceItf == 0) { @@ -867,7 +876,7 @@ try struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - if (!processQuery(localDynBlock, localRulactions, blockFilter, dq, remote, poolname, &delayMsec, now)) + if (!processQuery(localDynBlock, localRulactions, blockFilter, dq, poolname, &delayMsec, now)) { continue; } diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 6e2e735d17..6e92f51516 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -425,6 +425,14 @@ public: virtual string toString() const = 0; }; +class DNSResponseAction +{ +public: + enum class Action { None }; + virtual Action operator()(DNSQuestion*, string* ruleresult) const =0; + virtual string toString() const = 0; +}; + using NumberedServerVector = NumberedVector>; typedef std::function(const NumberedServerVector& servers, const DNSQuestion*)> policyfunc_t; @@ -462,7 +470,7 @@ extern GlobalStateHolder g_policy; extern GlobalStateHolder g_dstates; extern GlobalStateHolder g_pools; extern GlobalStateHolder, std::shared_ptr > > > g_rulactions; -extern GlobalStateHolder, std::shared_ptr > > > g_resprulactions; +extern GlobalStateHolder, std::shared_ptr > > > g_resprulactions; extern GlobalStateHolder g_ACL; extern ComboAddress g_serverControl; // not changed during runtime @@ -520,7 +528,8 @@ bool getLuaNoSideEffect(); // set if there were only explicit declarations of _n void resetLuaSideEffect(); // reset to indeterminate state bool responseContentMatches(const char* response, const uint16_t responseLen, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& remote); -bool processQuery(LocalStateHolder >& localDynBlock, LocalStateHolder, std::shared_ptr > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, const ComboAddress& remote, string& poolname, int* delayMsec, const struct timespec& now); +bool processQuery(LocalStateHolder >& localDynBlock, LocalStateHolder, std::shared_ptr > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, string& poolname, int* delayMsec, const struct timespec& now); +bool processResponse(LocalStateHolder, std::shared_ptr > > >& localRespRulactions, DNSQuestion& dq); bool fixUpResponse(char** response, uint16_t* responseLen, size_t* responseSize, const DNSName& qname, uint16_t origFlags, bool ednsAdded, std::vector& rewrittenResponse, uint16_t addRoom); void restoreFlags(struct dnsheader* dh, uint16_t origFlags); diff --git a/pdns/dnsrulactions.hh b/pdns/dnsrulactions.hh index 63cacd33b9..6f15664bbd 100644 --- a/pdns/dnsrulactions.hh +++ b/pdns/dnsrulactions.hh @@ -731,13 +731,13 @@ private: std::shared_ptr d_logger; }; -class RemoteLogResponseAction : public DNSAction, public boost::noncopyable +class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopyable { public: RemoteLogResponseAction(std::shared_ptr logger): d_logger(logger) { } - DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override + DNSResponseAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override { d_logger->logResponse(*dq); return Action::None;