Skip to content

Commit d72166c

Browse files
ahupowerdnsPeter van Dijk
authored andcommitted
CHANGES BEHAVIOUR: before we launch, check if we can connect to the controlsocket we are about to obliterate. If it works, abort. Fixes #841 and changes standing behaviour. There might be circumstances where PowerDNS now refuses to start, where it previously would. However, starting and making our previous instance mute wasn't good.
1 parent 9130f9e commit d72166c

File tree

4 files changed

+30
-5
lines changed

4 files changed

+30
-5
lines changed

pdns/common_startup.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ UDPNameserver *N;
3131
int avg_latency;
3232
TCPNameserver *TN;
3333

34-
35-
3634
ArgvMap &arg()
3735
{
3836
return theArg;

pdns/dynlistener.cc

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,33 @@ void DynListener::createSocketAndBind(int family, struct sockaddr*local, size_t
8383
}
8484
}
8585

86+
/* this does a simplistic check, if we can connect, we consider it live. If we can't connect because
87+
of access denied, we must consider it dead, nothing we can do about it.
88+
*/
89+
bool DynListener::testLive(const string& fname)
90+
{
91+
struct sockaddr_un addr;
92+
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
93+
if(fd < 0) { // we'll have bigger issues down the road
94+
return false;
95+
}
96+
97+
memset(&addr, 0, sizeof(addr));
98+
addr.sun_family = AF_UNIX;
99+
strncpy(addr.sun_path, fname.c_str(), fname.length());
100+
101+
int status = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
102+
int err=errno;
103+
close(fd);
104+
return status==0;
105+
}
106+
86107
void DynListener::listenOnUnixDomain(const string& fname)
87108
{
109+
if(testLive(fname)) {
110+
L<<Logger::Critical<<"Previous controlsocket '"<<fname<<"' is in use"<<endl;
111+
exit(1);
112+
}
88113
int err=unlink(fname.c_str());
89114
if(err < 0 && errno!=ENOENT) {
90115
L<<Logger::Critical<<"Unable to remove (previous) controlsocket at '"<<fname<<"': "<<strerror(errno)<<endl;
@@ -219,8 +244,10 @@ string DynListener::getLine()
219244
continue;
220245
}
221246
}
247+
errno=0;
222248
if(!fgets(&mesg[0], mesg.size(), fp.get())) {
223-
L<<Logger::Error<<"Unable to receive line from controlsocket ("<<d_client<<"): "<<strerror(errno)<<endl;
249+
if(errno)
250+
L<<Logger::Error<<"Unable to receive line from controlsocket ("<<d_client<<"): "<<strerror(errno)<<endl;
224251
close(d_client);
225252
continue;
226253
}

pdns/dynlistener.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,6 @@ private:
8484
ComboAddress d_socketaddress;
8585
static g_funkdb_t s_funcdb;
8686
static g_funk_t* s_restfunc;
87+
bool testLive(const string& fname);
8788
};
8889
#endif /* PDNS_DYNLISTENER */

pdns/receiver.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
PowerDNS Versatile Database Driven Nameserver
3-
Copyright (C) 2002 - 2011 PowerDNS.COM BV
3+
Copyright (C) 2002 - 2013 PowerDNS.COM BV
44
55
This program is free software; you can redistribute it and/or modify
66
it under the terms of the GNU General Public License version 2
@@ -585,7 +585,6 @@ int main(int argc, char **argv)
585585
showProductVersion();
586586

587587
try {
588-
589588
mainthread();
590589
}
591590
catch(AhuException &AE) {

0 commit comments

Comments
 (0)