From: Pieter Lexis Date: Fri, 19 Jan 2018 12:00:44 +0000 (+0100) Subject: ixfrdist: safely exit, ensure sockets can be reused X-Git-Tag: dnsdist-1.3.0~111^2~16 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bf676f2f05e7c9310d6b3977267279e373b31123;p=pdns ixfrdist: safely exit, ensure sockets can be reused --- diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 83da30159..824e68a47 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -66,6 +66,12 @@ ComboAddress g_master; bool g_verbose = false; bool g_debug = false; +bool g_exiting = false; + +void handleSignal(int signum) { + g_exiting = true; +} + void usage(po::options_description &desc) { cerr << "Usage: ixfrdist [OPTION]... DOMAIN [DOMAIN]..."<d_st.refresh) { continue; } + string dir = g_workdir + "/" + domain.toString(); if (g_verbose) { cerr<<"[INFO] Attempting to retrieve SOA Serial update for '"< sr; try { auto newSerial = getSerialFromMaster(g_master, domain, sr); // TODO TSIG + lastCheck[domain] = now; if(g_soas.find(domain) != g_soas.end() && g_verbose) { cerr<<"[INFO] Got SOA Serial for "<d_st.serial; if (newSerial == g_soas[domain]->d_st.serial) { @@ -171,13 +181,12 @@ void* updateThread(void*) { } catch (runtime_error &e) { cerr<<"[WARNING] Could not save zone '"< guard(g_soas_mutex); g_soas[domain] = soa; } } /* for (const auto &domain : domains) */ - sleep(10); + sleep(1); } /* while (true) */ } /* updateThread */ @@ -644,6 +653,7 @@ int main(int argc, char** argv) { } } + set allSockets; for (const auto addr : listen_addresses) { // Create UDP socket int s = socket(addr.sin4.sin_family, SOCK_DGRAM, 0); @@ -654,6 +664,7 @@ int main(int argc, char** argv) { } setNonBlocking(s); + setReuseAddr(s); if (bind(s, (sockaddr*) &addr, addr.getSocklen()) < 0) { cerr<<"[ERROR] Unable to bind to "<(); @@ -697,6 +710,10 @@ int main(int argc, char** argv) { } // It all starts here + signal(SIGTERM, handleSignal); + signal(SIGINT, handleSignal); + signal(SIGSTOP, handleSignal); + // Init the things we need reportAllTypes(); @@ -713,5 +730,19 @@ int main(int argc, char** argv) { for(;;) { gettimeofday(&now, 0); g_fdm.run(&now); + if (g_exiting) { + cerr<<"Shutting down!"<(sizeof tmp))<0) + throw PDNSException(string("Setsockopt failed: ")+strerror(errno)); + return true; +} + bool isNonBlocking(int sock) { int flags=fcntl(sock,F_GETFL,0); diff --git a/pdns/misc.hh b/pdns/misc.hh index f9db931a7..00056ff1c 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -534,6 +534,7 @@ bool setBlocking( int sock ); //! Sets the socket into non-blocking mode. bool setNonBlocking( int sock ); bool setTCPNoDelay(int sock); +bool setReuseAddr(int sock); bool isNonBlocking(int sock); int closesocket(int fd); bool setCloseOnExec(int sock); diff --git a/pdns/sstuff.hh b/pdns/sstuff.hh index 707b1ad12..0eec38487 100644 --- a/pdns/sstuff.hh +++ b/pdns/sstuff.hh @@ -133,9 +133,11 @@ public: void setReuseAddr() { - int tmp = 1; - if (setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, static_cast(sizeof tmp))<0) - throw NetworkError(string("Setsockopt failed: ")+strerror(errno)); + try { + ::setReuseAddr(d_socket); + } catch (PDNSException &e) { + throw NetworkError(e.reason); + } } //! Bind the socket to a specified endpoint