]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
If the control console fd is closed, handle this as a "quit" command. 15041/head
authorMiod Vallat <miod.vallat@open-xchange.com>
Wed, 15 Jan 2025 14:43:13 +0000 (15:43 +0100)
committerMiod Vallat <miod.vallat@open-xchange.com>
Wed, 15 Jan 2025 14:48:16 +0000 (15:48 +0100)
Fixes #1694

pdns/auth-main.cc
pdns/dynlistener.cc
pdns/dynlistener.hh

index 06d8742499696442200dddb8c656e98c87a01426..374c9603d1a2114a942bb1a3ac8f8725adf4e47e 100644 (file)
@@ -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", "<statistic>");
     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", "<zone> <host>");
     DynListener::registerFunc("NOTIFY", &DLNotifyHandler, "queue a notification", "<zone>");
index d2e7b06096299e8224520ac4bd847ed3a00f47d1..26d474455fecd931bf47b8ce6a7ede05f865bea1 100644 (file)
 #include <netinet/in.h>
 #include <iostream>
 #include <sstream>
-#include <sys/types.h>
 #include <csignal>
 
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <unistd.h>
-#include <boost/algorithm/string.hpp> 
 #include <thread>
 
 #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<size_t>(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);
 
       vector<string>parts;
index 2c3f354e88aadbcbdf858dd8bed54d453db1a2aa..44b91bf1b6fed4d7d652344780b92b73a51b8882 100644 (file)
@@ -49,6 +49,7 @@ public:
   typedef struct { g_funk_t *func; string args; string usage; } g_funkwithusage_t;
   typedef map<string,g_funkwithusage_t> 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);
 };