#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include "packetcache.hh"
+#include "auth-caches.hh"
#include "utility.hh"
#include <errno.h>
#include "communicator.hh"
{
bool hasQueuedItem=false;
set<string> nsset, ips;
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
FindNS fns;
if (d_onlyNotify.size()) {
- B->lookup(QType(QType::NS),domain);
+ B->lookup(QType(QType::NS), di.zone);
while(B->get(rr))
- nsset.insert(rr.content);
+ nsset.insert(getRR<NSRecordContent>(rr.dr)->getNS().toString());
for(set<string>::const_iterator j=nsset.begin();j!=nsset.end();++j) {
- vector<string> nsips=fns.lookup(DNSName(*j), B);
+ vector<string> nsips=fns.lookup(DNSName(*j), B, di.zone);
if(nsips.empty())
- L<<Logger::Warning<<"Unable to queue notification of domain '"<<domain<<"': nameservers do not resolve!"<<endl;
+ g_log<<Logger::Warning<<"Unable to queue notification of domain '"<<di.zone<<"': nameservers do not resolve!"<<endl;
else
for(vector<string>::const_iterator k=nsips.begin();k!=nsips.end();++k) {
const ComboAddress caIp(*k, 53);
if(!d_preventSelfNotification || !AddressIsUs(caIp)) {
if(!d_onlyNotify.match(&caIp))
- L<<Logger::Info<<"Skipped notification of domain '"<<domain<<"' to "<<*j<<" because it does not match only-notify."<<endl;
+ g_log<<Logger::Info<<"Skipped notification of domain '"<<di.zone<<"' to "<<*j<<" because it does not match only-notify."<<endl;
else
ips.insert(caIp.toStringWithPort());
}
}
for(set<string>::const_iterator j=ips.begin();j!=ips.end();++j) {
- L<<Logger::Warning<<"Queued notification of domain '"<<domain<<"' to "<<*j<<endl;
- d_nq.add(domain,*j);
+ g_log<<Logger::Warning<<"Queued notification of domain '"<<di.zone<<"' to "<<*j<<endl;
+ d_nq.add(di.zone,*j);
hasQueuedItem=true;
}
}
for(set<string>::const_iterator j=alsoNotify.begin();j!=alsoNotify.end();++j) {
try {
const ComboAddress caIp(*j, 53);
- L<<Logger::Warning<<"Queued also-notification of domain '"<<di.zone<<"' to "<<caIp.toStringWithPort()<<endl;
+ g_log<<Logger::Warning<<"Queued also-notification of domain '"<<di.zone<<"' to "<<caIp.toStringWithPort()<<endl;
if (!ips.count(caIp.toStringWithPort())) {
ips.insert(caIp.toStringWithPort());
d_nq.add(di.zone, caIp.toStringWithPort());
hasQueuedItem=true;
}
catch(PDNSException &e) {
- L<<Logger::Warning<<"Unparseable IP in ALSO-NOTIFY metadata of domain '"<<di.zone<<"'. Warning: "<<e.reason<<endl;
+ g_log<<Logger::Warning<<"Unparseable IP in ALSO-NOTIFY metadata of domain '"<<di.zone<<"'. Warning: "<<e.reason<<endl;
}
}
if (!hasQueuedItem)
- L<<Logger::Warning<<"Request to queue notification for domain '"<<di.zone<<"' was processed, but no valid nameservers or ALSO-NOTIFYs found. Not notifying!"<<endl;
+ g_log<<Logger::Warning<<"Request to queue notification for domain '"<<di.zone<<"' was processed, but no valid nameservers or ALSO-NOTIFYs found. Not notifying!"<<endl;
}
DomainInfo di;
UeberBackend B;
if(!B.getDomainInfo(domain, di)) {
- L<<Logger::Error<<"No such domain '"<<domain<<"' in our database"<<endl;
+ g_log<<Logger::Error<<"No such domain '"<<domain<<"' in our database"<<endl;
return false;
}
queueNotifyDomain(di, &B);
if(cmdomains.empty()) {
if(d_masterschanged)
- L<<Logger::Warning<<"No master domains need notifications"<<endl;
+ g_log<<Logger::Warning<<"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"<<
+ g_log<<Logger::Error<<cmdomains.size()<<" domain"<<(cmdomains.size()>1 ? "s" : "")<<" for which we are master need"<<
(cmdomains.size()>1 ? "" : "s")<<
" notifications"<<endl;
}
// do this via the FindNS class, d_fns
for(auto& di : cmdomains) {
- extern PacketCache PC;
- PC.purgeExact(di.zone);
+ purgeAuthCachesExact(di.zone);
queueNotifyDomain(di, B);
di.backend->setNotified(di.id, di.serial);
}
char buffer[1500];
int sock;
ssize_t size;
+ set<int> fds = {d_nsock4, d_nsock6};
// receive incoming notifications on the nonblocking socket and take them off the list
- while(waitFor2Data(d_nsock4, d_nsock6, 0, 0, &sock) > 0) {
+ while(waitForMultiData(fds, 0, 0, &sock) > 0) {
fromlen=sizeof(from);
size=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr *)&from,&fromlen);
if(size < 0)
p.setRemote(&from);
if(p.parse(buffer,(size_t)size)<0) {
- L<<Logger::Warning<<"Unable to parse SOA notification answer from "<<p.getRemote()<<endl;
+ g_log<<Logger::Warning<<"Unable to parse SOA notification answer from "<<p.getRemote()<<endl;
continue;
}
if(p.d.rcode)
- L<<Logger::Warning<<"Received unsuccessful notification report for '"<<p.qdomain<<"' from "<<from.toStringWithPort()<<", error: "<<RCode::to_s(p.d.rcode)<<endl;
+ g_log<<Logger::Warning<<"Received unsuccessful notification report for '"<<p.qdomain<<"' from "<<from.toStringWithPort()<<", error: "<<RCode::to_s(p.d.rcode)<<endl;
if(d_nq.removeIf(from.toStringWithPort(), p.d.id, p.qdomain))
- L<<Logger::Warning<<"Removed from notification list: '"<<p.qdomain<<"' to "<<from.toStringWithPort()<<" "<< (p.d.rcode ? RCode::to_s(p.d.rcode) : "(was acknowledged)")<<endl;
+ g_log<<Logger::Warning<<"Removed from notification list: '"<<p.qdomain<<"' to "<<from.toStringWithPort()<<" "<< (p.d.rcode ? RCode::to_s(p.d.rcode) : "(was acknowledged)")<<endl;
else {
- L<<Logger::Warning<<"Received spurious notify answer for '"<<p.qdomain<<"' from "<< from.toStringWithPort()<<endl;
+ g_log<<Logger::Warning<<"Received spurious notify answer for '"<<p.qdomain<<"' from "<< from.toStringWithPort()<<endl;
//d_nq.dump();
}
}
try {
ComboAddress remote(ip, 53); // default to 53
if((d_nsock6 < 0 && remote.sin4.sin_family == AF_INET6) ||
- (d_nsock4 < 0 && remote.sin4.sin_family == AF_INET))
+ (d_nsock4 < 0 && remote.sin4.sin_family == AF_INET)) {
+ g_log<<Logger::Warning<<"Unable to notify "<<remote.toStringWithPort()<<" for domain '"<<domain<<"', address family is disabled. Is query-local-address"<<(remote.sin4.sin_family == AF_INET ? "" : "6")<<" unset?"<<endl;
+ d_nq.removeIf(remote.toStringWithPort(), id, domain); // Remove, we'll never be able to notify
continue; // don't try to notify what we can't!
+ }
if(d_preventSelfNotification && AddressIsUs(remote))
continue;
- sendNotification(remote.sin4.sin_family == AF_INET ? d_nsock4 : d_nsock6, domain, remote, id);
+ sendNotification(remote.sin4.sin_family == AF_INET ? d_nsock4 : d_nsock6, domain, remote, id);
drillHole(domain, ip);
}
catch(ResolverException &re) {
- L<<Logger::Error<<"Error trying to resolve '"<<ip<<"' for notifying '"<<domain<<"' to server: "<<re.reason<<endl;
+ g_log<<Logger::Error<<"Error trying to resolve '"<<ip<<"' for notifying '"<<domain<<"' to server: "<<re.reason<<endl;
}
}
else
- L<<Logger::Error<<"Notification for "<<domain<<" to "<<ip<<" failed after retries"<<endl;
+ g_log<<Logger::Error<<"Notification for "<<domain<<" to "<<ip<<" failed after retries"<<endl;
}
return d_nq.earliest();
string tsigsecret64;
string tsigsecret;
- if (B.getDomainMetadata(domain, "TSIG-ALLOW-AXFR", meta) && meta.size() > 0) {
+ if (::arg().mustDo("send-signed-notify") && B.getDomainMetadata(domain, "TSIG-ALLOW-AXFR", meta) && meta.size() > 0) {
tsigkeyname = DNSName(meta[0]);
}
pw.getHeader()->aa = true;
if (tsigkeyname.empty() == false) {
- B.getTSIGKey(tsigkeyname, &tsigalgorithm, &tsigsecret64);
+ if (!B.getTSIGKey(tsigkeyname, &tsigalgorithm, &tsigsecret64)) {
+ g_log<<Logger::Error<<"TSIG key '"<<tsigkeyname<<"' for domain '"<<domain<<"' not found"<<endl;
+ return;
+ }
TSIGRecordContent trc;
if (tsigalgorithm.toStringNoDot() == "hmac-md5")
trc.d_algoName = DNSName(tsigalgorithm.toStringNoDot() + ".sig-alg.reg.int.");
trc.d_fudge = 300;
trc.d_origID=ntohs(id);
trc.d_eRcode=0;
- B64Decode(tsigsecret64, tsigsecret);
+ if (B64Decode(tsigsecret64, tsigsecret) == -1) {
+ g_log<<Logger::Error<<"Unable to Base-64 decode TSIG key '"<<tsigkeyname<<"' for domain '"<<domain<<"'"<<endl;
+ return;
+ }
addTSIG(pw, trc, tsigkeyname, tsigsecret, "", false);
}
void CommunicatorClass::makeNotifySockets()
{
- d_nsock4 = makeQuerySocket(ComboAddress(::arg()["query-local-address"]), true, ::arg().mustDo("non-local-bind"));
- if(!::arg()["query-local-address6"].empty())
+ if(!::arg()["query-local-address"].empty()) {
+ d_nsock4 = makeQuerySocket(ComboAddress(::arg()["query-local-address"]), true, ::arg().mustDo("non-local-bind"));
+ } else {
+ d_nsock4 = -1;
+ }
+ if(!::arg()["query-local-address6"].empty()) {
d_nsock6 = makeQuerySocket(ComboAddress(::arg()["query-local-address6"]), true, ::arg().mustDo("non-local-bind"));
- else
+ } else {
d_nsock6 = -1;
+ }
}
void CommunicatorClass::notify(const DNSName &domain, const string &ip)