]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/filterpo.cc
pdns_recursor.cc: Move comment to the right place
[thirdparty/pdns.git] / pdns / filterpo.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 */
644dd1da 22#include "filterpo.hh"
23#include <iostream>
24#include "namespaces.hh"
25#include "dnsrecords.hh"
26
27DNSFilterEngine::DNSFilterEngine()
28{
29}
30
31bool findNamedPolicy(const map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol)
32{
33 DNSName s(qname);
34
35 /* for www.powerdns.com, we need to check:
36 www.powerdns.com.
37 *.powerdns.com.
38 powerdns.com.
39 *.com.
40 com.
41 *.
42 . */
43
44 bool first=true;
45 do {
46 auto iter = polmap.find(s);
47 if(iter != polmap.end()) {
48 pol=iter->second;
49 return true;
50 }
51 if(!first) {
52 iter = polmap.find(DNSName("*")+s);
53 if(iter != polmap.end()) {
54 pol=iter->second;
55 return true;
56 }
57 }
58 first=false;
59 } while(s.chopOff());
60 return false;
61}
62
63DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qname) const
64{
39ec5d29 65 // cout<<"Got question for nameserver name "<<qname<<endl;
83971888 66 Policy pol{PolicyKind::NoAction, nullptr, "", 0};
644dd1da 67 for(const auto& z : d_zones) {
68 if(findNamedPolicy(z.propolName, qname, pol)) {
de0f72ba 69 // cerr<<"Had a hit on the nameserver ("<<qname<<") used to process the query"<<endl;
644dd1da 70 return pol;
71 }
72 }
73 return pol;
74}
75
76
77DNSFilterEngine::Policy DNSFilterEngine::getQueryPolicy(const DNSName& qname, const ComboAddress& ca) const
78{
de0f72ba 79 // cout<<"Got question for "<<qname<<" from "<<ca.toString()<<endl;
644dd1da 80
83971888 81 Policy pol{PolicyKind::NoAction, nullptr, "", 0};
644dd1da 82 for(const auto& z : d_zones) {
83 if(findNamedPolicy(z.qpolName, qname, pol)) {
de0f72ba 84 // cerr<<"Had a hit on the name of the query"<<endl;
644dd1da 85 return pol;
86 }
87
0e760497 88 if(auto fnd=z.qpolAddr.lookup(ca)) {
89 // cerr<<"Had a hit on the IP address ("<<ca.toString()<<") of the client"<<endl;
90 return fnd->second;
644dd1da 91 }
92 }
93
39ec5d29 94 return pol;
644dd1da 95}
96
97DNSFilterEngine::Policy DNSFilterEngine::getPostPolicy(const vector<DNSRecord>& records) const
98{
99 ComboAddress ca;
100
101 for(const auto& r : records) {
589ad24b 102 if(r.d_place != DNSResourceRecord::ANSWER)
644dd1da 103 continue;
ba3c54cb
RG
104 if(r.d_type == QType::A) {
105 if (auto rec = getRR<ARecordContent>(r)) {
106 ca = rec->getCA();
107 }
108 }
109 else if(r.d_type == QType::AAAA) {
110 if (auto rec = getRR<AAAARecordContent>(r)) {
111 ca = rec->getCA();
112 }
113 }
644dd1da 114 else
115 continue;
116
117 for(const auto& z : d_zones) {
0e760497 118 if(auto fnd=z.postpolAddr.lookup(ca))
119 return fnd->second;
644dd1da 120 }
121 }
83971888 122 return Policy{PolicyKind::NoAction, nullptr, "", 0};
644dd1da 123}
124
125void DNSFilterEngine::assureZones(int zone)
126{
127 if((int)d_zones.size() <= zone)
128 d_zones.resize(zone+1);
644dd1da 129}
130
7eafc52f 131void DNSFilterEngine::clear(int zone)
132{
133 assureZones(zone);
134 auto& z = d_zones[zone];
135 z.qpolAddr.clear();
136 z.postpolAddr.clear();
137 z.propolName.clear();
138 z.qpolName.clear();
139}
140
644dd1da 141void DNSFilterEngine::addClientTrigger(const Netmask& nm, Policy pol, int zone)
142{
143 assureZones(zone);
0e760497 144 d_zones[zone].qpolAddr.insert(nm).second=pol;
644dd1da 145}
146
147void DNSFilterEngine::addResponseTrigger(const Netmask& nm, Policy pol, int zone)
148{
149 assureZones(zone);
0e760497 150 d_zones[zone].postpolAddr.insert(nm).second=pol;
644dd1da 151}
152
153void DNSFilterEngine::addQNameTrigger(const DNSName& n, Policy pol, int zone)
154{
155 assureZones(zone);
156 d_zones[zone].qpolName[n]=pol;
157}
158
159void DNSFilterEngine::addNSTrigger(const DNSName& n, Policy pol, int zone)
160{
161 assureZones(zone);
162 d_zones[zone].propolName[n]=pol;
163}
39ec5d29 164
165bool DNSFilterEngine::rmClientTrigger(const Netmask& nm, Policy pol, int zone)
166{
167 assureZones(zone);
168
169 auto& qpols = d_zones[zone].qpolAddr;
0e760497 170 qpols.erase(nm);
39ec5d29 171 return true;
172}
173
174bool DNSFilterEngine::rmResponseTrigger(const Netmask& nm, Policy pol, int zone)
175{
176 assureZones(zone);
177 auto& postpols = d_zones[zone].postpolAddr;
0e760497 178 postpols.erase(nm);
39ec5d29 179 return true;
180}
181
182bool DNSFilterEngine::rmQNameTrigger(const DNSName& n, Policy pol, int zone)
183{
184 assureZones(zone);
185 d_zones[zone].qpolName.erase(n); // XXX verify we had identical policy?
186 return true;
187}
188
189bool DNSFilterEngine::rmNSTrigger(const DNSName& n, Policy pol, int zone)
190{
191 assureZones(zone);
192 d_zones[zone].propolName.erase(n); // XXX verify policy matched? =pol;
193 return true;
194}