]>
Commit | Line | Data |
---|---|---|
49a699c4 | 1 | /* |
6edbf68a PL |
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 | */ | |
870a0fe4 AT |
22 | #ifdef HAVE_CONFIG_H |
23 | #include "config.h" | |
24 | #endif | |
49a699c4 BH |
25 | #include "syncres.hh" |
26 | #include "arguments.hh" | |
27 | #include "zoneparser-tng.hh" | |
28 | #include "logger.hh" | |
29 | #include "dnsrecords.hh" | |
10c96475 | 30 | #include "root-addresses.hh" |
302df819 AT |
31 | |
32 | extern int g_argc; | |
33 | extern char** g_argv; | |
49a699c4 BH |
34 | |
35 | void primeHints(void) | |
36 | { | |
37 | // prime root cache | |
fb17a52f | 38 | const vState validationState = Insecure; |
e325f20c | 39 | vector<DNSRecord> nsset; |
49a699c4 | 40 | if(!t_RC) |
f26bf547 | 41 | t_RC = std::unique_ptr<MemRecursorCache>(new MemRecursorCache()); |
49a699c4 BH |
42 | |
43 | if(::arg()["hint-file"].empty()) { | |
e325f20c | 44 | DNSRecord arr, aaaarr, nsrr; |
12c06211 | 45 | nsrr.d_name=g_rootdnsname; |
e325f20c | 46 | arr.d_type=QType::A; |
47 | aaaarr.d_type=QType::AAAA; | |
48 | nsrr.d_type=QType::NS; | |
49 | arr.d_ttl=aaaarr.d_ttl=nsrr.d_ttl=time(0)+3600000; | |
49a699c4 BH |
50 | |
51 | for(char c='a';c<='m';++c) { | |
e863a05a | 52 | char templ[40]; |
49a699c4 | 53 | strncpy(templ,"a.root-servers.net.", sizeof(templ) - 1); |
a683e8bd | 54 | templ[sizeof(templ)-1] = '\0'; |
49a699c4 | 55 | *templ=c; |
e325f20c | 56 | aaaarr.d_name=arr.d_name=DNSName(templ); |
57 | nsrr.d_content=std::make_shared<NSRecordContent>(DNSName(templ)); | |
10c96475 | 58 | arr.d_content=std::make_shared<ARecordContent>(ComboAddress(rootIps4[c-'a'])); |
e325f20c | 59 | vector<DNSRecord> aset; |
60 | aset.push_back(arr); | |
2b984251 | 61 | t_RC->replace(time(0), DNSName(templ), QType(QType::A), aset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true, boost::none, validationState); // auth, nuke it all |
10c96475 PL |
62 | if (rootIps6[c-'a'] != NULL) { |
63 | aaaarr.d_content=std::make_shared<AAAARecordContent>(ComboAddress(rootIps6[c-'a'])); | |
49a699c4 | 64 | |
e325f20c | 65 | vector<DNSRecord> aaaaset; |
66 | aaaaset.push_back(aaaarr); | |
2b984251 | 67 | t_RC->replace(time(0), DNSName(templ), QType(QType::AAAA), aaaaset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true, boost::none, validationState); |
49a699c4 BH |
68 | } |
69 | ||
e325f20c | 70 | nsset.push_back(nsrr); |
49a699c4 BH |
71 | } |
72 | } | |
73 | else { | |
74 | ZoneParserTNG zpt(::arg()["hint-file"]); | |
75 | DNSResourceRecord rr; | |
76 | ||
77 | while(zpt.get(rr)) { | |
78 | rr.ttl+=time(0); | |
79 | if(rr.qtype.getCode()==QType::A) { | |
e325f20c | 80 | vector<DNSRecord> aset; |
81 | aset.push_back(DNSRecord(rr)); | |
2b984251 | 82 | t_RC->replace(time(0), rr.qname, QType(QType::A), aset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true, boost::none, validationState); // auth, etc see above |
49a699c4 | 83 | } else if(rr.qtype.getCode()==QType::AAAA) { |
e325f20c | 84 | vector<DNSRecord> aaaaset; |
85 | aaaaset.push_back(DNSRecord(rr)); | |
2b984251 | 86 | t_RC->replace(time(0), rr.qname, QType(QType::AAAA), aaaaset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true, boost::none, validationState); |
49a699c4 BH |
87 | } else if(rr.qtype.getCode()==QType::NS) { |
88 | rr.content=toLower(rr.content); | |
e325f20c | 89 | nsset.push_back(DNSRecord(rr)); |
49a699c4 BH |
90 | } |
91 | } | |
92 | } | |
0d032a66 | 93 | t_RC->doWipeCache(g_rootdnsname, false, QType::NS); |
2b984251 | 94 | t_RC->replace(time(0), g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, boost::none, validationState); // and stuff in the cache |
49a699c4 BH |
95 | } |
96 | ||
9065eb05 | 97 | static void makeNameToIPZone(std::shared_ptr<SyncRes::domainmap_t> newMap, const DNSName& hostname, const string& ip) |
49a699c4 BH |
98 | { |
99 | SyncRes::AuthDomain ad; | |
687fe166 CH |
100 | ad.d_rdForward=false; |
101 | ||
e325f20c | 102 | DNSRecord dr; |
103 | dr.d_name=hostname; | |
e693ff5a | 104 | dr.d_place=DNSResourceRecord::ANSWER; |
e325f20c | 105 | dr.d_ttl=86400; |
106 | dr.d_type=QType::SOA; | |
107 | dr.d_class = 1; | |
6177a176 | 108 | dr.d_content = DNSRecordContent::mastermake(QType::SOA, 1, "localhost. root 1 604800 86400 2419200 604800"); |
49a699c4 | 109 | |
e325f20c | 110 | ad.d_records.insert(dr); |
49a699c4 | 111 | |
e325f20c | 112 | dr.d_type=QType::NS; |
113 | dr.d_content=std::make_shared<NSRecordContent>("localhost."); | |
49a699c4 | 114 | |
e325f20c | 115 | ad.d_records.insert(dr); |
49a699c4 | 116 | |
e325f20c | 117 | dr.d_type=QType::A; |
6177a176 | 118 | dr.d_content = DNSRecordContent::mastermake(QType::A, 1, ip); |
e325f20c | 119 | ad.d_records.insert(dr); |
49a699c4 | 120 | |
e325f20c | 121 | if(newMap->count(dr.d_name)) { |
e6a9dde5 | 122 | g_log<<Logger::Warning<<"Hosts file will not overwrite zone '"<<dr.d_name<<"' already loaded"<<endl; |
49a699c4 BH |
123 | } |
124 | else { | |
e6a9dde5 | 125 | g_log<<Logger::Warning<<"Inserting forward zone '"<<dr.d_name<<"' based on hosts file"<<endl; |
3337c2f7 RG |
126 | ad.d_name=dr.d_name; |
127 | (*newMap)[ad.d_name]=ad; | |
49a699c4 BH |
128 | } |
129 | } | |
130 | ||
131 | //! parts[0] must be an IP address, the rest must be host names | |
9065eb05 | 132 | static void makeIPToNamesZone(std::shared_ptr<SyncRes::domainmap_t> newMap, const vector<string>& parts) |
49a699c4 BH |
133 | { |
134 | string address=parts[0]; | |
135 | vector<string> ipparts; | |
136 | stringtok(ipparts, address,"."); | |
137 | ||
138 | SyncRes::AuthDomain ad; | |
687fe166 CH |
139 | ad.d_rdForward=false; |
140 | ||
e325f20c | 141 | DNSRecord dr; |
49a699c4 | 142 | for(int n=ipparts.size()-1; n>=0 ; --n) { |
e325f20c | 143 | dr.d_name.appendRawLabel(ipparts[n]); |
49a699c4 | 144 | } |
e325f20c | 145 | dr.d_name.appendRawLabel("in-addr"); |
146 | dr.d_name.appendRawLabel("arpa"); | |
147 | dr.d_class = 1; | |
e693ff5a | 148 | dr.d_place=DNSResourceRecord::ANSWER; |
e325f20c | 149 | dr.d_ttl=86400; |
150 | dr.d_type=QType::SOA; | |
6177a176 | 151 | dr.d_content=DNSRecordContent::mastermake(QType::SOA, 1, "localhost. root 1 604800 86400 2419200 604800"); |
49a699c4 | 152 | |
e325f20c | 153 | ad.d_records.insert(dr); |
49a699c4 | 154 | |
e325f20c | 155 | dr.d_type=QType::NS; |
156 | dr.d_content=std::make_shared<NSRecordContent>(DNSName("localhost.")); | |
49a699c4 | 157 | |
e325f20c | 158 | ad.d_records.insert(dr); |
159 | dr.d_type=QType::PTR; | |
49a699c4 BH |
160 | |
161 | if(ipparts.size()==4) // otherwise this is a partial zone | |
162 | for(unsigned int n=1; n < parts.size(); ++n) { | |
6177a176 | 163 | dr.d_content=DNSRecordContent::mastermake(QType::PTR, 1, DNSName(parts[n]).toString()); // XXX FIXME DNSNAME PAIN CAN THIS BE RIGHT? |
e325f20c | 164 | ad.d_records.insert(dr); |
49a699c4 BH |
165 | } |
166 | ||
e325f20c | 167 | if(newMap->count(dr.d_name)) { |
e6a9dde5 | 168 | g_log<<Logger::Warning<<"Will not overwrite zone '"<<dr.d_name<<"' already loaded"<<endl; |
49a699c4 BH |
169 | } |
170 | else { | |
171 | if(ipparts.size()==4) | |
e6a9dde5 | 172 | g_log<<Logger::Warning<<"Inserting reverse zone '"<<dr.d_name<<"' based on hosts file"<<endl; |
3337c2f7 RG |
173 | ad.d_name = dr.d_name; |
174 | (*newMap)[ad.d_name]=ad; | |
49a699c4 BH |
175 | } |
176 | } | |
177 | ||
178 | ||
179 | ||
180 | /* mission in life: parse three cases | |
181 | 1) 1.2.3.4 | |
182 | 2) 1.2.3.4:5300 | |
183 | 3) 2001::1 | |
184 | 4) [2002::1]:53 | |
185 | */ | |
186 | ||
187 | ComboAddress parseIPAndPort(const std::string& input, uint16_t port) | |
188 | { | |
189 | if(input.find(':') == string::npos || input.empty()) // common case | |
190 | return ComboAddress(input, port); | |
191 | ||
192 | pair<string,string> both; | |
193 | ||
194 | try { // case 2 | |
195 | both=splitField(input,':'); | |
335da0ba | 196 | uint16_t newport=static_cast<uint16_t>(pdns_stou(both.second)); |
49a699c4 BH |
197 | return ComboAddress(both.first, newport); |
198 | } | |
199 | catch(...){} | |
200 | ||
201 | if(input[0]=='[') { // case 4 | |
202 | both=splitField(input.substr(1),']'); | |
335da0ba | 203 | return ComboAddress(both.first, both.second.empty() ? port : static_cast<uint16_t>(pdns_stou(both.second.substr(1)))); |
49a699c4 BH |
204 | } |
205 | ||
206 | return ComboAddress(input, port); // case 3 | |
207 | } | |
208 | ||
209 | ||
210 | void convertServersForAD(const std::string& input, SyncRes::AuthDomain& ad, const char* sepa, bool verbose=true) | |
211 | { | |
212 | vector<string> servers; | |
213 | stringtok(servers, input, sepa); | |
214 | ad.d_servers.clear(); | |
215 | ||
216 | for(vector<string>::const_iterator iter = servers.begin(); iter != servers.end(); ++iter) { | |
217 | if(verbose && iter != servers.begin()) | |
e6a9dde5 | 218 | g_log<<", "; |
49a699c4 BH |
219 | |
220 | ComboAddress addr=parseIPAndPort(*iter, 53); | |
221 | if(verbose) | |
e6a9dde5 | 222 | g_log<<addr.toStringWithPort(); |
49a699c4 BH |
223 | ad.d_servers.push_back(addr); |
224 | } | |
225 | if(verbose) | |
e6a9dde5 | 226 | g_log<<endl; |
49a699c4 BH |
227 | } |
228 | ||
3427fa8a | 229 | void* pleaseWipeNegCache() |
49a699c4 | 230 | { |
a712cb56 | 231 | SyncRes::clearNegCache(); |
3427fa8a | 232 | return 0; |
49a699c4 BH |
233 | } |
234 | ||
9065eb05 | 235 | void* pleaseUseNewSDomainsMap(std::shared_ptr<SyncRes::domainmap_t> newmap) |
49a699c4 | 236 | { |
a712cb56 | 237 | SyncRes::setDomainMap(newmap); |
3427fa8a | 238 | return 0; |
49a699c4 BH |
239 | } |
240 | ||
241 | string reloadAuthAndForwards() | |
242 | { | |
a712cb56 | 243 | std::shared_ptr<SyncRes::domainmap_t> original=SyncRes::getDomainMap(); |
49a699c4 BH |
244 | |
245 | try { | |
e6a9dde5 | 246 | g_log<<Logger::Warning<<"Reloading zones, purging data from cache"<<endl; |
a712cb56 | 247 | |
49a699c4 | 248 | string configname=::arg()["config-dir"]+"/recursor.conf"; |
3e63da83 JR |
249 | if(::arg()["config-name"]!="") { |
250 | configname=::arg()["config-dir"]+"/recursor-"+::arg()["config-name"]+".conf"; | |
251 | } | |
49a699c4 BH |
252 | cleanSlashes(configname); |
253 | ||
49e3ed87 PL |
254 | if(!::arg().preParseFile(configname.c_str(), "forward-zones")) |
255 | throw runtime_error("Unable to re-parse configuration file '"+configname+"'"); | |
49a699c4 | 256 | ::arg().preParseFile(configname.c_str(), "forward-zones-file"); |
4b6d1ba4 | 257 | ::arg().preParseFile(configname.c_str(), "forward-zones-recurse"); |
49a699c4 BH |
258 | ::arg().preParseFile(configname.c_str(), "auth-zones"); |
259 | ::arg().preParseFile(configname.c_str(), "export-etc-hosts", "off"); | |
260 | ::arg().preParseFile(configname.c_str(), "serve-rfc1918"); | |
302df819 AT |
261 | ::arg().preParseFile(configname.c_str(), "include-dir"); |
262 | ::arg().preParse(g_argc, g_argv, "include-dir"); | |
263 | ||
264 | // then process includes | |
265 | std::vector<std::string> extraConfigs; | |
266 | ::arg().gatherIncludes(extraConfigs); | |
267 | ||
ef7cd021 | 268 | for(const std::string& fn : extraConfigs) { |
49e3ed87 PL |
269 | if(!::arg().preParseFile(fn.c_str(), "forward-zones", ::arg()["forward-zones"])) |
270 | throw runtime_error("Unable to re-parse configuration file include '"+fn+"'"); | |
302df819 | 271 | ::arg().preParseFile(fn.c_str(), "forward-zones-file", ::arg()["forward-zones-file"]); |
4b6d1ba4 | 272 | ::arg().preParseFile(fn.c_str(), "forward-zones-recurse", ::arg()["forward-zones-recurse"]); |
302df819 AT |
273 | ::arg().preParseFile(fn.c_str(), "auth-zones",::arg()["auth-zones"]); |
274 | ::arg().preParseFile(fn.c_str(), "export-etc-hosts",::arg()["export-etc-hosts"]); | |
275 | ::arg().preParseFile(fn.c_str(), "serve-rfc1918",::arg()["serve-rfc1918"]); | |
276 | } | |
49a699c4 | 277 | |
452d5116 AT |
278 | ::arg().preParse(g_argc, g_argv, "forward-zones"); |
279 | ::arg().preParse(g_argc, g_argv, "forward-zones-file"); | |
4b6d1ba4 | 280 | ::arg().preParse(g_argc, g_argv, "forward-zones-recurse"); |
452d5116 AT |
281 | ::arg().preParse(g_argc, g_argv, "auth-zones"); |
282 | ::arg().preParse(g_argc, g_argv, "export-etc-hosts"); | |
283 | ::arg().preParse(g_argc, g_argv, "serve-rfc1918"); | |
284 | ||
9065eb05 | 285 | std::shared_ptr<SyncRes::domainmap_t> newDomainMap = parseAuthAndForwards(); |
b68af3ee | 286 | |
287 | // purge both original and new names | |
288 | std::set<DNSName> oldAndNewDomains; | |
9065eb05 | 289 | for(const auto& i : *newDomainMap) { |
b68af3ee | 290 | oldAndNewDomains.insert(i.first); |
291 | } | |
292 | ||
293 | if(original) { | |
294 | for(const auto& i : *original) { | |
295 | oldAndNewDomains.insert(i.first); | |
296 | } | |
297 | } | |
298 | ||
299 | for(const auto i : oldAndNewDomains) { | |
300 | broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, i, true)); | |
301 | broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, i, true)); | |
302 | broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, i, true)); | |
49a699c4 BH |
303 | } |
304 | ||
9065eb05 | 305 | broadcastFunction(boost::bind(pleaseUseNewSDomainsMap, newDomainMap)); |
49a699c4 BH |
306 | return "ok\n"; |
307 | } | |
308 | catch(std::exception& e) { | |
e6a9dde5 | 309 | g_log<<Logger::Error<<"Encountered error reloading zones, keeping original data: "<<e.what()<<endl; |
49a699c4 | 310 | } |
3f81d239 | 311 | catch(PDNSException& ae) { |
e6a9dde5 | 312 | g_log<<Logger::Error<<"Encountered error reloading zones, keeping original data: "<<ae.reason<<endl; |
49a699c4 BH |
313 | } |
314 | catch(...) { | |
e6a9dde5 | 315 | g_log<<Logger::Error<<"Encountered unknown error reloading zones, keeping original data"<<endl; |
49a699c4 BH |
316 | } |
317 | return "reloading failed, see log\n"; | |
318 | } | |
319 | ||
9065eb05 | 320 | std::shared_ptr<SyncRes::domainmap_t> parseAuthAndForwards() |
49a699c4 BH |
321 | { |
322 | TXTRecordContent::report(); | |
323 | OPTRecordContent::report(); | |
324 | ||
9065eb05 | 325 | auto newMap = std::make_shared<SyncRes::domainmap_t>(); |
49a699c4 BH |
326 | |
327 | typedef vector<string> parts_t; | |
328 | parts_t parts; | |
329 | const char *option_names[3]={"auth-zones", "forward-zones", "forward-zones-recurse"}; | |
330 | for(int n=0; n < 3 ; ++n ) { | |
331 | parts.clear(); | |
39588f55 | 332 | stringtok(parts, ::arg()[option_names[n]], " ,\t\n\r"); |
49a699c4 BH |
333 | for(parts_t::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { |
334 | SyncRes::AuthDomain ad; | |
71925546 AT |
335 | if ((*iter).find('=') == string::npos) |
336 | throw PDNSException("Error parsing '" + *iter + "', missing ="); | |
49a699c4 BH |
337 | pair<string,string> headers=splitField(*iter, '='); |
338 | trim(headers.first); | |
339 | trim(headers.second); | |
c5c066bf | 340 | // headers.first=toCanonic("", headers.first); |
49a699c4 | 341 | if(n==0) { |
687fe166 | 342 | ad.d_rdForward = false; |
e6a9dde5 | 343 | g_log<<Logger::Error<<"Parsing authoritative data for zone '"<<headers.first<<"' from file '"<<headers.second<<"'"<<endl; |
c5c066bf | 344 | ZoneParserTNG zpt(headers.second, DNSName(headers.first)); |
49a699c4 | 345 | DNSResourceRecord rr; |
e325f20c | 346 | DNSRecord dr; |
49a699c4 BH |
347 | while(zpt.get(rr)) { |
348 | try { | |
e325f20c | 349 | dr=DNSRecord(rr); |
e693ff5a | 350 | dr.d_place=DNSResourceRecord::ANSWER; |
49a699c4 BH |
351 | } |
352 | catch(std::exception &e) { | |
86f1af1c | 353 | throw PDNSException("Error parsing record '"+rr.qname.toLogString()+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"': "+e.what()); |
49a699c4 BH |
354 | } |
355 | catch(...) { | |
86f1af1c | 356 | throw PDNSException("Error parsing record '"+rr.qname.toLogString()+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"'"); |
49a699c4 BH |
357 | } |
358 | ||
e325f20c | 359 | ad.d_records.insert(dr); |
49a699c4 BH |
360 | } |
361 | } | |
362 | else { | |
e6a9dde5 | 363 | g_log<<Logger::Error<<"Redirecting queries for zone '"<<headers.first<<"' "; |
49a699c4 | 364 | if(n == 2) { |
e6a9dde5 | 365 | g_log<<"with recursion "; |
687fe166 | 366 | ad.d_rdForward = true; |
49a699c4 | 367 | } |
687fe166 | 368 | else ad.d_rdForward = false; |
e6a9dde5 | 369 | g_log<<"to: "; |
49a699c4 BH |
370 | |
371 | convertServersForAD(headers.second, ad, ";"); | |
372 | if(n == 2) { | |
687fe166 | 373 | ad.d_rdForward = true; |
49a699c4 BH |
374 | } |
375 | } | |
3337c2f7 RG |
376 | |
377 | ad.d_name = DNSName(headers.first); | |
378 | (*newMap)[ad.d_name]=ad; | |
49a699c4 BH |
379 | } |
380 | } | |
381 | ||
382 | if(!::arg()["forward-zones-file"].empty()) { | |
e6a9dde5 | 383 | g_log<<Logger::Warning<<"Reading zone forwarding information from '"<<::arg()["forward-zones-file"]<<"'"<<endl; |
49a699c4 | 384 | SyncRes::AuthDomain ad; |
5e1f23ca RG |
385 | auto fp = std::unique_ptr<FILE, int(*)(FILE*)>(fopen(::arg()["forward-zones-file"].c_str(), "r"), fclose); |
386 | if(!fp) { | |
3f81d239 | 387 | throw PDNSException("Error opening forward-zones-file '"+::arg()["forward-zones-file"]+"': "+stringerror()); |
49a699c4 BH |
388 | } |
389 | ||
834942f1 | 390 | string line; |
49a699c4 BH |
391 | int linenum=0; |
392 | uint64_t before = newMap->size(); | |
834942f1 | 393 | while(linenum++, stringfgets(fp.get(), line)) { |
fa2909dc PL |
394 | trim(line); |
395 | if (line[0] == '#') // Comment line, skip to the next line | |
396 | continue; | |
49a699c4 BH |
397 | string domain, instructions; |
398 | tie(domain, instructions)=splitField(line, '='); | |
fa2909dc | 399 | instructions = splitField(instructions, '#').first; // Remove EOL comments |
49a699c4 BH |
400 | trim(domain); |
401 | trim(instructions); | |
e58483cc BH |
402 | if(domain.empty() && instructions.empty()) { // empty line |
403 | continue; | |
404 | } | |
49a699c4 BH |
405 | if(boost::starts_with(domain,"+")) { |
406 | domain=domain.c_str()+1; | |
407 | ad.d_rdForward = true; | |
408 | } | |
409 | else | |
410 | ad.d_rdForward = false; | |
411 | if(domain.empty()) { | |
335da0ba | 412 | throw PDNSException("Error parsing line "+std::to_string(linenum)+" of " +::arg()["forward-zones-file"]); |
49a699c4 BH |
413 | } |
414 | ||
415 | try { | |
416 | convertServersForAD(instructions, ad, ",; ", false); | |
417 | } | |
418 | catch(...) { | |
335da0ba | 419 | throw PDNSException("Conversion error parsing line "+std::to_string(linenum)+" of " +::arg()["forward-zones-file"]); |
49a699c4 BH |
420 | } |
421 | ||
3337c2f7 RG |
422 | ad.d_name = DNSName(domain); |
423 | (*newMap)[ad.d_name]=ad; | |
49a699c4 | 424 | } |
e6a9dde5 | 425 | g_log<<Logger::Warning<<"Done parsing " << newMap->size() - before<<" forwarding instructions from file '"<<::arg()["forward-zones-file"]<<"'"<<endl; |
49a699c4 BH |
426 | } |
427 | ||
428 | if(::arg().mustDo("export-etc-hosts")) { | |
429 | string line; | |
430 | string fname=::arg()["etc-hosts-file"]; | |
431 | ||
432 | ifstream ifs(fname.c_str()); | |
433 | if(!ifs) { | |
8c0128ef | 434 | g_log<<Logger::Warning<<"Could not open "<<fname<<" for reading"<<endl; |
49a699c4 BH |
435 | } |
436 | else { | |
ac0b4eb3 | 437 | string searchSuffix = ::arg()["export-etc-hosts-search-suffix"]; |
49a699c4 BH |
438 | string::size_type pos; |
439 | while(getline(ifs,line)) { | |
232f0877 CH |
440 | pos=line.find('#'); |
441 | if(pos!=string::npos) | |
442 | line.resize(pos); | |
443 | trim(line); | |
444 | if(line.empty()) | |
445 | continue; | |
446 | parts.clear(); | |
447 | stringtok(parts, line, "\t\r\n "); | |
448 | if(parts[0].find(':')!=string::npos) | |
449 | continue; | |
450 | ||
451 | for(unsigned int n=1; n < parts.size(); ++n) { | |
452 | if(searchSuffix.empty() || parts[n].find('.') != string::npos) | |
8171ab83 | 453 | makeNameToIPZone(newMap, DNSName(parts[n]), parts[0]); |
232f0877 | 454 | else { |
8171ab83 | 455 | DNSName canonic=toCanonic(DNSName(searchSuffix), parts[n]); /// XXXX DNSName pain |
456 | if(canonic != DNSName(parts[n])) { // XXX further DNSName pain | |
232f0877 | 457 | makeNameToIPZone(newMap, canonic, parts[0]); |
ac0b4eb3 BH |
458 | } |
459 | } | |
460 | } | |
232f0877 | 461 | makeIPToNamesZone(newMap, parts); |
49a699c4 BH |
462 | } |
463 | } | |
464 | } | |
465 | if(::arg().mustDo("serve-rfc1918")) { | |
e6a9dde5 | 466 | g_log<<Logger::Warning<<"Inserting rfc 1918 private space zones"<<endl; |
49a699c4 BH |
467 | parts.clear(); |
468 | parts.push_back("127"); | |
469 | makeIPToNamesZone(newMap, parts); | |
470 | parts[0]="10"; | |
471 | makeIPToNamesZone(newMap, parts); | |
472 | ||
473 | parts[0]="192.168"; | |
474 | makeIPToNamesZone(newMap, parts); | |
475 | for(int n=16; n < 32; n++) { | |
335da0ba | 476 | parts[0]="172."+std::to_string(n); |
49a699c4 BH |
477 | makeIPToNamesZone(newMap,parts); |
478 | } | |
479 | } | |
480 | return newMap; | |
481 | } | |
482 |