continue;
sr=d_suckdomains.front();
- d_suckdomains.pop_front();
}
try {
suck(sr.domain,sr.master);
catch(AhuException& ae) {
cerr<<"Error: "<<ae.reason<<endl;
}
+
+ {
+ Lock l(&d_lock);
+ domains_by_name_t& uqIndex = d_suckdomains.get<IDTag>();
+ uqIndex.erase(sr);
+ }
}
+
}
void CommunicatorClass::go()
{
pthread_t tid;
- pthread_create(&tid,0,&launchhelper,this);
+ pthread_create(&tid,0,&launchhelper,this); // Starts CommunicatorClass::mainloop()
for(int n=0; n < ::arg().asNum("retrieval-threads"); ++n)
- pthread_create(&tid, 0, &retrieveLaunchhelper, this);
+ pthread_create(&tid, 0, &retrieveLaunchhelper, this); // Starts CommunicatorClass::retrievalLoopThread()
}
ordered_unique<tag<IDTag>, identity<SuckRequest> >
>
> UniQueue;
+typedef UniQueue::index<IDTag>::type domains_by_name_t;
class NotificationQueue
{
bool removeIf(const string &remote, uint16_t id, const string &domain)
{
- for(d_nqueue_t::iterator i=d_nqueue.begin();i!=d_nqueue.end();++i) {
+ for(d_nqueue_t::iterator i=d_nqueue.begin(); i!=d_nqueue.end(); ++i) {
// cout<<i->id<<" "<<id<<endl;
//cout<<i->ip<<" "<<remote<<endl;
//cout<<i->domain<<" "<<domain<<endl;
string remoteIP, ourIP, port;
- tie(remoteIP, port)=splitField(remote,':');
- tie(ourIP, port)=splitField(i->ip,':');
+ tie(remoteIP, port)=splitField(remote, ':');
+ tie(ourIP, port)=splitField(i->ip, ':');
if(i->id==id && ourIP == remoteIP && i->domain==domain) {
d_nqueue.erase(i);
return true;
time_t next;
};
- typedef std::list<NotificationRequest>d_nqueue_t;
+ typedef std::list<NotificationRequest> d_nqueue_t;
d_nqueue_t d_nqueue;
};
void drillHole(const string &domain, const string &ip);
bool justNotified(const string &domain, const string &ip);
- void addSuckRequest(const string &domain, const string &master, bool priority=false);
+ void addSuckRequest(const string &domain, const string &master);
void addSlaveCheckRequest(const DomainInfo& di, const ComboAddress& remote);
void addTrySuperMasterRequest(DNSPacket *p);
void notify(const string &domain, const string &ip);
void mainloop();
void retrievalLoopThread();
+ void sendNotification(int sock, const string &domain, const ComboAddress& remote, uint16_t id);
+
static void *launchhelper(void *p)
{
static_cast<CommunicatorClass *>(p)->mainloop();
ComboAddress from;
Utility::socklen_t fromlen=sizeof(from);
char buffer[1500];
- int size;
- // receive incoming notifications on the nonblocking socket and take them off the list
- int sock;
+ int size, sock;
+ // receive incoming notifications on the nonblocking socket and take them off the list
while(waitFor2Data(d_nsock4, d_nsock6, 0, 0, &sock) > 0) {
size=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr *)&from,&fromlen);
if(size < 0)
return d_nq.earliest();
}
+void CommunicatorClass::sendNotification(int sock, const string& domain, const ComboAddress& remote, uint16_t id)
+{
+ vector<uint8_t> packet;
+ DNSPacketWriter pw(packet, domain, QType::SOA, 1, Opcode::Notify);
+ pw.getHeader()->id = id;
+ pw.getHeader()->aa = true;
+
+ if(sendto(sock, &packet[0], packet.size(), 0, (struct sockaddr*)(&remote), remote.getSocklen()) < 0) {
+ throw ResolverException("Unable to send notify to "+remote.toStringWithPort()+": "+stringerror());
+ }
+}
+
void CommunicatorClass::drillHole(const string &domain, const string &ip)
{
Lock l(&d_holelock);
return ret;
}
-// returns -1 in case if error, 0 if no data is available, 1 if there is. In the first two cases, errno is set
+// returns -1 in case of error, 0 if no data is available, 1 if there is. In the first two cases, errno is set
int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int*fd)
{
int ret;
#include "namespaces.hh"
-int sendNotification(int sock, const string& domain, const ComboAddress& remote, uint16_t id)
-{
- vector<uint8_t> packet;
- DNSPacketWriter pw(packet, domain, QType::SOA, 1, Opcode::Notify);
- pw.getHeader()->id = id;
- pw.getHeader()->aa = true;
-
- if(sendto(sock, &packet[0], packet.size(), 0, (struct sockaddr*)(&remote), remote.getSocklen())<0) {
- throw ResolverException("Unable to send notify to "+remote.toStringWithPort()+": "+stringerror());
- }
- return true;
-}
-
int makeQuerySocket(const ComboAddress& local, bool udpOrTCP)
{
ComboAddress ourLocal(local);
ResolverException(const string &reason) : AhuException(reason){}
};
-// send out an update notification for a domain to an IPv4/v6 address
-int sendNotification(int sock, const string &domain, const ComboAddress& remote, uint16_t id);
-
// make an IPv4 or IPv6 query socket
int makeQuerySocket(const ComboAddress& local, bool udpOrTCP);
//! Resolver class. Can be used synchronously and asynchronously, over IPv4 and over IPv6 (simultaneously)
return ((signed)(a - b)) < 0;
}
-void CommunicatorClass::addSuckRequest(const string &domain, const string &master, bool priority)
+void CommunicatorClass::addSuckRequest(const string &domain, const string &master)
{
Lock l(&d_lock);
-
SuckRequest sr;
sr.domain = domain;
sr.master = master;
pair<UniQueue::iterator, bool> res;
- if(priority) {
- res=d_suckdomains.push_front(sr);
- }
- else {
- res=d_suckdomains.push_back(sr);
- }
+
+ res=d_suckdomains.push_back(sr);
if(res.second) {
d_suck_sem.post();
{
UeberBackend *B=dynamic_cast<UeberBackend *>(P->getBackend());
vector<DomainInfo> rdomains;
- vector<DomainNotificationInfo > sdomains; // the bool is for 'presigned'
+ vector<DomainNotificationInfo> sdomains; // the bool is for 'presigned'
vector<DNSPacket> trysuperdomains;
{
DNSSECKeeper dk(B); // NOW HEAR THIS! This DK uses our B backend, so no interleaved access!
{
Lock l(&d_lock);
- typedef UniQueue::index<IDTag>::type domains_by_name_t;
domains_by_name_t& nameindex=boost::multi_index::get<IDTag>(d_suckdomains);
BOOST_FOREACH(DomainInfo& di, rdomains) {
continue;
// remove unfresh domains already queued for AXFR, no sense polling them again
sr.master=*di.masters.begin();
- if(nameindex.count(sr))
+ if(nameindex.count(sr)) {
+ L<<Logger::Warning<<"Domain "<<sr.domain<<" already queued for AXFR."<<endl;
continue;
+ }
DomainNotificationInfo dni;
dni.di=di;
dni.dnssecOk = dk.isPresigned(di.zone);