From: Miod Vallat Date: Wed, 15 Jan 2025 14:43:13 +0000 (+0100) Subject: If the control console fd is closed, handle this as a "quit" command. X-Git-Tag: dnsdist-2.0.0-alpha1~166^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9441e6872181b91e00ab5b38c29a1d88b64a56b5;p=thirdparty%2Fpdns.git If the control console fd is closed, handle this as a "quit" command. Fixes #1694 --- diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 06d8742499..374c9603d1 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -1026,11 +1026,11 @@ static int guardian(int argc, char** argv) int infd = 0, outfd = 1; DynListener dlg(g_programname); - dlg.registerFunc("QUIT", &DLQuitHandler, "quit daemon"); - dlg.registerFunc("CYCLE", &DLCycleHandler, "restart instance"); - dlg.registerFunc("PING", &DLPingHandler, "ping guardian"); - dlg.registerFunc("STATUS", &DLStatusHandler, "get instance status from guardian"); - dlg.registerRestFunc(&DLRestHandler); + DynListener::registerExitFunc("QUIT", &DLQuitHandler); + DynListener::registerFunc("CYCLE", &DLCycleHandler, "restart instance"); + DynListener::registerFunc("PING", &DLPingHandler, "ping guardian"); + DynListener::registerFunc("STATUS", &DLStatusHandler, "get instance status from guardian"); + DynListener::registerRestFunc(&DLRestHandler); dlg.go(); string progname = argv[0]; @@ -1415,7 +1415,7 @@ int main(int argc, char** argv) } DynListener::registerFunc("SHOW", &DLShowHandler, "show a specific statistic or * to get a list", ""); DynListener::registerFunc("RPING", &DLPingHandler, "ping instance"); - DynListener::registerFunc("QUIT", &DLRQuitHandler, "quit daemon"); + DynListener::registerExitFunc("QUIT", &DLRQuitHandler); DynListener::registerFunc("UPTIME", &DLUptimeHandler, "get instance uptime"); DynListener::registerFunc("NOTIFY-HOST", &DLNotifyHostHandler, "notify host for specific zone", " "); DynListener::registerFunc("NOTIFY", &DLNotifyHandler, "queue a notification", ""); diff --git a/pdns/dynlistener.cc b/pdns/dynlistener.cc index d2e7b06096..26d474455f 100644 --- a/pdns/dynlistener.cc +++ b/pdns/dynlistener.cc @@ -36,13 +36,10 @@ #include #include #include -#include #include #include #include -#include -#include #include #include "misc.hh" @@ -59,6 +56,7 @@ extern StatBag S; DynListener::g_funkdb_t DynListener::s_funcdb; DynListener::g_funk_t* DynListener::s_restfunc; +std::string DynListener::s_exitfuncname; DynListener::~DynListener() { @@ -280,7 +278,14 @@ string DynListener::getLine() } if (len == 0) { - throw PDNSException("Guardian exited - going down as well"); + // File descriptor has been closed. We translate this into an exit + // request, but if it did not succeed and we are back attempting to + // read data, there's not much we can do but throw up. + static bool firstTime = true; + if (!firstTime) { + throw PDNSException("Guardian exited - going down as well"); + } + firstTime = false; } if (static_cast(len) == mesg.size()) { @@ -319,6 +324,13 @@ void DynListener::sendlines(const string &l) } } +void DynListener::registerExitFunc(const string &name, g_funk_t *gf) // NOLINT(readability-identifier-length) +{ + g_funkwithusage_t funk = {gf, "", "quit daemon"}; + s_exitfuncname = name; + s_funcdb[s_exitfuncname] = std::move(funk); +} + void DynListener::registerFunc(const string &name, g_funk_t *gf, const string &usage, const string &args) { g_funkwithusage_t e = {gf, args, usage}; @@ -339,6 +351,9 @@ void DynListener::theListener() for(;;) { string line=getLine(); + if (line.empty()) { + line = s_exitfuncname; + } boost::trim_right(line); vectorparts; diff --git a/pdns/dynlistener.hh b/pdns/dynlistener.hh index 2c3f354e88..44b91bf1b6 100644 --- a/pdns/dynlistener.hh +++ b/pdns/dynlistener.hh @@ -49,6 +49,7 @@ public: typedef struct { g_funk_t *func; string args; string usage; } g_funkwithusage_t; typedef map g_funkdb_t; + static void registerExitFunc(const string &name, g_funk_t *gf); static void registerFunc(const string &name, g_funk_t *gf, const string &usage="", const string &args=""); static void registerRestFunc(g_funk_t *gf); static g_funk_t* getFunc(const string& fname) { return s_funcdb[fname].func; } @@ -72,5 +73,6 @@ private: ComboAddress d_socketaddress; static g_funkdb_t s_funcdb; static g_funk_t* s_restfunc; + static string s_exitfuncname; bool testLive(const string& fname); };