47
46
/** new scheme of things:
48
47
we have zone-id map
49
a zone-id has a vector of DNSResourceRecords */
48
a zone-id has a vector of DNSResourceRecords
49
on start of query, we find the best zone to answer from
51
52
map<string,int> Bind2Backend::s_name_id_map;
52
53
map<u_int32_t,BB2DomainInfo* > Bind2Backend::s_id_zone_map;
293
set<string> contents;
293
295
map<unsigned int, BB2DomainInfo*> nbbds;
294
296
/** This function adds a record to a domain with a certain id. */
295
297
void Bind2Backend::insert(int id, const string &qnameu, const string &qtype, const string &content, int ttl=300, int prio=25)
297
DNSResourceRecord rr;
299
rr.qname=canonic(qnameu);
304
nbbds[id]->d_records->push_back(rr);
302
BB2DomainInfo* bb2=nbbds[id];
304
vector<Bind2DNSRecord> &records=*bb2->d_records;
306
bdr.qname=toLower(canonic(qnameu));
307
if(bdr.qname==bb2->d_name)
309
else if(bdr.qname.length() > bb2->d_name.length())
310
bdr.qname.resize(bdr.qname.length() - (bb2->d_name.length() + 1));
312
throw AhuException("Trying to insert non-zone data, name='"+bdr.qname+"', zone='"+nbbds[id]->d_name+"'");
314
bdr.qname.swap(bdr.qname);
316
if(!records.empty() && bdr.qname==(records.end()-1)->qname)
317
bdr.qname=(records.end()-1)->qname;
319
bdr.qtype=QType(qtype.c_str()).getCode();
320
bdr.content=canonic(content); // I think this is wrong, the zoneparser should not come up with . terminated stuff XXX FIXME
321
set<string>::const_iterator i=contents.find(bdr.content);
322
if(i!=contents.end())
325
contents.insert(bdr.content);
330
records.push_back(bdr);
404
if(mustDo("example-zones")) {
405
insert(0,"www.example.com","A","1.2.3.4");
406
insert(0,"example.com","SOA","ns1.example.com hostmaster.example.com");
407
insert(0,"example.com","NS","ns1.example.com",86400);
408
insert(0,"example.com","NS","ns2.example.com",86400);
409
insert(0,"example.com","MX","mail.example.com",3600,25);
410
insert(0,"example.com","MX","mail1.example.com",3600,25);
411
insert(0,"mail.example.com","A","4.3.2.1");
412
insert(0,"mail1.example.com","A","5.4.3.2");
413
insert(0,"ns1.example.com","A","4.3.2.1");
414
insert(0,"ns2.example.com","A","5.4.3.2");
416
for(int i=0;i<1000;i++)
417
insert(0,"host-"+itoa(i)+".example.com","A","2.3.4.5");
419
s_id_zone_map[0]=new BB2DomainInfo;
420
BB2DomainInfo &bbd=*s_id_zone_map[0];
421
bbd.d_name="example.com";
424
s_id_zone_map[0]->d_loaded=true;
425
s_id_zone_map[0]->d_status="parsed into memory at "+nowTime();
431
430
extern DynListener *dl;
509
513
ZP.parse(i->filename,i->name,bbd->d_id); // calls callback for us
514
L<<Logger::Info<<d_logprefix<<" sorting '"<<i->name<<"'"<<endl;
515
sort(nbbds[bbd->d_id]->d_records->begin(), nbbds[bbd->d_id]->d_records->end());
510
516
nbbds[bbd->d_id]->setCtime();
511
517
nbbds[bbd->d_id]->d_loaded=true; // does this perform locking for us?
512
518
nbbds[bbd->d_id]->d_status="parsed into memory at "+nowTime();
519
// cout<<"Had "<<contents.size()<<" different content fields, "<<nbbds[bbd->d_id]->d_records->size()<<" records, capacity: "<<
520
// nbbds[bbd->d_id]->d_records->capacity()<<endl;
522
nbbds[bbd->d_id]->d_records->swap(*nbbds[bbd->d_id]->d_records);
515
525
catch(AhuException &ae) {
516
526
ostringstream msg;
634
bool operator<(const Bind2DNSRecord &a, const string &b)
639
bool operator<(const string &a, const Bind2DNSRecord &b)
625
645
void Bind2Backend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_p, int zoneId )
627
d_handle=new Bind2Backend::handle;
628
d_handle->d_records=new vector<DNSResourceRecord>; // WRONG
629
// cout<<"Lookup! for "<<qname<<endl;
647
d_handle.reset(); // =new Bind2Backend::handle;
649
string domain=toLower(qname);
651
if(arg().mustDo("query-logging"))
652
L<<"Lookup for '"<<qtype.getName()<<"' of '"<<domain<<"'"<<endl;
631
654
while(!s_name_id_map.count(domain) && chopOff(domain));
633
656
if(!s_name_id_map.count(domain)) {
634
// cout<<"no such domain: '"<<qname<<"'"<<endl;
635
d_handle->d_iter=d_handle->d_records->end(); // WRONG
636
d_handle->d_list=false;
657
d_handle.d_list=false;
640
661
unsigned int id=s_name_id_map[domain];
642
// cout<<"domain: '"<<domain<<"', id="<<id<<endl;
645
665
DLOG(L<<"Bind2Backend constructing handle for search for "<<qtype.getName()<<" for "<<
648
d_handle->qname=qname;
649
d_handle->parent=this;
650
d_handle->qtype=qtype;
651
string compressed=toLower(qname);
652
d_handle->d_records=s_id_zone_map[id]->d_records;
654
if(!d_handle->d_records->empty()) {
668
if(strcasecmp(qname.c_str(),domain.c_str()))
669
d_handle.qname=toLower(qname.substr(0,qname.size()-domain.length()-1)); // strip domain name
671
d_handle.parent=this;
672
d_handle.qtype=qtype;
673
d_handle.domain=domain;
674
d_handle.d_records=s_id_zone_map[id]->d_records; // give it a copy
676
if(!d_handle.d_records->empty()) {
655
677
BB2DomainInfo& bbd=*s_id_zone_map[id];
656
678
if(!bbd.d_loaded) {
658
throw DBException("Zone temporarily not available (file missing, or master dead)"); // fuck
680
throw DBException("Zone temporarily not available (file missing, or master dead)"); // fsck
661
683
if(!bbd.tryRLock()) {
662
684
L<<Logger::Warning<<"Can't get read lock on zone '"<<bbd.d_name<<"'"<<endl;
664
throw DBException("Temporarily unavailable due to a zone lock"); // fuck
686
throw DBException("Temporarily unavailable due to a zone lock"); // fsck
668
689
if(!bbd.current()) {
669
690
L<<Logger::Warning<<"Zone '"<<bbd.d_name<<"' ("<<bbd.d_filename<<") needs reloading"<<endl;
670
691
queueReload(&bbd);
672
d_handle->d_bbd=&bbd;
675
696
DLOG(L<<"Query with no results"<<endl);
677
d_handle->d_iter=d_handle->d_records->begin();
678
d_handle->d_list=false;
699
pair<vector<Bind2DNSRecord>::const_iterator, vector<Bind2DNSRecord>::const_iterator> range;
701
// cout<<"starting equal range for: '"<<d_handle.qname<<"'"<<endl;
702
range=equal_range(d_handle.d_records->begin(), d_handle.d_records->end(), d_handle.qname);
704
if(range.first==range.second) {
706
d_handle.d_list=false;
710
d_handle.d_iter=range.first;
711
d_handle.d_end_iter=range.second;
714
d_handle.d_list=false;
681
717
Bind2Backend::handle::handle()
687
724
bool Bind2Backend::get(DNSResourceRecord &r)
689
if(!d_handle->get(r)) {
726
if(!d_handle.d_records)
729
if(!d_handle.get(r)) {
732
if(arg().mustDo("query-logging"))
733
L<<"End of answers"<<endl;
737
if(arg().mustDo("query-logging"))
738
L<<"Returning: '"<<r.qtype.getName()<<"' of '"<<r.qname<<"', content: '"<<r.content<<"'"<<endl;
721
774
DLOG(L << "Bind2Backend get() returning a rr with a "<<QType(d_iter->qtype).getCode()<<endl);
723
r.qname=qname; // fill this in
776
r.qname=qname.empty() ? domain : (qname+"."+domain);
725
778
r.content=(d_iter)->content;
726
r.domain_id=(d_iter)->domain_id;
779
// r.domain_id=(d_iter)->domain_id;
727
780
r.qtype=(d_iter)->qtype;
728
781
r.ttl=(d_iter)->ttl;
729
r.priority=(d_iter)->priority;
782
// r.priority=(d_iter)->priority;
735
788
bool Bind2Backend::list(const string &target, int id)
737
// cout<<"List of id "<<id<<" requested"<<endl;
738
790
if(!s_id_zone_map.count(id))
741
d_handle=new Bind2Backend::handle;
793
d_handle.reset(); // new Bind2Backend::handle;
742
794
DLOG(L<<"Bind2Backend constructing handle for list of "<<id<<endl);
744
d_handle->d_qname_iter=s_id_zone_map[id]->d_records->begin();
745
d_handle->d_qname_end=s_id_zone_map[id]->d_records->end(); // iter now points to a vector of pointers to vector<BBResourceRecords>
747
d_handle->parent=this;
749
d_handle->d_list=true;
796
d_handle.d_qname_iter=s_id_zone_map[id]->d_records->begin();
797
d_handle.d_qname_end=s_id_zone_map[id]->d_records->end(); // iter now points to a vector of pointers to vector<BBResourceRecords>
799
d_handle.d_records=s_id_zone_map[id]->d_records; // give it a copy --- WHY??? XXX FIXME
801
d_handle.parent=this;
803
d_handle.d_list=true;