]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/syncres.cc
new bindbackend
[thirdparty/pdns.git] / pdns / syncres.cc
CommitLineData
86c152f2
BH
1/*
2 PowerDNS Versatile Database Driven Nameserver
20177d1d 3 Copyright (C) 2003 PowerDNS.COM BV
86c152f2
BH
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
caa6eefa
BH
19
20#include "utility.hh"
288f4aa9 21#include "syncres.hh"
86c152f2
BH
22#include <iostream>
23#include <map>
24#include <algorithm>
afbe2787 25#include <set>
86c152f2
BH
26#include <cerrno>
27#include <cstdio>
28#include <cstdlib>
86c152f2 29#include <utility>
3de83124 30#include <deque>
c836dc19 31#include "logger.hh"
20177d1d 32#include "misc.hh"
86c152f2
BH
33#include "arguments.hh"
34#include "lwres.hh"
35
7b35aa49
BH
36map<string,string> SyncRes::s_negcache;
37unsigned int SyncRes::s_queries;
38unsigned int SyncRes::s_outqueries;
3de83124 39unsigned int SyncRes::s_throttledqueries;
7b35aa49 40bool SyncRes::s_log;
c836dc19
BH
41
42#define LOG if(s_log)L<<Logger::Warning
728485ca 43
3de83124
BH
44Throttle<string> SyncRes::s_throttle;
45
728485ca 46/** everything begins here - this is the entry point just after receiving a packet */
7b35aa49 47int SyncRes::beginResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret)
728485ca 48{
7bf26383 49 set<GetBestNSAnswer> beenthere;
c836dc19 50 s_queries++;
7bf26383 51 int res=doResolve(qname, qtype, ret,0,beenthere);
728485ca
BH
52 if(!res)
53 addCruft(qname, ret);
728485ca
BH
54 return res;
55}
afbe2787 56
7b35aa49 57int SyncRes::doResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, set<GetBestNSAnswer>& beenthere)
afbe2787 58{
c836dc19
BH
59 string prefix(d_prefix);
60 prefix.append(depth, ' ');
728485ca
BH
61
62 int res;
c836dc19
BH
63 if(!(d_nocache && qtype.getCode()==QType::NS && qname.empty())) {
64 if(doCNAMECacheCheck(qname,qtype,ret,depth,res)) // will reroute us if needed
65 return res;
66
67 if(doCacheCheck(qname,qtype,ret,depth,res)) // we done
68 return res;
69 }
afbe2787 70
c836dc19
BH
71 if(d_cacheonly)
72 return 0;
afbe2787 73
c836dc19 74 LOG<<prefix<<qname<<": No cache hit for '"<<qname<<"|"<<qtype.getName()<<"', trying to find an appropriate NS record"<<endl;
728485ca
BH
75
76 string subdomain(qname);
77
78 set<string> nsset;
7bf26383
BH
79 subdomain=getBestNSNamesFromCache(subdomain,nsset,depth, beenthere); // pass beenthere to both occasions/
80 if(!(res=doResolveAt(nsset,subdomain,qname,qtype,ret,depth, beenthere)))
728485ca
BH
81 return 0;
82
c836dc19 83 LOG<<prefix<<qname<<": failed"<<endl;
20177d1d 84 return res<0 ? RCode::ServFail : res;
afbe2787
BH
85}
86
7b35aa49 87string SyncRes::getA(const string &qname, int depth, set<GetBestNSAnswer>& beenthere)
75b49099 88{
728485ca
BH
89 vector<DNSResourceRecord> res;
90 string ret;
75b49099 91
7bf26383 92 if(!doResolve(qname,QType(QType::A), res,depth+1,beenthere) && !res.empty())
728485ca 93 ret=res[res.size()-1].content; // last entry, in case of CNAME in between
75b49099 94
728485ca 95 return ret;
75b49099
BH
96}
97
7b35aa49 98void SyncRes::getBestNSFromCache(const string &qname, set<DNSResourceRecord>&bestns, int depth, set<GetBestNSAnswer>& beenthere)
86c152f2 99{
c836dc19
BH
100 string prefix(d_prefix), subdomain(qname);
101 prefix.append(depth, ' ');
75b49099
BH
102 bestns.clear();
103
75b49099 104 do {
c836dc19 105 LOG<<prefix<<qname<<": Checking if we have NS in cache for '"<<subdomain<<"'"<<endl;
7bf26383
BH
106 set<DNSResourceRecord>ns;
107 if(getCache(subdomain,QType(QType::NS),&ns)>0) {
108 for(set<DNSResourceRecord>::const_iterator k=ns.begin();k!=ns.end();++k) {
109 if(k->ttl>(unsigned int)time(0)) {
110 set<DNSResourceRecord>aset;
111 if(!endsOn(k->content,subdomain) || getCache(k->content,QType(QType::A),&aset) > 5) {
20177d1d 112 bestns.insert(*k);
c836dc19
BH
113 LOG<<prefix<<qname<<": NS (with ip, or non-glue) in cache for '"<<subdomain<<"' -> '"<<k->content<<"'"<<endl;
114 LOG<<prefix<<qname<<": endson: "<<endsOn(k->content,subdomain);
7bf26383 115 if(!aset.empty())
c836dc19 116 LOG<<", in cache, ttl="<<((time_t)aset.begin()->ttl-time(0))<<endl;
0d8612f2 117 else
c836dc19 118 LOG<<", not in cache"<<endl;
0d8612f2 119 }
20177d1d 120 else
c836dc19 121 LOG<<prefix<<qname<<": NS in cache for '"<<subdomain<<"', but needs glue ("<<k->content<<") which we miss or is expired"<<endl;
ac539791 122 }
afbe2787 123 }
75b49099 124 if(!bestns.empty()) {
7bf26383
BH
125 GetBestNSAnswer answer;
126 answer.qname=toLower(qname); answer.bestns=bestns;
127 if(beenthere.count(answer)) {
c836dc19 128 LOG<<prefix<<qname<<": We have NS in cache for '"<<subdomain<<"' but part of LOOP! Trying less specific NS"<<endl;
7b35aa49 129 for( set<GetBestNSAnswer>::const_iterator j=beenthere.begin();j!=beenthere.end();++j)
c836dc19 130 LOG<<prefix<<qname<<": beenthere: "<<j->qname<<" ("<<j->bestns.size()<<")"<<endl;
7bf26383
BH
131 bestns.clear();
132 }
133 else {
134 beenthere.insert(answer);
c836dc19 135 LOG<<prefix<<qname<<": We have NS in cache for '"<<subdomain<<"'"<<endl;
7bf26383
BH
136 return;
137 }
75b49099 138 }
afbe2787 139 }
75b49099
BH
140 }while(chopOff(subdomain));
141}
142
288f4aa9 143
7bf26383 144/** doesn't actually do the work, leaves that to getBestNSFromCache */
7b35aa49 145string SyncRes::getBestNSNamesFromCache(const string &qname,set<string>& nsset, int depth, set<GetBestNSAnswer>&beenthere)
75b49099
BH
146{
147 string subdomain(qname);
148
149 set<DNSResourceRecord> bestns;
7bf26383 150 getBestNSFromCache(subdomain, bestns, depth, beenthere);
75b49099
BH
151
152 for(set<DNSResourceRecord>::const_iterator k=bestns.begin();k!=bestns.end();++k) {
153 nsset.insert(k->content);
154 subdomain=k->qname;
86c152f2 155 }
75b49099 156 return subdomain;
afbe2787
BH
157}
158
7b35aa49 159bool SyncRes::doCNAMECacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res)
afbe2787 160{
c836dc19
BH
161 string prefix(d_prefix), tuple=toLower(qname)+"|CNAME";
162 prefix.append(depth, ' ');
36f5e3db 163
c6644fc5 164 if(depth>10) {
c836dc19 165 LOG<<prefix<<qname<<": CNAME loop too deep, depth="<<depth<<endl;
c6644fc5
BH
166 res=RCode::ServFail;
167 return true;
168 }
36f5e3db 169
c836dc19 170 LOG<<prefix<<qname<<": Looking for CNAME cache hit of '"<<tuple<<"'"<<endl;
7bf26383
BH
171 set<DNSResourceRecord> cset;
172 if(getCache(qname,QType(QType::CNAME),&cset) > 0) {
173 for(set<DNSResourceRecord>::const_iterator j=cset.begin();j!=cset.end();++j) {
75b49099 174 if(j->ttl>(unsigned int)time(0)) {
c836dc19 175 LOG<<prefix<<qname<<": Found cache CNAME hit for '"<<tuple<<"' to '"<<j->content<<"'"<<endl;
ac539791
BH
176 DNSResourceRecord rr=*j;
177 rr.ttl-=time(0);
178 ret.push_back(rr);
7bf26383
BH
179 if(!(qtype==QType(QType::CNAME))) {// perhaps they really wanted a CNAME!
180 set<GetBestNSAnswer>beenthere;
c1663439 181 res=doResolve(j->content, qtype, ret, depth+1, beenthere);
7bf26383 182 }
75b49099 183 return true;
ac539791
BH
184 }
185 }
afbe2787 186 }
c836dc19 187 LOG<<prefix<<qname<<": No CNAME cache hit of '"<<tuple<<"' found"<<endl;
75b49099
BH
188 return false;
189}
190
7b35aa49 191bool SyncRes::doCacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res)
75b49099 192{
c836dc19
BH
193 string prefix(d_prefix), tuple;
194 prefix.append(depth, ' ');
afbe2787
BH
195
196 tuple=toLower(qname)+"|"+qtype.getName();
c836dc19 197 LOG<<prefix<<qname<<": Looking for direct cache hit of '"<<tuple<<"', "<<s_negcache.count(tuple)<<endl;
288f4aa9
BH
198
199 string sqname(qname);
200 QType sqt(qtype);
afbe2787 201
20177d1d 202 res=0;
288f4aa9
BH
203 map<string,string>::const_iterator ni=s_negcache.find(tuple);
204 if(ni!=s_negcache.end()) {
c836dc19 205 LOG<<prefix<<qname<<": "<<qtype.getName()<<" is negatively cached, will return immediately if we still have SOA ("<<ni->second<<") to prove it"<<endl;
20177d1d 206 res=RCode::NXDomain;
288f4aa9
BH
207 sqname=ni->second;
208 sqt="SOA";
20177d1d
BH
209 }
210
7bf26383 211 set<DNSResourceRecord> cset;
75b49099 212 bool found=false, expired=false;
288f4aa9 213 if(getCache(sqname,sqt,&cset)>0) {
c836dc19 214 LOG<<prefix<<qname<<": Found cache hit for "<<sqt.getName()<<": ";
7bf26383 215 for(set<DNSResourceRecord>::const_iterator j=cset.begin();j!=cset.end();++j) {
c836dc19 216 LOG<<j->content;
75b49099 217 if(j->ttl>(unsigned int)time(0)) {
ac539791
BH
218 DNSResourceRecord rr=*j;
219 rr.ttl-=time(0);
20177d1d
BH
220 if(res==RCode::NXDomain)
221 rr.d_place=DNSResourceRecord::AUTHORITY;
ac539791 222 ret.push_back(rr);
c836dc19 223 LOG<<"[ttl="<<rr.ttl<<"] ";
75b49099 224 found=true;
ac539791 225 }
75b49099 226 else {
c836dc19 227 LOG<<"[expired] ";
75b49099
BH
228 expired=true;
229 }
afbe2787 230 }
ac539791 231
c836dc19 232 LOG<<endl;
20177d1d 233 if(found && !expired)
75b49099 234 return true;
75b49099 235 else
c836dc19 236 LOG<<prefix<<qname<<": cache had only stale entries"<<endl;
afbe2787 237 }
75b49099
BH
238 return false;
239}
afbe2787 240
7b35aa49 241bool SyncRes::moreSpecificThan(const string& a, const string &b)
75b49099 242{
728485ca 243 int counta=!a.empty(), countb=!b.empty();
afbe2787 244
728485ca
BH
245 for(string::size_type n=0;n<a.size();++n)
246 if(a[n]=='.')
247 counta++;
248 for(string::size_type n=0;n<b.size();++n)
249 if(b[n]=='.')
250 countb++;
251 return counta>countb;
afbe2787
BH
252}
253
7b35aa49 254vector<string> SyncRes::shuffle(set<string> &nameservers)
afbe2787 255{
728485ca
BH
256 vector<string> rnameservers;
257 for(set<string>::const_iterator i=nameservers.begin();i!=nameservers.end();++i)
258 rnameservers.push_back(*i);
259
260 random_shuffle(rnameservers.begin(),rnameservers.end());
261 return rnameservers;
afbe2787
BH
262}
263
ac539791 264/** returns -1 in case of no results, rcode otherwise */
7b35aa49 265int SyncRes::doResolveAt(set<string> nameservers, string auth, const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret,
7bf26383 266 int depth, set<GetBestNSAnswer>&beenthere)
86c152f2 267{
c836dc19
BH
268 string prefix(d_prefix);
269 prefix.append(depth, ' ');
86c152f2 270
86c152f2 271 LWRes::res_t result;
86c152f2 272
c836dc19 273 LOG<<prefix<<qname<<": Cache consultations done, have "<<nameservers.size()<<" NS to contact"<<endl;
afbe2787
BH
274
275 for(;;) { // we may get more specific nameservers
75b49099 276 bool aabit=false;
86c152f2
BH
277 result.clear();
278
728485ca 279 vector<string>rnameservers=shuffle(nameservers);
86c152f2 280
20177d1d
BH
281 // what if we don't have an A for an NS anymore, but do have an NS for that NS?
282
728485ca
BH
283 for(vector<string>::const_iterator tns=rnameservers.begin();;++tns) {
284 if(tns==rnameservers.end()) {
c836dc19 285 LOG<<prefix<<qname<<": Failed to resolve via any of the "<<rnameservers.size()<<" offered NS"<<endl;
ac539791 286 return -1;
afbe2787 287 }
288f4aa9 288 if(qname==*tns && qtype.getCode()==QType::A) {
c836dc19 289 LOG<<prefix<<qname<<": Not using NS to resolve itself!"<<endl;
20177d1d
BH
290 continue;
291 }
c836dc19 292 LOG<<prefix<<qname<<": Trying to resolve NS "<<*tns<<" ("<<1+tns-rnameservers.begin()<<"/"<<rnameservers.size()<<")"<<endl;
7bf26383 293 string remoteIP=getA(*tns, depth+1,beenthere);
afbe2787 294 if(remoteIP.empty()) {
c836dc19 295 LOG<<prefix<<qname<<": Failed to get IP for NS "<<*tns<<", trying next if available"<<endl;
afbe2787
BH
296 continue;
297 }
c836dc19 298 LOG<<prefix<<qname<<": Resolved NS "<<*tns<<" to "<<remoteIP<<", asking '"<<qname<<"|"<<qtype.getName()<<"'"<<endl;
86c152f2 299
3de83124
BH
300 if(s_throttle.shouldThrottle(remoteIP+"|"+qname+"|"+qtype.getName())) {
301 LOG<<prefix<<qname<<": query throttled "<<endl;
302 s_throttledqueries++;
303 d_throttledqueries++;
728485ca 304 continue;
afbe2787 305 }
3de83124
BH
306 else {
307 s_outqueries++;
308 d_outqueries++;
309 if(d_lwr.asyncresolve(remoteIP,qname.c_str(),qtype.getCode())!=1) { // <- we go out on the wire!
310 LOG<<prefix<<qname<<": error resolving (perhaps timeout?)"<<endl;
c4bee46c 311 s_throttle.throttle(remoteIP+"|"+qname+"|"+qtype.getName(),20,5);
3de83124
BH
312 continue;
313 }
314 }
20177d1d 315
36f5e3db 316 result=d_lwr.result(aabit);
288f4aa9 317 if(d_lwr.d_rcode==RCode::ServFail) {
c836dc19 318 LOG<<prefix<<qname<<": "<<*tns<<" returned a ServFail, trying sibling NS"<<endl;
3de83124 319 s_throttle.throttle(remoteIP+"|"+qname+"|"+qtype.getName(),60,3);
20177d1d
BH
320 continue;
321 }
c836dc19 322 LOG<<prefix<<qname<<": Got "<<result.size()<<" answers from "<<*tns<<" ("<<remoteIP<<"), rcode="<<d_lwr.d_rcode<<endl;
20177d1d 323
288f4aa9 324 map<string,set<DNSResourceRecord> > tcache;
728485ca
BH
325 // reap all answers from this packet that are acceptable
326 for(LWRes::res_t::const_iterator i=result.begin();i!=result.end();++i) {
c836dc19
BH
327 LOG<<prefix<<qname<<": accept answer '"<<i->qname<<"|"<<i->qtype.getName()<<"|"<<i->content<<"' from '"<<auth<<"' nameservers? ";
328
728485ca 329 if(endsOn(i->qname, auth)) {
c836dc19 330 LOG<<"YES!"<<endl;
728485ca
BH
331
332 DNSResourceRecord rr=*i;
333 rr.d_place=DNSResourceRecord::ANSWER;
334 rr.ttl+=time(0);
7bf26383 335 // rr.ttl=time(0)+10+10*rr.qtype.getCode();
728485ca
BH
336 tcache[toLower(i->qname)+"|"+i->qtype.getName()].insert(rr);
337 }
338 else
c836dc19 339 LOG<<"NO!"<<endl;
86c152f2 340 }
728485ca
BH
341
342 // supplant
288f4aa9
BH
343 for(map<string,set<DNSResourceRecord> >::const_iterator i=tcache.begin();i!=tcache.end();++i) {
344 vector<string>parts;
345 stringtok(parts,i->first,"|");
346 QType qt;
347 if(parts.size()==2) {
348 qt=parts[1];
349 replaceCache(parts[0],qt,i->second);
350 }
351 else {
352 qt=parts[0];
353 replaceCache("",qt,i->second);
354 }
355 }
728485ca 356 set<string> nsset;
c836dc19 357 LOG<<prefix<<qname<<": determining status after receiving this packet"<<endl;
728485ca 358
20177d1d 359 bool done=false, realreferral=false, negindic=false;
c6644fc5 360 string newauth, soaname, newtarget;
728485ca
BH
361
362 for(LWRes::res_t::const_iterator i=result.begin();i!=result.end();++i) {
363 if(i->d_place==DNSResourceRecord::AUTHORITY && endsOn(qname,i->qname) && i->qtype.getCode()==QType::SOA) {
c836dc19 364 LOG<<prefix<<qname<<": got negative caching indication for '"<<toLower(qname)+"|"+qtype.getName()<<"'"<<endl;
728485ca 365 ret.push_back(*i);
288f4aa9 366 s_negcache[toLower(qname)+"|"+qtype.getName()]=i->qname;
20177d1d 367 negindic=true;
728485ca
BH
368 }
369 else if(i->d_place==DNSResourceRecord::ANSWER && i->qname==qname && i->qtype.getCode()==QType::CNAME && (!(qtype==QType(QType::CNAME)))) {
728485ca 370 ret.push_back(*i);
c6644fc5 371 newtarget=i->content;
728485ca
BH
372 }
373 // for ANY answers we *must* have an authoritive answer
7b35aa49 374 else if(i->d_place==DNSResourceRecord::ANSWER && toLower(i->qname)==toLower(qname) && (i->qtype==qtype || ( qtype==QType(QType::ANY) && aabit))) {
c836dc19 375 LOG<<prefix<<qname<<": answer is in: resolved to '"<<i->content<<"|"<<i->qtype.getName()<<"'"<<endl;
728485ca
BH
376 done=true;
377 ret.push_back(*i);
378 }
379 else if(i->d_place==DNSResourceRecord::AUTHORITY && endsOn(qname,i->qname) && i->qtype.getCode()==QType::NS) {
380 if(moreSpecificThan(i->qname,auth)) {
381 newauth=i->qname;
c836dc19 382 LOG<<prefix<<qname<<": got NS record '"<<i->qname<<"' -> '"<<i->content<<"'"<<endl;
728485ca
BH
383 realreferral=true;
384 }
7bf26383 385 else
c836dc19 386 LOG<<prefix<<qname<<": got upwards/level NS record '"<<i->qname<<"' -> '"<<i->content<<"', had '"<<auth<<"'"<<endl;
728485ca
BH
387 nsset.insert(toLower(i->content));
388 }
86c152f2 389 }
86c152f2 390
728485ca 391 if(done){
c836dc19 392 LOG<<prefix<<qname<<": status=got results, this level of recursion done"<<endl;
728485ca 393 return 0;
ac539791 394 }
288f4aa9 395 if(d_lwr.d_rcode==RCode::NXDomain) {
c836dc19 396 LOG<<prefix<<qname<<": status=NXDOMAIN, we are done "<<(negindic ? "(have negative SOA)" : "")<<endl;
728485ca 397 return RCode::NXDomain;
86c152f2 398 }
c6644fc5 399 if(!newtarget.empty()) {
c836dc19 400 LOG<<prefix<<qname<<": status=got a CNAME referral, starting over with "<<newtarget<<endl;
c6644fc5
BH
401 set<GetBestNSAnswer>beenthere2;
402 return doResolve(newtarget, qtype, ret,0,beenthere2);
403 }
caa6eefa
BH
404 if(nsset.empty() && !d_lwr.d_rcode) {
405 LOG<<prefix<<qname<<": status=noerror, other types may exist, but we are done "<<(negindic ? "(have negative SOA)" : "")<<endl;
406 return 0;
407 }
728485ca 408 else if(realreferral) {
c836dc19 409 LOG<<prefix<<qname<<": status=did not resolve, got "<<nsset.size()<<" NS, looping to them"<<endl;
728485ca
BH
410 auth=newauth;
411 nameservers=nsset;
412 break;
413 }
414 else {
c836dc19 415 LOG<<prefix<<qname<<": status=NS "<<*tns<<" is lame for '"<<auth<<"', trying sibling NS"<<endl;
3de83124 416 s_throttle.throttle(remoteIP+"|"+qname+"|"+qtype.getName(),60,0);
86c152f2
BH
417 }
418 }
86c152f2 419 }
ac539791 420 return -1;
86c152f2
BH
421}
422
7b35aa49 423void SyncRes::addCruft(const string &qname, vector<DNSResourceRecord>& ret)
728485ca
BH
424{
425 for(vector<DNSResourceRecord>::const_iterator k=ret.begin();k!=ret.end();++k) // don't add stuff to an NXDOMAIN!
426 if(k->d_place==DNSResourceRecord::AUTHORITY && k->qtype==QType(QType::SOA))
427 return;
428
c836dc19 429 // LOG<<qname<<": Adding best authority records from cache"<<endl;
288f4aa9 430 // addAuthorityRecords(qname,ret,0);
c836dc19 431 // LOG<<qname<<": Done adding best authority records."<<endl;
728485ca 432
c836dc19 433 LOG<<d_prefix<<qname<<": Starting additional processing"<<endl;
728485ca
BH
434 vector<DNSResourceRecord> addit;
435 for(vector<DNSResourceRecord>::const_iterator k=ret.begin();k!=ret.end();++k)
436 if((k->d_place==DNSResourceRecord::ANSWER && k->qtype==QType(QType::MX)) ||
288f4aa9 437 ((k->d_place==DNSResourceRecord::AUTHORITY || k->d_place==DNSResourceRecord::ANSWER) && k->qtype==QType(QType::NS))) {
c836dc19 438 LOG<<qname<<": record '"<<k->content<<"|"<<k->qtype.getName()<<"' needs an IP address"<<endl;
7bf26383
BH
439 set<GetBestNSAnswer>beenthere;
440 doResolve(k->content,QType(QType::A),addit,1,beenthere);
b636533b
BH
441 if(arg().mustDo("aaaa-additional-processing"))
442 doResolve(k->content,QType(QType::AAAA),addit,1,beenthere);
728485ca
BH
443 }
444
445 for(vector<DNSResourceRecord>::iterator k=addit.begin();k!=addit.end();++k) {
288f4aa9
BH
446 if(k->qtype.getCode()==QType::A || k->qtype.getCode()==QType::AAAA) {
447 k->d_place=DNSResourceRecord::ADDITIONAL;
448 ret.push_back(*k);
449 }
728485ca 450 }
c836dc19 451 LOG<<d_prefix<<qname<<": Done with additional processing"<<endl;
728485ca
BH
452}
453
7b35aa49 454void SyncRes::addAuthorityRecords(const string& qname, vector<DNSResourceRecord>& ret, int depth)
86c152f2 455{
288f4aa9
BH
456 set<DNSResourceRecord> bestns;
457 set<GetBestNSAnswer>beenthere;
458 getBestNSFromCache(qname, bestns, depth,beenthere);
459 for(set<DNSResourceRecord>::const_iterator k=bestns.begin();k!=bestns.end();++k) {
460 DNSResourceRecord ns=*k;
461 ns.d_place=DNSResourceRecord::AUTHORITY;
462 ns.ttl-=time(0);
463 ret.push_back(ns);
86c152f2
BH
464 }
465}