From: Remi Gacogne Date: Mon, 20 Jun 2016 11:58:27 +0000 (+0200) Subject: dnsdist: Add an optional `addECS` option to `TeeAction()` X-Git-Tag: auth-4.0.0-rc1~32^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F4019%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Add an optional `addECS` option to `TeeAction()` --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 958ff16265..71db623d43 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -1159,7 +1159,7 @@ instantiate a server with additional parameters * `SpoofAction(ip[, ip])` or `SpoofAction({ip, ip, ..}): forge a response with the specified IPv4 (for an A query) or IPv6 (for an AAAA). If you specify multiple addresses, all that match the query type (A, AAAA or ANY) will get spoofed in * `SpoofCNAMEAction(cname)`: forge a response with the specified CNAME value * `TCAction()`: create answer to query with TC and RD bits set, to move to TCP/IP - * `TeeAction(remote)`: send copy of query to remote, keep stats on responses + * `TeeAction(remote[, addECS])`: send copy of query to remote, keep stats on responses. If `addECS` is set to `true`, EDNS Client Subnet information will be added to the query * Specialist rule generators * `addAnyTCRule()`: generate TC=1 answers to ANY queries received over UDP, moving them to TCP * `addDomainSpoof(domain, ip[, ip6])` or `addDomainSpoof(domain, {IP, IP, IP..})`: generate answers for A/AAAA/ANY queries using the ip parameters diff --git a/pdns/dnsdist-lua2.cc b/pdns/dnsdist-lua2.cc index 17be04bacd..6b0f95e9bf 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -579,9 +579,8 @@ void moreLua(bool client) return std::make_shared(ComboAddress(remote), timeout ? *timeout : 2, maxQueuedEntries ? *maxQueuedEntries : 100, reconnectWaitTime ? *reconnectWaitTime : 1); }); - g_lua.writeFunction("TeeAction", [](const std::string& remote) { - setLuaNoSideEffect(); - return std::shared_ptr(new TeeAction(ComboAddress(remote, 53))); + g_lua.writeFunction("TeeAction", [](const std::string& remote, boost::optional addECS) { + return std::shared_ptr(new TeeAction(ComboAddress(remote, 53), addECS ? *addECS : false)); }); g_lua.registerFunction("printStats", [](const DNSAction& ta) { diff --git a/pdns/dnsdistdist/dnsrulactions.cc b/pdns/dnsdistdist/dnsrulactions.cc index aa40c5a381..88e76c295a 100644 --- a/pdns/dnsdistdist/dnsrulactions.cc +++ b/pdns/dnsdistdist/dnsrulactions.cc @@ -3,7 +3,7 @@ using namespace std; -TeeAction::TeeAction(const ComboAddress& ca) : d_remote(ca) +TeeAction::TeeAction(const ComboAddress& ca, bool addECS) : d_remote(ca), d_addECS(addECS) { d_fd=SSocket(d_remote.sin4.sin_family, SOCK_DGRAM, 0); SConnect(d_fd, d_remote); @@ -23,8 +23,32 @@ DNSAction::Action TeeAction::operator()(DNSQuestion* dq, string* ruleresult) con if(dq->tcp) d_tcpdrops++; else { + ssize_t res; d_queries++; - if(send(d_fd, (char*)dq->dh, dq->len, 0) <= 0) + + if(d_addECS) { + std::string query; + std::string larger; + uint16_t len = dq->len; + bool ednsAdded = false; + bool ecsAdded = false; + query.reserve(dq->size); + query.assign((char*) dq->dh, len); + + handleEDNSClientSubnet((char*) query.c_str(), query.size(), dq->qname->wirelength(), &len, larger, &ednsAdded, &ecsAdded, *dq->remote); + + if (larger.empty()) { + res = send(d_fd, query.c_str(), len, 0); + } + else { + res = send(d_fd, larger.c_str(), larger.length(), 0); + } + } + else { + res = send(d_fd, (char*)dq->dh, dq->len, 0); + } + + if (res <= 0) d_senderrors++; } return DNSAction::Action::None; diff --git a/pdns/dnsrulactions.hh b/pdns/dnsrulactions.hh index 899e7d64b4..9d47c4dd52 100644 --- a/pdns/dnsrulactions.hh +++ b/pdns/dnsrulactions.hh @@ -557,7 +557,7 @@ private: class TeeAction : public DNSAction { public: - TeeAction(const ComboAddress& ca); + TeeAction(const ComboAddress& ca, bool addECS=false); ~TeeAction(); DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override; string toString() const override; @@ -581,6 +581,7 @@ private: mutable unsigned long d_tcpdrops{0}; unsigned long d_otherrcode{0}; std::atomic d_pleaseQuit{false}; + bool d_addECS{false}; };