]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/filterpo.cc
Merge pull request #5247 from Habbie/requires-nit
[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
a2d0450e 31static bool findNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol)
644dd1da 32{
5678437b
PL
33 /* for www.powerdns.com, we need to check:
34 www.powerdns.com.
35 *.powerdns.com.
36 *.com.
37 *.
38 */
0a273054 39
a2d0450e
RG
40 std::unordered_map<DNSName, DNSFilterEngine::Policy>::const_iterator iter;
41 iter = polmap.find(qname);
bef458b2
PL
42
43 if(iter != polmap.end()) {
44 pol=iter->second;
45 return true;
46 }
5678437b 47
a2d0450e 48 DNSName s(qname);
bef458b2 49 while(s.chopOff()){
12c06211 50 iter = polmap.find(g_wildcarddnsname+s);
5678437b
PL
51 if(iter != polmap.end()) {
52 pol=iter->second;
53 return true;
54 }
bef458b2 55 }
644dd1da 56 return false;
57}
58
0a273054 59DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies) const
644dd1da 60{
39ec5d29 61 // cout<<"Got question for nameserver name "<<qname<<endl;
1f1ca368 62 Policy pol;
644dd1da 63 for(const auto& z : d_zones) {
0a273054
RG
64 if(z.name && discardedPolicies.find(*z.name) != discardedPolicies.end()) {
65 continue;
66 }
67
644dd1da 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;
b8470add 74}
644dd1da 75
0a273054 76DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const ComboAddress& address, const std::unordered_map<std::string,bool>& discardedPolicies) const
b8470add
PL
77{
78 // cout<<"Got question for nameserver IP "<<address.toString()<<endl;
79 for(const auto& z : d_zones) {
0a273054
RG
80 if(z.name && discardedPolicies.find(*z.name) != discardedPolicies.end()) {
81 continue;
82 }
83
b8470add
PL
84 if(auto fnd=z.propolNSAddr.lookup(address)) {
85 // cerr<<"Had a hit on the nameserver ("<<address.toString()<<") used to process the query"<<endl;
86 return fnd->second;;
87 }
88 }
1f1ca368 89 return Policy();
b8470add 90}
644dd1da 91
0a273054 92DNSFilterEngine::Policy DNSFilterEngine::getQueryPolicy(const DNSName& qname, const ComboAddress& ca, const std::unordered_map<std::string,bool>& discardedPolicies) const
644dd1da 93{
de0f72ba 94 // cout<<"Got question for "<<qname<<" from "<<ca.toString()<<endl;
1f1ca368 95 Policy pol;
644dd1da 96 for(const auto& z : d_zones) {
0a273054
RG
97 if(z.name && discardedPolicies.find(*z.name) != discardedPolicies.end()) {
98 continue;
99 }
100
644dd1da 101 if(findNamedPolicy(z.qpolName, qname, pol)) {
de0f72ba 102 // cerr<<"Had a hit on the name of the query"<<endl;
644dd1da 103 return pol;
104 }
105
0e760497 106 if(auto fnd=z.qpolAddr.lookup(ca)) {
107 // cerr<<"Had a hit on the IP address ("<<ca.toString()<<") of the client"<<endl;
108 return fnd->second;
644dd1da 109 }
110 }
111
39ec5d29 112 return pol;
644dd1da 113}
114
0a273054 115DNSFilterEngine::Policy DNSFilterEngine::getPostPolicy(const vector<DNSRecord>& records, const std::unordered_map<std::string,bool>& discardedPolicies) const
644dd1da 116{
117 ComboAddress ca;
644dd1da 118 for(const auto& r : records) {
589ad24b 119 if(r.d_place != DNSResourceRecord::ANSWER)
644dd1da 120 continue;
ba3c54cb
RG
121 if(r.d_type == QType::A) {
122 if (auto rec = getRR<ARecordContent>(r)) {
123 ca = rec->getCA();
124 }
125 }
126 else if(r.d_type == QType::AAAA) {
127 if (auto rec = getRR<AAAARecordContent>(r)) {
128 ca = rec->getCA();
129 }
130 }
644dd1da 131 else
132 continue;
133
134 for(const auto& z : d_zones) {
0a273054
RG
135 if(z.name && discardedPolicies.find(*z.name) != discardedPolicies.end()) {
136 continue;
137 }
138
0e760497 139 if(auto fnd=z.postpolAddr.lookup(ca))
140 return fnd->second;
644dd1da 141 }
142 }
1f1ca368 143 return Policy();
644dd1da 144}
145
0a273054 146void DNSFilterEngine::assureZones(size_t zone)
644dd1da 147{
0a273054 148 if(d_zones.size() <= zone)
644dd1da 149 d_zones.resize(zone+1);
644dd1da 150}
151
0a273054 152void DNSFilterEngine::clear(size_t zone)
7eafc52f 153{
154 assureZones(zone);
155 auto& z = d_zones[zone];
156 z.qpolAddr.clear();
157 z.postpolAddr.clear();
158 z.propolName.clear();
2ae56398 159 z.propolNSAddr.clear();
7eafc52f 160 z.qpolName.clear();
161}
162
0a7ef1b8
RG
163void DNSFilterEngine::clear()
164{
165 for(auto& z : d_zones) {
166 z.qpolAddr.clear();
167 z.postpolAddr.clear();
168 z.propolName.clear();
2ae56398 169 z.propolNSAddr.clear();
0a7ef1b8
RG
170 z.qpolName.clear();
171 }
172}
173
0a273054 174void DNSFilterEngine::addClientTrigger(const Netmask& nm, Policy pol, size_t zone)
644dd1da 175{
176 assureZones(zone);
0a273054 177 pol.d_name = d_zones[zone].name;
0e760497 178 d_zones[zone].qpolAddr.insert(nm).second=pol;
644dd1da 179}
180
0a273054 181void DNSFilterEngine::addResponseTrigger(const Netmask& nm, Policy pol, size_t zone)
644dd1da 182{
183 assureZones(zone);
0a273054 184 pol.d_name = d_zones[zone].name;
0e760497 185 d_zones[zone].postpolAddr.insert(nm).second=pol;
644dd1da 186}
187
0a273054 188void DNSFilterEngine::addQNameTrigger(const DNSName& n, Policy pol, size_t zone)
644dd1da 189{
190 assureZones(zone);
0a273054 191 pol.d_name = d_zones[zone].name;
644dd1da 192 d_zones[zone].qpolName[n]=pol;
193}
194
0a273054 195void DNSFilterEngine::addNSTrigger(const DNSName& n, Policy pol, size_t zone)
644dd1da 196{
197 assureZones(zone);
0a273054 198 pol.d_name = d_zones[zone].name;
644dd1da 199 d_zones[zone].propolName[n]=pol;
200}
39ec5d29 201
0a273054 202void DNSFilterEngine::addNSIPTrigger(const Netmask& nm, Policy pol, size_t zone)
b8470add
PL
203{
204 assureZones(zone);
0a273054 205 pol.d_name = d_zones[zone].name;
b8470add
PL
206 d_zones[zone].propolNSAddr.insert(nm).second = pol;
207}
208
0a273054 209bool DNSFilterEngine::rmClientTrigger(const Netmask& nm, Policy pol, size_t zone)
39ec5d29 210{
211 assureZones(zone);
212
213 auto& qpols = d_zones[zone].qpolAddr;
0e760497 214 qpols.erase(nm);
39ec5d29 215 return true;
216}
217
0a273054 218bool DNSFilterEngine::rmResponseTrigger(const Netmask& nm, Policy pol, size_t zone)
39ec5d29 219{
220 assureZones(zone);
221 auto& postpols = d_zones[zone].postpolAddr;
0e760497 222 postpols.erase(nm);
39ec5d29 223 return true;
224}
225
0a273054 226bool DNSFilterEngine::rmQNameTrigger(const DNSName& n, Policy pol, size_t zone)
39ec5d29 227{
228 assureZones(zone);
229 d_zones[zone].qpolName.erase(n); // XXX verify we had identical policy?
230 return true;
231}
232
0a273054 233bool DNSFilterEngine::rmNSTrigger(const DNSName& n, Policy pol, size_t zone)
39ec5d29 234{
235 assureZones(zone);
236 d_zones[zone].propolName.erase(n); // XXX verify policy matched? =pol;
237 return true;
238}
b8470add 239
0a273054 240bool DNSFilterEngine::rmNSIPTrigger(const Netmask& nm, Policy pol, size_t zone)
b8470add
PL
241{
242 assureZones(zone);
243 auto& pols = d_zones[zone].propolNSAddr;
244 pols.erase(nm);
245 return true;
246}