]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnsdistdist/dnsrulactions.cc
Merge pull request #4692 from cmouse/ssql-unique-ptr
[thirdparty/pdns.git] / pdns / dnsdistdist / dnsrulactions.cc
CommitLineData
12471842
PL
1/*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
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.
8 *
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.
12 *
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.
17 *
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.
21 */
cf6874ba 22#include "dnsrulactions.hh"
23#include <iostream>
24
25using namespace std;
26
384c2cb2 27TeeAction::TeeAction(const ComboAddress& ca, bool addECS) : d_remote(ca), d_addECS(addECS)
cf6874ba 28{
cf6874ba 29 d_fd=SSocket(d_remote.sin4.sin_family, SOCK_DGRAM, 0);
30 SConnect(d_fd, d_remote);
3d8a6b1d 31 setNonBlocking(d_fd);
32 d_worker=std::thread(std::bind(&TeeAction::worker, this));
cf6874ba 33}
34
35TeeAction::~TeeAction()
36{
cf6874ba 37 d_pleaseQuit=true;
38 close(d_fd);
39 d_worker.join();
40}
41
42DNSAction::Action TeeAction::operator()(DNSQuestion* dq, string* ruleresult) const
43{
3d8a6b1d 44 if(dq->tcp)
45 d_tcpdrops++;
46 else {
384c2cb2 47 ssize_t res;
3d8a6b1d 48 d_queries++;
384c2cb2
RG
49
50 if(d_addECS) {
51 std::string query;
52 std::string larger;
53 uint16_t len = dq->len;
54 bool ednsAdded = false;
55 bool ecsAdded = false;
56 query.reserve(dq->size);
57 query.assign((char*) dq->dh, len);
58
ff0902ec 59 handleEDNSClientSubnet((char*) query.c_str(), query.size(), dq->qname->wirelength(), &len, larger, &ednsAdded, &ecsAdded, *dq->remote, dq->ecsOverride, dq->ecsPrefixLength);
384c2cb2
RG
60
61 if (larger.empty()) {
62 res = send(d_fd, query.c_str(), len, 0);
63 }
64 else {
65 res = send(d_fd, larger.c_str(), larger.length(), 0);
66 }
67 }
68 else {
69 res = send(d_fd, (char*)dq->dh, dq->len, 0);
70 }
71
72 if (res <= 0)
3d8a6b1d 73 d_senderrors++;
74 }
cf6874ba 75 return DNSAction::Action::None;
76}
77
78string TeeAction::toString() const
79{
80 return "tee to "+d_remote.toStringWithPort();
81}
82
83std::unordered_map<string,double> TeeAction::getStats() const
84{
85 return {{"queries", d_queries},
3d8a6b1d 86 {"responses", d_responses},
87 {"recv-errors", d_recverrors},
88 {"send-errors", d_senderrors},
89 {"noerrors", d_noerrors},
90 {"nxdomains", d_nxdomains},
91 {"refuseds", d_refuseds},
92 {"servfails", d_servfails},
93 {"other-rcode", d_otherrcode},
94 {"tcp-drops", d_tcpdrops}
95 };
cf6874ba 96}
97
98void TeeAction::worker()
99{
100 char packet[1500];
101 int res=0;
3d8a6b1d 102 struct dnsheader* dh=(struct dnsheader*)packet;
cf6874ba 103 for(;;) {
3d8a6b1d 104 res=waitForData(d_fd, 0, 250000);
105 if(d_pleaseQuit)
106 break;
107 if(res < 0) {
108 usleep(250000);
109 continue;
110 }
111 if(res==0)
112 continue;
cf6874ba 113 res=recv(d_fd, packet, sizeof(packet), 0);
fa6c1f0c 114 if(res <= (int)sizeof(struct dnsheader))
3d8a6b1d 115 d_recverrors++;
cf6874ba 116 else if(res > 0)
117 d_responses++;
3d8a6b1d 118
119 if(dh->rcode == RCode::NoError)
120 d_noerrors++;
121 else if(dh->rcode == RCode::ServFail)
122 d_servfails++;
123 else if(dh->rcode == RCode::NXDomain)
124 d_nxdomains++;
125 else if(dh->rcode == RCode::Refused)
126 d_refuseds++;
127 else if(dh->rcode == RCode::FormErr)
128 d_formerrs++;
129 else if(dh->rcode == RCode::NotImp)
130 d_notimps++;
cf6874ba 131 }
132}