Permalink
Browse files

CHANGES BEHAVIOUR: before we launch, check if we can connect to the c…

…ontrolsocket 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.
  • Loading branch information...
1 parent 9130f9e commit 7db735cf5dbf7473afbf5bb3b0e65a99cb1a7600 @ahupowerdns ahupowerdns committed Jun 10, 2013
Showing with 30 additions and 5 deletions.
  1. +0 −2 pdns/common_startup.cc
  2. +28 −1 pdns/dynlistener.cc
  3. +1 −0 pdns/dynlistener.hh
  4. +1 −2 pdns/receiver.cc
@@ -31,8 +31,6 @@ UDPNameserver *N;
int avg_latency;
TCPNameserver *TN;
-
-
ArgvMap &arg()
{
return theArg;
View
@@ -83,8 +83,33 @@ void DynListener::createSocketAndBind(int family, struct sockaddr*local, size_t
}
}
+/* this does a simplistic check, if we can connect, we consider it live. If we can't connect because
+ of access denied, we must consider it dead, nothing we can do about it.
+*/
+bool DynListener::testLive(const string& fname)
+{
+ struct sockaddr_un addr;
+ int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if(fd < 0) { // we'll have bigger issues down the road
+ return false;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, fname.c_str(), fname.length());
+
+ int status = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
+ int err=errno;
+ close(fd);
+ return status==0;
+}
+
void DynListener::listenOnUnixDomain(const string& fname)
{
+ if(testLive(fname)) {
+ L<<Logger::Critical<<"Previous controlsocket '"<<fname<<"' is in use"<<endl;
+ exit(1);
+ }
int err=unlink(fname.c_str());
if(err < 0 && errno!=ENOENT) {
L<<Logger::Critical<<"Unable to remove (previous) controlsocket at '"<<fname<<"': "<<strerror(errno)<<endl;
@@ -219,8 +244,10 @@ string DynListener::getLine()
continue;
}
}
+ errno=0;
if(!fgets(&mesg[0], mesg.size(), fp.get())) {
- L<<Logger::Error<<"Unable to receive line from controlsocket ("<<d_client<<"): "<<strerror(errno)<<endl;
+ if(errno)
+ L<<Logger::Error<<"Unable to receive line from controlsocket ("<<d_client<<"): "<<strerror(errno)<<endl;
close(d_client);
continue;
}
View
@@ -84,5 +84,6 @@ private:
ComboAddress d_socketaddress;
static g_funkdb_t s_funcdb;
static g_funk_t* s_restfunc;
+ bool testLive(const string& fname);
};
#endif /* PDNS_DYNLISTENER */
View
@@ -1,6 +1,6 @@
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002 - 2011 PowerDNS.COM BV
+ Copyright (C) 2002 - 2013 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 version 2
@@ -585,7 +585,6 @@ int main(int argc, char **argv)
showProductVersion();
try {
-
mainthread();
}
catch(AhuException &AE) {

0 comments on commit 7db735c

Please sign in to comment.