2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "dnsdist-ecs.hh"
26 #include "ednsoptions.hh"
28 #include "remote_logger.hh"
29 #include "dnsdist-protobuf.hh"
30 #include "dnsparser.hh"
32 class MaxQPSIPRule : public DNSRule
35 MaxQPSIPRule(unsigned int qps, unsigned int ipv4trunc=32, unsigned int ipv6trunc=64) :
36 d_qps(qps), d_ipv4trunc(ipv4trunc), d_ipv6trunc(ipv6trunc)
38 pthread_rwlock_init(&d_lock, 0);
41 bool matches(const DNSQuestion* dq) const override
43 ComboAddress zeroport(*dq->remote);
44 zeroport.sin4.sin_port=0;
45 zeroport.truncate(zeroport.sin4.sin_family == AF_INET ? d_ipv4trunc : d_ipv6trunc);
48 const auto iter = d_limits.find(zeroport);
49 if (iter != d_limits.end()) {
50 return !iter->second.check();
55 auto iter = d_limits.find(zeroport);
56 if(iter == d_limits.end()) {
57 iter=d_limits.insert({zeroport,QPSLimiter(d_qps, d_qps)}).first;
59 return !iter->second.check();
63 string toString() const override
65 return "IP (/"+std::to_string(d_ipv4trunc)+", /"+std::to_string(d_ipv6trunc)+") match for QPS over " + std::to_string(d_qps);
70 mutable pthread_rwlock_t d_lock;
71 mutable std::map<ComboAddress, QPSLimiter> d_limits;
72 unsigned int d_qps, d_ipv4trunc, d_ipv6trunc;
76 class MaxQPSRule : public DNSRule
79 MaxQPSRule(unsigned int qps)
83 MaxQPSRule(unsigned int qps, unsigned int burst)
88 bool matches(const DNSQuestion* qd) const override
93 string toString() const override
95 return "Max " + std::to_string(d_qps.getRate()) + " qps";
100 mutable QPSLimiter d_qps;
103 class NMGRule : public DNSRule
106 NMGRule(const NetmaskGroup& nmg) : d_nmg(nmg) {}
111 class NetmaskGroupRule : public NMGRule
114 NetmaskGroupRule(const NetmaskGroup& nmg, bool src) : NMGRule(nmg)
118 bool matches(const DNSQuestion* dq) const override
121 return d_nmg.match(*dq->local);
123 return d_nmg.match(*dq->remote);
126 string toString() const override
129 return "Dst: "+d_nmg.toString();
131 return "Src: "+d_nmg.toString();
137 class TimedIPSetRule : public DNSRule, boost::noncopyable
141 IPv6(const ComboAddress& ca)
143 static_assert(sizeof(*this)==16, "IPv6 struct has wrong size");
144 memcpy((char*)this, ca.sin6.sin6_addr.s6_addr, 16);
146 bool operator==(const IPv6& rhs) const
148 return a==rhs.a && b==rhs.b;
156 pthread_rwlock_init(&d_lock4, 0);
157 pthread_rwlock_init(&d_lock6, 0);
159 bool matches(const DNSQuestion* dq) const override
161 if(dq->remote->sin4.sin_family == AF_INET) {
162 ReadLock rl(&d_lock4);
163 auto fnd = d_ip4s.find(dq->remote->sin4.sin_addr.s_addr);
164 if(fnd == d_ip4s.end()) {
167 return time(0) < fnd->second;
169 ReadLock rl(&d_lock6);
170 auto fnd = d_ip6s.find({*dq->remote});
171 if(fnd == d_ip6s.end()) {
174 return time(0) < fnd->second;
178 void add(const ComboAddress& ca, time_t ttd)
180 // think twice before adding templates here
181 if(ca.sin4.sin_family == AF_INET) {
182 WriteLock rl(&d_lock4);
183 auto res=d_ip4s.insert({ca.sin4.sin_addr.s_addr, ttd});
184 if(!res.second && (time_t)res.first->second < ttd)
185 res.first->second = (uint32_t)ttd;
188 WriteLock rl(&d_lock6);
189 auto res=d_ip6s.insert({{ca}, ttd});
190 if(!res.second && (time_t)res.first->second < ttd)
191 res.first->second = (uint32_t)ttd;
195 void remove(const ComboAddress& ca)
197 if(ca.sin4.sin_family == AF_INET) {
198 WriteLock rl(&d_lock4);
199 d_ip4s.erase(ca.sin4.sin_addr.s_addr);
202 WriteLock rl(&d_lock6);
210 WriteLock rl(&d_lock4);
213 WriteLock rl(&d_lock6);
221 WriteLock rl(&d_lock4);
223 for(auto iter = d_ip4s.begin(); iter != d_ip4s.end(); ) {
224 if(iter->second < now)
225 iter=d_ip4s.erase(iter);
233 WriteLock rl(&d_lock6);
235 for(auto iter = d_ip6s.begin(); iter != d_ip6s.end(); ) {
236 if(iter->second < now)
237 iter=d_ip6s.erase(iter);
246 string toString() const override
251 ReadLock rl(&d_lock4);
252 for(const auto& ip : d_ip4s)
257 ReadLock rl(&d_lock6);
258 for(const auto& ip : d_ip6s)
263 return "Src: "+std::to_string(count)+" ips";
268 std::size_t operator()(const IPv6& ip) const
270 auto ah=std::hash<uint64_t>{}(ip.a);
271 auto bh=std::hash<uint64_t>{}(ip.b);
275 std::unordered_map<IPv6, uint32_t, IPv6Hash> d_ip6s;
276 std::unordered_map<uint32_t, uint32_t> d_ip4s;
277 mutable pthread_rwlock_t d_lock4;
278 mutable pthread_rwlock_t d_lock6;
282 class AllRule : public DNSRule
286 bool matches(const DNSQuestion* dq) const override
291 string toString() const override
299 class DNSSECRule : public DNSRule
306 bool matches(const DNSQuestion* dq) const override
308 return dq->dh->cd || (getEDNSZ((const char*)dq->dh, dq->len) & EDNS_HEADER_FLAG_DO); // turns out dig sets ad by default..
311 string toString() const override
317 class AndRule : public DNSRule
320 AndRule(const vector<pair<int, shared_ptr<DNSRule> > >& rules)
322 for(const auto& r : rules)
323 d_rules.push_back(r.second);
326 bool matches(const DNSQuestion* dq) const override
328 auto iter = d_rules.begin();
329 for(; iter != d_rules.end(); ++iter)
330 if(!(*iter)->matches(dq))
332 return iter == d_rules.end();
335 string toString() const override
338 for(const auto& rule : d_rules) {
341 ret += "("+ rule->toString()+")";
347 vector<std::shared_ptr<DNSRule> > d_rules;
352 class OrRule : public DNSRule
355 OrRule(const vector<pair<int, shared_ptr<DNSRule> > >& rules)
357 for(const auto& r : rules)
358 d_rules.push_back(r.second);
361 bool matches(const DNSQuestion* dq) const override
363 auto iter = d_rules.begin();
364 for(; iter != d_rules.end(); ++iter)
365 if((*iter)->matches(dq))
370 string toString() const override
373 for(const auto& rule : d_rules) {
376 ret += "("+ rule->toString()+")";
382 vector<std::shared_ptr<DNSRule> > d_rules;
387 class RegexRule : public DNSRule
390 RegexRule(const std::string& regex) : d_regex(regex), d_visual(regex)
394 bool matches(const DNSQuestion* dq) const override
396 return d_regex.match(dq->qname->toStringNoDot());
399 string toString() const override
401 return "Regex: "+d_visual;
410 class RE2Rule : public DNSRule
413 RE2Rule(const std::string& re2) : d_re2(re2, RE2::Latin1), d_visual(re2)
417 bool matches(const DNSQuestion* dq) const override
419 return RE2::FullMatch(dq->qname->toStringNoDot(), d_re2);
422 string toString() const override
424 return "RE2 match: "+d_visual;
433 class SuffixMatchNodeRule : public DNSRule
436 SuffixMatchNodeRule(const SuffixMatchNode& smn, bool quiet=false) : d_smn(smn), d_quiet(quiet)
439 bool matches(const DNSQuestion* dq) const override
441 return d_smn.check(*dq->qname);
443 string toString() const override
446 return "qname==in-set";
448 return "qname in "+d_smn.toString();
451 SuffixMatchNode d_smn;
455 class QNameRule : public DNSRule
458 QNameRule(const DNSName& qname) : d_qname(qname)
461 bool matches(const DNSQuestion* dq) const override
463 return d_qname==*dq->qname;
465 string toString() const override
467 return "qname=="+d_qname.toString();
474 class QTypeRule : public DNSRule
477 QTypeRule(uint16_t qtype) : d_qtype(qtype)
480 bool matches(const DNSQuestion* dq) const override
482 return d_qtype == dq->qtype;
484 string toString() const override
487 return "qtype=="+qt.getName();
493 class QClassRule : public DNSRule
496 QClassRule(uint16_t qclass) : d_qclass(qclass)
499 bool matches(const DNSQuestion* dq) const override
501 return d_qclass == dq->qclass;
503 string toString() const override
505 return "qclass=="+std::to_string(d_qclass);
511 class OpcodeRule : public DNSRule
514 OpcodeRule(uint8_t opcode) : d_opcode(opcode)
517 bool matches(const DNSQuestion* dq) const override
519 return d_opcode == dq->dh->opcode;
521 string toString() const override
523 return "opcode=="+std::to_string(d_opcode);
529 class TCPRule : public DNSRule
532 TCPRule(bool tcp): d_tcp(tcp)
535 bool matches(const DNSQuestion* dq) const override
537 return dq->tcp == d_tcp;
539 string toString() const override
541 return (d_tcp ? "TCP" : "UDP");
548 class NotRule : public DNSRule
551 NotRule(shared_ptr<DNSRule>& rule): d_rule(rule)
554 bool matches(const DNSQuestion* dq) const override
556 return !d_rule->matches(dq);
558 string toString() const override
560 return "!("+ d_rule->toString()+")";
563 shared_ptr<DNSRule> d_rule;
566 class RecordsCountRule : public DNSRule
569 RecordsCountRule(uint8_t section, uint16_t minCount, uint16_t maxCount): d_minCount(minCount), d_maxCount(maxCount), d_section(section)
572 bool matches(const DNSQuestion* dq) const override
577 count = ntohs(dq->dh->qdcount);
580 count = ntohs(dq->dh->ancount);
583 count = ntohs(dq->dh->nscount);
586 count = ntohs(dq->dh->arcount);
589 return count >= d_minCount && count <= d_maxCount;
591 string toString() const override
608 return std::to_string(d_minCount) + " <= records in " + section + " <= "+ std::to_string(d_maxCount);
616 class RecordsTypeCountRule : public DNSRule
619 RecordsTypeCountRule(uint8_t section, uint16_t type, uint16_t minCount, uint16_t maxCount): d_type(type), d_minCount(minCount), d_maxCount(maxCount), d_section(section)
622 bool matches(const DNSQuestion* dq) const override
627 count = ntohs(dq->dh->qdcount);
630 count = ntohs(dq->dh->ancount);
633 count = ntohs(dq->dh->nscount);
636 count = ntohs(dq->dh->arcount);
639 if (count < d_minCount) {
642 count = getRecordsOfTypeCount(reinterpret_cast<const char*>(dq->dh), dq->len, d_section, d_type);
643 return count >= d_minCount && count <= d_maxCount;
645 string toString() const override
662 return std::to_string(d_minCount) + " <= " + QType(d_type).getName() + " records in " + section + " <= "+ std::to_string(d_maxCount);
671 class TrailingDataRule : public DNSRule
677 bool matches(const DNSQuestion* dq) const override
679 uint16_t length = getDNSPacketLength(reinterpret_cast<const char*>(dq->dh), dq->len);
680 return length < dq->len;
682 string toString() const override
684 return "trailing data";
688 class QNameLabelsCountRule : public DNSRule
691 QNameLabelsCountRule(unsigned int minLabelsCount, unsigned int maxLabelsCount): d_min(minLabelsCount), d_max(maxLabelsCount)
694 bool matches(const DNSQuestion* dq) const override
696 unsigned int count = dq->qname->countLabels();
697 return count < d_min || count > d_max;
699 string toString() const override
701 return "labels count < " + std::to_string(d_min) + " || labels count > " + std::to_string(d_max);
708 class QNameWireLengthRule : public DNSRule
711 QNameWireLengthRule(size_t min, size_t max): d_min(min), d_max(max)
714 bool matches(const DNSQuestion* dq) const override
716 size_t const wirelength = dq->qname->wirelength();
717 return wirelength < d_min || wirelength > d_max;
719 string toString() const override
721 return "wire length < " + std::to_string(d_min) + " || wire length > " + std::to_string(d_max);
728 class RCodeRule : public DNSRule
731 RCodeRule(int rcode) : d_rcode(rcode)
734 bool matches(const DNSQuestion* dq) const override
736 return d_rcode == dq->dh->rcode;
738 string toString() const override
740 return "rcode=="+RCode::to_s(d_rcode);
746 class RDRule : public DNSRule
752 bool matches(const DNSQuestion* dq) const override
754 return dq->dh->rd == 1;
756 string toString() const override
763 class DropAction : public DNSAction
766 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
770 string toString() const override
776 class AllowAction : public DNSAction
779 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
781 return Action::Allow;
783 string toString() const override
790 class QPSAction : public DNSAction
793 QPSAction(int limit) : d_qps(limit, limit)
795 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
802 string toString() const override
804 return "qps limit to "+std::to_string(d_qps.getRate());
810 class DelayAction : public DNSAction
813 DelayAction(int msec) : d_msec(msec)
815 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
817 *ruleresult=std::to_string(d_msec);
818 return Action::Delay;
820 string toString() const override
822 return "delay by "+std::to_string(d_msec)+ " msec";
829 class TeeAction : public DNSAction
832 TeeAction(const ComboAddress& ca, bool addECS=false);
833 ~TeeAction() override;
834 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override;
835 string toString() const override;
836 std::unordered_map<string, double> getStats() const override;
838 ComboAddress d_remote;
839 std::thread d_worker;
843 mutable std::atomic<unsigned long> d_senderrors{0};
844 unsigned long d_recverrors{0};
845 mutable std::atomic<unsigned long> d_queries{0};
846 unsigned long d_responses{0};
847 unsigned long d_nxdomains{0};
848 unsigned long d_servfails{0};
849 unsigned long d_refuseds{0};
850 unsigned long d_formerrs{0};
851 unsigned long d_notimps{0};
852 unsigned long d_noerrors{0};
853 mutable unsigned long d_tcpdrops{0};
854 unsigned long d_otherrcode{0};
855 std::atomic<bool> d_pleaseQuit{false};
856 bool d_addECS{false};
861 class PoolAction : public DNSAction
864 PoolAction(const std::string& pool) : d_pool(pool) {}
865 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
870 string toString() const override
872 return "to pool "+d_pool;
880 class QPSPoolAction : public DNSAction
883 QPSPoolAction(unsigned int limit, const std::string& pool) : d_qps(limit, limit), d_pool(pool) {}
884 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
893 string toString() const override
895 return "max " +std::to_string(d_qps.getRate())+" to pool "+d_pool;
903 class RCodeAction : public DNSAction
906 RCodeAction(int rcode) : d_rcode(rcode) {}
907 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
909 dq->dh->rcode = d_rcode;
910 dq->dh->qr = true; // for good measure
911 return Action::HeaderModify;
913 string toString() const override
915 return "set rcode "+std::to_string(d_rcode);
922 class TCAction : public DNSAction
925 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
927 return Action::Truncate;
929 string toString() const override
931 return "tc=1 answer";
935 class SpoofAction : public DNSAction
938 SpoofAction(const vector<ComboAddress>& addrs) : d_addrs(addrs)
942 SpoofAction(const string& cname): d_cname(cname) { }
944 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
946 uint16_t qtype = dq->qtype;
947 // do we even have a response?
948 if(d_cname.empty() && !std::count_if(d_addrs.begin(), d_addrs.end(), [qtype](const ComboAddress& a)
950 return (qtype == QType::ANY || ((a.sin4.sin_family == AF_INET && qtype == QType::A) ||
951 (a.sin4.sin_family == AF_INET6 && qtype == QType::AAAA)));
955 vector<ComboAddress> addrs;
956 unsigned int totrdatalen=0;
957 if (!d_cname.empty()) {
958 qtype = QType::CNAME;
959 totrdatalen += d_cname.toDNSString().size();
961 for(const auto& addr : d_addrs) {
962 if(qtype != QType::ANY && ((addr.sin4.sin_family == AF_INET && qtype != QType::A) ||
963 (addr.sin4.sin_family == AF_INET6 && qtype != QType::AAAA)))
965 totrdatalen += addr.sin4.sin_family == AF_INET ? sizeof(addr.sin4.sin_addr.s_addr) : sizeof(addr.sin6.sin6_addr.s6_addr);
966 addrs.push_back(addr);
971 random_shuffle(addrs.begin(), addrs.end());
973 unsigned int consumed=0;
974 DNSName ignore((char*)dq->dh, dq->len, sizeof(dnsheader), false, 0, 0, &consumed);
976 if (dq->size < (sizeof(dnsheader) + consumed + 4 + ((d_cname.empty() ? 0 : 1) + addrs.size())*12 /* recordstart */ + totrdatalen)) {
980 dq->len = sizeof(dnsheader) + consumed + 4; // there goes your EDNS
981 char* dest = ((char*)dq->dh) + dq->len;
983 dq->dh->qr = true; // for good measure
984 dq->dh->ra = dq->dh->rd; // for good measure
987 dq->dh->arcount = 0; // for now, forget about your EDNS, we're marching over it
989 if(qtype == QType::CNAME) {
990 string wireData = d_cname.toDNSString(); // Note! This doesn't do compression!
991 const unsigned char recordstart[]={0xc0, 0x0c, // compressed name
992 0, (unsigned char) qtype,
995 0, (unsigned char)wireData.length()};
996 static_assert(sizeof(recordstart) == 12, "sizeof(recordstart) must be equal to 12, otherwise the above check is invalid");
998 memcpy(dest, recordstart, sizeof(recordstart));
999 dest += sizeof(recordstart);
1000 memcpy(dest, wireData.c_str(), wireData.length());
1001 dq->len += wireData.length() + sizeof(recordstart);
1005 for(const auto& addr : addrs) {
1006 unsigned char rdatalen = addr.sin4.sin_family == AF_INET ? sizeof(addr.sin4.sin_addr.s_addr) : sizeof(addr.sin6.sin6_addr.s6_addr);
1007 const unsigned char recordstart[]={0xc0, 0x0c, // compressed name
1008 0, (unsigned char) (addr.sin4.sin_family == AF_INET ? QType::A : QType::AAAA),
1009 0, QClass::IN, // IN
1012 static_assert(sizeof(recordstart) == 12, "sizeof(recordstart) must be equal to 12, otherwise the above check is invalid");
1014 memcpy(dest, recordstart, sizeof(recordstart));
1015 dest += sizeof(recordstart);
1018 addr.sin4.sin_family == AF_INET ? (void*)&addr.sin4.sin_addr.s_addr : (void*)&addr.sin6.sin6_addr.s6_addr,
1021 dq->len += rdatalen + sizeof(recordstart);
1026 dq->dh->ancount = htons(dq->dh->ancount);
1028 return Action::HeaderModify;
1031 string toString() const override
1033 string ret = "spoof in ";
1034 if(!d_cname.empty()) {
1035 ret+=d_cname.toString()+ " ";
1037 for(const auto& a : d_addrs)
1038 ret += a.toString()+" ";
1043 std::vector<ComboAddress> d_addrs;
1047 class MacAddrAction : public DNSAction
1050 MacAddrAction(uint16_t code) : d_code(code)
1052 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1055 return Action::None;
1057 string mac = getMACAddress(*dq->remote);
1059 return Action::None;
1062 generateEDNSOption(d_code, mac, optRData);
1065 generateOptRR(optRData, res);
1067 if ((dq->size - dq->len) < res.length())
1068 return Action::None;
1070 dq->dh->arcount = htons(1);
1071 char* dest = ((char*)dq->dh) + dq->len;
1072 memcpy(dest, res.c_str(), res.length());
1073 dq->len += res.length();
1075 return Action::None;
1077 string toString() const override
1079 return "add EDNS MAC (code="+std::to_string(d_code)+")";
1085 class NoRecurseAction : public DNSAction
1088 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1091 return Action::None;
1093 string toString() const override
1099 class LogAction : public DNSAction, public boost::noncopyable
1102 LogAction() : d_fp(0)
1105 LogAction(const std::string& str, bool binary=true, bool append=false, bool buffered=true) : d_fname(str), d_binary(binary)
1110 d_fp = fopen(str.c_str(), "a+");
1112 d_fp = fopen(str.c_str(), "w");
1114 throw std::runtime_error("Unable to open file '"+str+"' for logging: "+string(strerror(errno)));
1118 ~LogAction() override
1123 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1126 vinfolog("Packet from %s for %s %s with id %d", dq->remote->toStringWithPort(), dq->qname->toString(), QType(dq->qtype).getName(), dq->dh->id);
1130 string out = dq->qname->toDNSString();
1131 fwrite(out.c_str(), 1, out.size(), d_fp);
1132 fwrite((void*)&dq->qtype, 1, 2, d_fp);
1135 fprintf(d_fp, "Packet from %s for %s %s with id %d\n", dq->remote->toStringWithPort().c_str(), dq->qname->toString().c_str(), QType(dq->qtype).getName().c_str(), dq->dh->id);
1138 return Action::None;
1140 string toString() const override
1142 if (!d_fname.empty()) {
1143 return "log to " + d_fname;
1150 bool d_binary{true};
1154 class DisableValidationAction : public DNSAction
1157 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1160 return Action::None;
1162 string toString() const override
1168 class SkipCacheAction : public DNSAction
1171 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1173 dq->skipCache = true;
1174 return Action::None;
1176 string toString() const override
1178 return "skip cache";
1182 class ECSPrefixLengthAction : public DNSAction
1185 ECSPrefixLengthAction(uint16_t v4Length, uint16_t v6Length) : d_v4PrefixLength(v4Length), d_v6PrefixLength(v6Length)
1188 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1190 dq->ecsPrefixLength = dq->remote->sin4.sin_family == AF_INET ? d_v4PrefixLength : d_v6PrefixLength;
1191 return Action::None;
1193 string toString() const override
1195 return "set ECS prefix length to " + std::to_string(d_v4PrefixLength) + "/" + std::to_string(d_v6PrefixLength);
1198 uint16_t d_v4PrefixLength;
1199 uint16_t d_v6PrefixLength;
1202 class ECSOverrideAction : public DNSAction
1205 ECSOverrideAction(bool ecsOverride) : d_ecsOverride(ecsOverride)
1208 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1210 dq->ecsOverride = d_ecsOverride;
1211 return Action::None;
1213 string toString() const override
1215 return "set ECS override to " + std::to_string(d_ecsOverride);
1222 class DisableECSAction : public DNSAction
1225 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1228 return Action::None;
1230 string toString() const override
1232 return "disable ECS";
1236 class RemoteLogAction : public DNSAction, public boost::noncopyable
1239 RemoteLogAction(std::shared_ptr<RemoteLogger> logger, boost::optional<std::function<void(const DNSQuestion&, DNSDistProtoBufMessage*)> > alterFunc): d_logger(logger), d_alterFunc(alterFunc)
1242 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1244 #ifdef HAVE_PROTOBUF
1245 DNSDistProtoBufMessage message(*dq);
1248 std::lock_guard<std::mutex> lock(g_luamutex);
1249 (*d_alterFunc)(*dq, &message);
1253 message.serialize(data);
1254 d_logger->queueData(data);
1255 #endif /* HAVE_PROTOBUF */
1256 return Action::None;
1258 string toString() const override
1260 return "remote log to " + d_logger->toString();
1263 std::shared_ptr<RemoteLogger> d_logger;
1264 boost::optional<std::function<void(const DNSQuestion&, DNSDistProtoBufMessage*)> > d_alterFunc;
1267 class SNMPTrapAction : public DNSAction
1270 SNMPTrapAction(const std::string& reason): d_reason(reason)
1273 DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
1275 if (g_snmpAgent && g_snmpTrapsEnabled) {
1276 g_snmpAgent->sendDNSTrap(*dq, d_reason);
1279 return Action::None;
1281 string toString() const override
1283 return "send SNMP trap";
1286 std::string d_reason;
1289 class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopyable
1292 RemoteLogResponseAction(std::shared_ptr<RemoteLogger> logger, boost::optional<std::function<void(const DNSResponse&, DNSDistProtoBufMessage*)> > alterFunc, bool includeCNAME): d_logger(logger), d_alterFunc(alterFunc), d_includeCNAME(includeCNAME)
1295 DNSResponseAction::Action operator()(DNSResponse* dr, string* ruleresult) const override
1297 #ifdef HAVE_PROTOBUF
1298 DNSDistProtoBufMessage message(*dr, d_includeCNAME);
1301 std::lock_guard<std::mutex> lock(g_luamutex);
1302 (*d_alterFunc)(*dr, &message);
1306 message.serialize(data);
1307 d_logger->queueData(data);
1308 #endif /* HAVE_PROTOBUF */
1309 return Action::None;
1311 string toString() const override
1313 return "remote log response to " + d_logger->toString();
1316 std::shared_ptr<RemoteLogger> d_logger;
1317 boost::optional<std::function<void(const DNSResponse&, DNSDistProtoBufMessage*)> > d_alterFunc;
1318 bool d_includeCNAME;
1321 class DropResponseAction : public DNSResponseAction
1324 DNSResponseAction::Action operator()(DNSResponse* dr, string* ruleresult) const override
1326 return Action::Drop;
1328 string toString() const override
1334 class AllowResponseAction : public DNSResponseAction
1337 DNSResponseAction::Action operator()(DNSResponse* dr, string* ruleresult) const override
1339 return Action::Allow;
1341 string toString() const override
1347 class DelayResponseAction : public DNSResponseAction
1350 DelayResponseAction(int msec) : d_msec(msec)
1352 DNSResponseAction::Action operator()(DNSResponse* dr, string* ruleresult) const override
1354 *ruleresult=std::to_string(d_msec);
1355 return Action::Delay;
1357 string toString() const override
1359 return "delay by "+std::to_string(d_msec)+ " msec";
1365 class SNMPTrapResponseAction : public DNSResponseAction
1368 SNMPTrapResponseAction(const std::string& reason): d_reason(reason)
1371 DNSResponseAction::Action operator()(DNSResponse* dr, string* ruleresult) const override
1373 if (g_snmpAgent && g_snmpTrapsEnabled) {
1374 g_snmpAgent->sendDNSTrap(*dr, d_reason);
1377 return Action::None;
1379 string toString() const override
1381 return "send SNMP trap";
1384 std::string d_reason;