- can now understand incoming RP records in AXFR
- fixed potential crasher bug in shortened packet parsing
- now groks LOC records incoming/outgoing
+ - configparser now strips leading spaces in arguments
+ - improved chroot error reporting
+ - lots of bind backend work
Changes since 2.9.1:
- removed debugging output from the webserver (found by Paul Wouters)
+reset yacc/lex in bindparser
+
bugs:
pdns.conf-dist contains old descriptions
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "utility.hh"\r
+#include "utility.hh"
#include <fstream>
#include <iostream>
#include "logger.hh"
}
bool ArgvMap::mustDo(const string &var)
-{\r
+{
return ((*this)[var]!="no") && ((*this)[var]!="off");
}
}
if(var!="" && (parseOnly.empty() || var==parseOnly)) {
+
+ pos=val.find_first_not_of(" \t"); // strip leading whitespace
+ if(pos && pos!=string::npos)
+ val=val.substr(pos);
+
if(parmIsset(var))
params[var]=val;
else
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-// $Id: bindbackend.cc,v 1.3 2002/12/17 16:50:31 ahu Exp $
+// $Id: bindbackend.cc,v 1.4 2002/12/18 09:30:13 ahu Exp $
#include <errno.h>
#include <string>
#include <map>
#include "huffman.hh"
#include "qtype.hh"
#include "misc.hh"
-
+#include "dynlistener.hh"
using namespace std;
d_last_check=0;
d_checknow=false;
d_rwlock=new pthread_rwlock_t;
+ d_confcount=0;
//cout<<"Generated a new bbdomaininfo: "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
pthread_rwlock_init(d_rwlock,0);
}
sd.last_check=i->second.d_last_check;
sd.backend=this;
sd.kind=DomainInfo::Slave;
-
SOAData soadata;
soadata.serial=0;
soadata.refresh=0;
- getSOA(i->second.d_name,soadata);
- sd.serial=soadata.serial;
+ soadata.serial=0;
+ try {
+ getSOA(i->second.d_name,soadata); // we might not *have* a SOA yet
+ sd.serial=soadata.serial;
+ }
+ catch(...){}
if(sd.last_check+soadata.refresh<(unsigned int)time(0))
unfreshDomains->push_back(sd);
static string canonic(string ret)
{
string::iterator i;
+
for(i=ret.begin();
i!=ret.end();
++i)
- *i=tolower(*i);
+ *i=*i; //tolower(*i);
+
if(*(i-1)=='.')
ret.resize(i-ret.begin()-1);
static BindBackend *us;
static int domain_id;
+BindBackend *self;
+string BindBackend::DLReloadHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ for(map<u_int32_t,BBDomainInfo>::iterator i=self->d_bbds.begin();i!=self->d_bbds.end();++i)
+ i->second.d_checknow=true;
+ return "queued";
+}
static void callback(const string &domain, const string &qtype, const string &content, int ttl, int prio)
{
BindBackend::BindBackend(const string &suffix)
{
+ d_logprefix="[bind"+suffix+"backend]";
+ setArgPrefix("bind"+suffix);
if(!s_first)
return;
- d_logprefix="[bind"+suffix+"backend]";
- setArgPrefix("bind"+suffix);
-
s_first=0;
if(!mustDo("enable-huffman"))
s_hc.passthrough(true);
d_bbds[0].d_loaded=true;
}
+ loadConfig();
+
+
+ extern DynListener *dl;
+ self=this;
+ dl->registerFunc("BIND-RELOAD", &DLReloadHandler);
+}
+
+
+void BindBackend::rediscover()
+{
+ loadConfig();
+}
+
+void BindBackend::loadConfig()
+{
+ static int s_confcount;
if(!getArg("config").empty()) {
BindParser BP;
- BP.parse(getArg("config"));
+ try {
+ BP.parse(getArg("config"));
+ }
+ catch(AhuException &ae) {
+ L<<Logger::Error<<"Error parsing bind configuration: "<<ae.reason<<endl;
+ throw;
+ }
ZoneParser ZP;
L<<Logger::Warning<<d_logprefix<<" Parsing "<<domains.size()<<" domain(s), will report when done"<<endl;
int rejected=0;
+ int newdomains=0;
+ s_confcount++;
+
+ map<unsigned int, BBDomainInfo> nbbds;
+
for(vector<BindDomainInfo>::const_iterator i=domains.begin();
i!=domains.end();
++i)
bbd.d_name=i->name;
bbd.d_filename=i->filename;
bbd.d_master=i->master;
- bbd.d_id=domain_id;
+
bbd.setCtime();
bbd.setCheckInterval(getArgAsNum("check-interval"));
+
+ map<unsigned int, BBDomainInfo>::const_iterator j=d_bbds.begin();
+ for(;j!=d_bbds.end();++j)
+ if(j->second.d_name==bbd.d_name) {
+ bbd.d_id=j->second.d_id;
+ break;
+ }
+ if(j==d_bbds.end())
+ bbd.d_id=domain_id++;
- d_bbds[domain_id]=bbd;
+ nbbds[bbd.d_id]=bbd;
L<<Logger::Info<<d_logprefix<<" parsing '"<<i->name<<"' from file '"<<i->filename<<"'"<<endl;
- d_bbds[domain_id].d_loaded=false;
+ nbbds[bbd.d_id].d_loaded=false;
try {
ZP.parse(i->filename,i->name); // calls callback for us
- d_bbds[domain_id].d_loaded=true;
+ nbbds[bbd.d_id].d_loaded=true;
}
catch(AhuException &ae) {
L<<Logger::Warning<<d_logprefix<<" error parsing '"<<i->name<<"' from file '"<<i->filename<<"': "<<ae.reason<<endl;
rejected++;
}
- vector<vector<BBResourceRecord> *>&tmp=d_zone_id_map[domain_id]; // shrink trick
+ vector<vector<BBResourceRecord> *>&tmp=d_zone_id_map[bbd.d_id]; // shrink trick
vector<vector<BBResourceRecord> *>(tmp).swap(tmp);
-
- domain_id++;
}
- L<<Logger::Error<<d_logprefix<<" Done parsing domains, "<<rejected<<" were rejected"<<endl; // XXX add how many were rejected
- L<<Logger::Info<<d_logprefix<<" Number of hash buckets: "<<d_qnames.bucket_count()<<", number of entries: "<<d_qnames.size()<< endl;
- }
-}
-void BindBackend::rediscover()
-{
+ int remdomains=0;
+ vector<string> oldnames, newnames;
+ for(map<unsigned int, BBDomainInfo>::const_iterator j=d_bbds.begin();j!=d_bbds.end();++j)
+ oldnames.push_back(j->second.d_name);
+ for(map<unsigned int, BBDomainInfo>::const_iterator j=nbbds.begin();j!=nbbds.end();++j)
+ newnames.push_back(j->second.d_name);
+
+ d_bbds.swap(nbbds); // commit
+
+ L<<Logger::Error<<d_logprefix<<" Done parsing domains, "<<rejected<<" rejected, "<<newdomains<<" new, "<<remdomains<<" removed"<<endl; // XXX add how many were rejected
+ L<<Logger::Info<<d_logprefix<<" Number of hash buckets: "<<d_qnames.bucket_count()<<", number of entries: "<<d_qnames.size()<< endl;
+ }
}
void BindBackend::queueReload(BBDomainInfo *bbd)
if(!bbd.d_loaded) {
delete d_handle;
- throw AhuException("Temporarily unavailable due to a zone lock"); // fuck
+ throw AhuException("Zone temporarily not available (file missing, or master dead)"); // fuck
}
if(!bbd.current()) {
unsigned int d_id;
time_t d_last_check;
string d_master;
+ int d_confcount;
bool tryRLock()
{
handle *d_handle;
void queueReload(BBDomainInfo *bbd);
BBResourceRecord resourceMaker(int id, const string &qtype, const string &content, int ttl, int prio);
+ static string DLReloadHandler(const vector<string>&parts, Utility::pid_t ppid);
+ void loadConfig();
};
-/*
- PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002 PowerDNS.COM BV
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-/* A Bison parser, made from /home/ahu/programming/ahudns/backends/bind/bindparser.yy
+/* A Bison parser, made from /home/ahu/programming/pdns/pdns/backends/bind/bindparser.yy
by GNU bison 1.35. */
#define YYBISON 1 /* Identify Bison output. */
{
return 1;
}
+ void yyrestart(FILE *);
}
{
yydebug=0;
yyin=fopen(fname.c_str(),"r");
-
+ yyrestart(yyin);
if(!yyin)
throw AhuException("Unable to open '"+fname+"': "+strerror(errno));
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const short yyrline[] =
{
- 0, 107, 108, 112, 112, 112, 112, 115, 116, 120,
- 124, 131, 141, 143, 147, 148, 151, 154, 155, 159,
- 163, 164, 168, 168, 171, 178, 179, 183, 183, 183,
- 185, 189, 193, 194, 198, 198, 198, 198, 201, 204,
- 205, 209, 215, 223, 232, 239
+ 0, 108, 109, 113, 113, 113, 113, 116, 117, 121,
+ 125, 132, 142, 144, 148, 149, 152, 155, 156, 160,
+ 164, 165, 169, 169, 172, 179, 180, 184, 184, 184,
+ 186, 190, 194, 195, 199, 199, 199, 199, 202, 205,
+ 206, 210, 216, 224, 233, 240
};
#endif
switch (yyn) {
case 10:
-#line 126 "bindparser.yy"
+#line 127 "bindparser.yy"
{
s_di.name=yyvsp[-1];
parent->commit(s_di);
}
break;
case 11:
-#line 133 "bindparser.yy"
+#line 134 "bindparser.yy"
{
s_di.name=yyvsp[-2];
parent->commit(s_di);
}
break;
case 24:
-#line 172 "bindparser.yy"
+#line 173 "bindparser.yy"
{
parent->setDirectory(yyvsp[0]);
}
break;
case 41:
-#line 210 "bindparser.yy"
+#line 211 "bindparser.yy"
{
s_di.master=yyvsp[0];
}
break;
case 42:
-#line 217 "bindparser.yy"
+#line 218 "bindparser.yy"
{
// printf("Found a filename: '%s'\n",$2);
s_di.filename=yyvsp[0];
}
break;
case 43:
-#line 225 "bindparser.yy"
+#line 226 "bindparser.yy"
{
// printf("Found a filename: '%s'\n",$2);
// ztype=$2;
}
break;
case 44:
-#line 234 "bindparser.yy"
+#line 235 "bindparser.yy"
{
yyval=yyvsp[0];
}
#endif
return yyresult;
}
-#line 240 "bindparser.yy"
+#line 241 "bindparser.yy"
{
return 1;
}
+ void yyrestart(FILE *);
}
{
yydebug=0;
yyin=fopen(fname.c_str(),"r");
-
+ yyrestart(yyin);
if(!yyin)
throw AhuException("Unable to open '"+fname+"': "+strerror(errno));
#ifndef WIN32
if(!arg()["chroot"].empty()) {
if(chroot(arg()["chroot"].c_str())<0) {
- L<<Logger::Error<<"Unable to chroot: "<<strerror(errno)<<", exiting"<<endl;
+ L<<Logger::Error<<"Unable to chroot to '"+arg()["chroot"]+"': "<<strerror(errno)<<", exiting"<<endl;
exit(1);
}
else
vector<DomainInfo> cmdomains;
B->getUpdatedMasters(&cmdomains);
- if(cmdomains.empty())
- L<<Logger::Error<<"No master domains need notifications"<<endl;
- else
+ if(cmdomains.empty()) {
+ if(d_masterschanged)
+ L<<Logger::Error<<"No master domains need notifications"<<endl;
+ d_masterschanged=false;
+ }
+ else {
+ d_masterschanged=true;
L<<Logger::Error<<cmdomains.size()<<" domain"<<(cmdomains.size()>1 ? "s" : "")<<" for which we are master need"<<
(cmdomains.size()>1 ? "" : "s")<<
" notifications"<<endl;
+ }
// figure out A records of everybody needing notification
// do this via the FindNS class, d_fns
if(sdomains.empty())
{
- L<<Logger::Error<<"All slave domains are fresh"<<endl;
+ if(d_slaveschanged)
+ L<<Logger::Error<<"All slave domains are fresh"<<endl;
+ d_slaveschanged=false;
return;
}
- else
+ else
L<<Logger::Error<<sdomains.size()<<" slave domain"<<(sdomains.size()>1 ? "s" : "")<<" need"<<
(sdomains.size()>1 ? "" : "s")<<
" checking"<<endl;
for(vector<DomainInfo>::const_iterator i=sdomains.begin();i!=sdomains.end();++i) {
+ d_slaveschanged=true;
u_int32_t theirserial=0;
try {
Resolver resolver;
// sem_init(&d_suck_sem,0,0);
// sem_init(&d_any_sem,0,0);
d_tickinterval=60;
+ d_masterschanged=d_slaveschanged=true;
}
int doNotifications();
void go()
Semaphore d_any_sem;
int d_tickinterval;
NotificationQueue d_nq;
+ bool d_masterschanged, d_slaveschanged;
};
#endif
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-// $Id: dnspacket.hh,v 1.6 2002/12/17 16:50:30 ahu Exp $
+// $Id: dnspacket.hh,v 1.7 2002/12/18 09:30:13 ahu Exp $
#ifndef DNSPACKET_HH
#define DNSPACKET_HH
d_qlen=offset+4; // this points to the start of any answers
}
- if(15+offset>=stringbuffer.length()) {
+ if((unsigned int)(15+offset)>=stringbuffer.length()) {
L << Logger::Warning << "Ignoring packet: question too short from "
<< getRemote() << endl;
return -1;
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "utility.hh"\r
+#include "utility.hh"
#include "dynhandler.hh"
#include "statbag.hh"
#include "logger.hh"
#include "dns.hh"
#include "arguments.hh"
#include <signal.h>
-#include "misc.hh"\r
+#include "misc.hh"
#include "communicator.hh"
static bool s_pleasequit;
string DLRediscoverHandler(const vector<string>&parts, Utility::pid_t ppid)
{
PacketHandler P;
- P.getBackend()->rediscover();
- L<<Logger::Error<<"Rediscovery was requested"<<endl;
- return "Ok";
+ try {
+ L<<Logger::Error<<"Rediscovery was requested"<<endl;
+ P.getBackend()->rediscover();
+ return "Ok";
+ }
+ catch(AhuException &ae) {
+ return ae.reason;
+ }
+
}
string DLReloadHandler(const vector<string>&parts, Utility::pid_t ppid)