]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Return command status and output as two separate items
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 18 Dec 2020 10:49:47 +0000 (11:49 +0100)
committerOtto <otto.moerbeek@open-xchange.com>
Mon, 15 Feb 2021 08:11:30 +0000 (09:11 +0100)
pdns/lua-base4.cc
pdns/lua-base4.hh
pdns/pdns_recursor.cc
pdns/rec_channel.cc
pdns/rec_channel.hh
pdns/rec_channel_rec.cc
pdns/rec_control.cc
pdns/syncres.hh

index bce88d14182ce608192dead4f7ef7504bfbab642..d36fc1e8c08cba30f2c73fec6388fabbeea1a4bf 100644 (file)
 BaseLua4::BaseLua4() {
 }
 
-void BaseLua4::loadFile(const std::string &fname) {
+int BaseLua4::loadFile(const std::string &fname) {
+  int ret = 0;
   std::ifstream ifs(fname);
-  if(!ifs) {
+  if (!ifs) {
+    ret = errno;
     g_log<<Logger::Error<<"Unable to read configuration file from '"<<fname<<"': "<<stringerror()<<endl;
-    return;
+    return ret;
   }
   loadStream(ifs);
+  return 0;
 };
 
 void BaseLua4::loadString(const std::string &script) {
index 1dbf62eecb39cca01a38d827ca7f5e5f3903c8b6..9394de4f8466c5390d8763f9a4e3b09a573956fc 100644 (file)
@@ -13,7 +13,7 @@ protected:
 
 public:
   BaseLua4();
-  void loadFile(const std::string &fname);
+  int loadFile(const std::string &fname);
   void loadString(const std::string &script);
   void loadStream(std::istream &is);
   virtual ~BaseLua4(); // this is so unique_ptr works with an incomplete type
index fda3a859d876fc8c47c8fbd8b8bed071e3d338c4..45e44b62ebaab6c23e8b37027f9ee2fb066f04fe 100644 (file)
@@ -3842,6 +3842,13 @@ static vector<pair<DNSName, uint16_t> >& operator+=(vector<pair<DNSName, uint16_
   return a;
 }
 
+static pair<int, string>& operator+=(std::pair<int, string>& a, const std::pair<int, string>& b)
+{
+  a.first |= b.first;
+  a.second += b.second;
+  return a;
+}
+
 /*
   This function should only be called by the handler to gather metrics, wipe the cache,
   reload the Lua script (not the Lua config) or change the current trace regex,
@@ -3884,6 +3891,7 @@ template<class T> T broadcastAccFunction(const boost::function<T*()>& func)
 }
 
 template string broadcastAccFunction(const boost::function<string*()>& fun); // explicit instantiation
+template std::pair<int, string> broadcastAccFunction(const boost::function<pair<int,string>*()>& fun); // explicit instantiation
 template uint64_t broadcastAccFunction(const boost::function<uint64_t*()>& fun); // explicit instantiation
 template vector<ComboAddress> broadcastAccFunction(const boost::function<vector<ComboAddress> *()>& fun); // explicit instantiation
 template vector<pair<DNSName,uint16_t> > broadcastAccFunction(const boost::function<vector<pair<DNSName, uint16_t> > *()>& fun); // explicit instantiation
@@ -3893,12 +3901,12 @@ static void handleRCC(int fd, FDMultiplexer::funcparam_t& var)
 {
   try {
     string remote;
-    string msg=s_rcc.recv(&remote);
+    string msg = s_rcc.recv(&remote).second;
     RecursorControlParser rcp;
     RecursorControlParser::func_t* command;
 
     g_log << Logger::Notice << "Received rec_control command '" << msg << "' from control socket" << endl;
-    string answer=rcp.getAnswer(fd, msg, &command);
+    auto answer = rcp.getAnswer(fd, msg, &command);
 
     // If we are inside a chroot, we need to strip
     if (!arg()["chroot"].empty()) {
@@ -4109,35 +4117,40 @@ static FDMultiplexer* getMultiplexer()
 }
 
 
-static string* doReloadLuaScript()
+static std::pair<int, string>* doReloadLuaScript()
 {
   string fname= ::arg()["lua-dns-script"];
   try {
     if(fname.empty()) {
       t_pdl.reset();
       g_log<<Logger::Info<<t_id<<" Unloaded current lua script"<<endl;
-      return new string("unloaded\n");
+      return new std::pair<int, string>(0, string("unloaded\n"));
     }
     else {
       t_pdl = std::make_shared<RecursorLua4>();
-      t_pdl->loadFile(fname);
+      int err = t_pdl->loadFile(fname);
+      if (err != 0) {
+        string msg = std::to_string(t_id) + " Retaining current script, could not read '" + fname + "': " + stringerror(err);
+        g_log<<Logger::Error<<msg<<endl;
+        return new std::pair<int, string>(1, msg + "\n");
+      }
     }
   }
   catch(std::exception& e) {
     g_log<<Logger::Error<<t_id<<" Retaining current script, error from '"<<fname<<"': "<< e.what() <<endl;
-    return new string("retaining current script, error from '"+fname+"': "+e.what()+"\n");
+    return new std::pair<int, string>(1, string("retaining current script, error from '"+fname+"': "+e.what()+"\n"));
   }
 
   g_log<<Logger::Warning<<t_id<<" (Re)loaded lua script from '"<<fname<<"'"<<endl;
-  return new string("(re)loaded '"+fname+"'\n");
+  return new std::pair<int, string>(0, string("(re)loaded '"+fname+"'\n"));
 }
 
-string doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end)
+std::pair<int,string> doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end)
 {
   if(begin != end)
     ::arg().set("lua-dns-script") = *begin;
 
-  return broadcastAccFunction<string>(doReloadLuaScript);
+  return broadcastAccFunction<std::pair<int, string>>(doReloadLuaScript);
 }
 
 static string* pleaseUseNewTraceRegex(const std::string& newRegex)
index 8e77f20a6d666624f333bee75f4fe5172bbb5894..3d95e5b7727caf8dba22ec2e23f4f5f49aeb30dd 100644 (file)
@@ -179,7 +179,7 @@ static void sendfd(int s, int fd, const string* remote)
   }
 }
 
-void RecursorControlChannel::send(const std::string& msg, const std::string* remote, unsigned int timeout, int fd)
+void RecursorControlChannel::send(const std::pair<int, const string&>& msg, const std::string* remote, unsigned int timeout, int fd)
 {
   int ret = waitForRWData(d_fd, false, timeout, 0);
   if(ret == 0) {
@@ -197,34 +197,45 @@ void RecursorControlChannel::send(const std::string& msg, const std::string* rem
     strncpy(remoteaddr.sun_path, remote->c_str(), sizeof(remoteaddr.sun_path)-1);
     remoteaddr.sun_path[sizeof(remoteaddr.sun_path)-1] = '\0';
 
-    if(::sendto(d_fd, msg.c_str(), msg.length(), 0, (struct sockaddr*) &remoteaddr, sizeof(remoteaddr) ) < 0)
+    if(::sendto(d_fd, &msg.first, sizeof(msg.first), 0, (struct sockaddr*) &remoteaddr, sizeof(remoteaddr) ) < 0)
+      throw PDNSException("Unable to send message over control channel '"+string(remoteaddr.sun_path)+"': "+stringerror());
+    if(::sendto(d_fd, msg.second.c_str(), msg.second.length(), 0, (struct sockaddr*) &remoteaddr, sizeof(remoteaddr) ) < 0)
       throw PDNSException("Unable to send message over control channel '"+string(remoteaddr.sun_path)+"': "+stringerror());
   }
-  else if(::send(d_fd, msg.c_str(), msg.length(), 0) < 0)
-    throw PDNSException("Unable to send message over control channel: "+stringerror());
-
+  else {
+    if(::send(d_fd, &msg.first, sizeof(msg.first), 0) < 0)
+      throw PDNSException("Unable to send message over control channel: "+stringerror());
+    if(::send(d_fd, msg.second.c_str(), msg.second.length(), 0) < 0)
+      throw PDNSException("Unable to send message over control channel: "+stringerror());
+  }
   if (fd != -1) {
     sendfd(d_fd, fd, remote);
   }
 }
 
-string RecursorControlChannel::recv(std::string* remote, unsigned int timeout)
+std::pair<int, string> RecursorControlChannel::recv(std::string* remote, unsigned int timeout)
 {
   char buffer[16384];
   ssize_t len;
   struct sockaddr_un remoteaddr;
-  socklen_t addrlen=sizeof(remoteaddr);
-  
-  int ret=waitForData(d_fd, timeout, 0);
-  if(ret==0)
+  socklen_t addrlen = sizeof(remoteaddr);
+
+  int ret = waitForData(d_fd, timeout, 0);
+  if (ret == 0) {
     throw PDNSException("Timeout waiting for answer from control channel");
-  
-  if( ret < 0 || (len=::recvfrom(d_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&remoteaddr, &addrlen)) < 0)
+  }
+  int err;
+  if (ret < 0 || ::recvfrom(d_fd, &err, sizeof(err), 0, (struct sockaddr*)&remoteaddr, &addrlen) < 0) {
+    throw PDNSException("Unable to receive return status over control channel: " + stringerror());
+  }
+  if (ret < 0 || (len = ::recvfrom(d_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&remoteaddr, &addrlen)) < 0) {
     throw PDNSException("Unable to receive message over control channel: "+stringerror());
+  }
 
-  if(remote)
+  if(remote) {
     *remote=remoteaddr.sun_path;
+  }
 
-  return string(buffer, buffer+len);
+  return make_pair(err, string(buffer, buffer+len));
 }
 
index 7337bd93f7c57b87c78df8a25c57770bcdab15b9..2a03b446662ca97e7b42ad4cd31d21238e45a6af 100644 (file)
@@ -51,8 +51,8 @@ public:
 
   uint64_t getStat(const std::string& name);
 
-  void send(const std::string& msg, const std::string* remote=nullptr, unsigned int timeout=5, int fd = -1);
-  std::string recv(std::string* remote=0, unsigned int timeout=5);
+  void send(const std::pair<int, const std::string&>&, const std::string* remote=nullptr, unsigned int timeout=5, int fd = -1);
+  std::pair<int, std::string> recv(std::string* remote=0, unsigned int timeout=5);
 
   int d_fd;
   static volatile sig_atomic_t stop;
@@ -68,7 +68,7 @@ public:
   }
   static void nop(void){}
   typedef void func_t(void);
-  std::string getAnswer(int s, const std::string& question, func_t** func);
+  pair<int, std::string> getAnswer(int s, const std::string& question, func_t** func);
 };
 
 enum class StatComponent { API, Carbon, RecControl, SNMP };
index e9fb0fc425930651b41945384cfac85c85c556c7..b67796292e11c66a4488d456621b9944027c229b 100644 (file)
@@ -1711,21 +1711,22 @@ static string clearDontThrottleNetmasks(T begin, T end) {
   return ret + "\n";
 }
 
-string RecursorControlParser::getAnswer(int s, const string& question, RecursorControlParser::func_t** command)
+
+std::pair<int, string> RecursorControlParser::getAnswer(int s, const string& question, RecursorControlParser::func_t** command)
 {
   *command=nop;
   vector<string> words;
   stringtok(words, question);
 
   if(words.empty())
-    return "invalid command\n";
+    return make_pair(1, "invalid command\n");
 
   string cmd=toLower(words[0]);
   vector<string>::const_iterator begin=words.begin()+1, end=words.end();
 
   // should probably have a smart dispatcher here, like auth has
   if(cmd=="help")
-    return
+    return make_pair(0,
 "add-dont-throttle-names [N...]   add names that are not allowed to be throttled\n"
 "add-dont-throttle-netmasks [N...]\n"
 "                                 add netmasks that are not allowed to be throttled\n"
@@ -1781,64 +1782,59 @@ string RecursorControlParser::getAnswer(int s, const string& question, RecursorC
 "unload-lua-script                unload Lua script\n"
 "version                          return Recursor version number\n"
 "wipe-cache domain0 [domain1] ..  wipe domain data from cache\n"
-"wipe-cache-typed type domain0 [domain1] ..  wipe domain data with qtype from cache\n";
-
-  if(cmd=="get-all")
-    return getAllStats();
-
-  if(cmd=="get")
-    return doGet(begin, end);
+"wipe-cache-typed type domain0 [domain1] ..  wipe domain data with qtype from cache\n");
 
-  if(cmd=="get-parameter")
-    return doGetParameter(begin, end);
-
-  if(cmd=="quit") {
+  if (cmd == "get-all") {
+    return make_pair(0, getAllStats());
+  }
+  if (cmd == "get") {
+    return make_pair(0, doGet(begin, end));
+  }
+  if (cmd == "get-parameter") {
+    return make_pair(0, doGetParameter(begin, end));
+  }
+  if (cmd == "quit") {
     *command=&doExit;
-    return "bye\n";
+    return make_pair(0, "bye\n");
   }
-
-  if(cmd=="version") {
-    return getPDNSVersion()+"\n";
+  if (cmd == "version") {
+    return make_pair(0, getPDNSVersion()+"\n");
   }
-
-  if(cmd=="quit-nicely") {
+  if (cmd == "quit-nicely") {
     *command=&doExitNicely;
-    return "bye nicely\n";
+    return make_pair(0, "bye nicely\n");
   }
-
-  if(cmd=="dump-cache")
-    return doDumpCache(s);
-
-  if(cmd=="dump-ednsstatus" || cmd=="dump-edns")
-    return doDumpEDNSStatus(begin, end);
-
-  if(cmd=="dump-nsspeeds")
-    return doDumpNSSpeeds(begin, end);
-
-  if(cmd=="dump-failedservers")
-    return doDumpFailedServers(begin, end);
-
-  if(cmd=="dump-rpz") {
-    return doDumpRPZ(begin, end);
+  if (cmd == "dump-cache") {
+    return make_pair(0, doDumpCache(s));
   }
-
-  if(cmd=="dump-throttlemap")
-   return doDumpThrottleMap(begin, end);
-
-  if(cmd=="wipe-cache" || cmd=="flushname")
-    return doWipeCache(begin, end, 0xffff);
-
-  if(cmd=="wipe-cache-typed") {
+  if (cmd == "dump-ednsstatus" || cmd == "dump-edns") {
+    return make_pair(0, doDumpEDNSStatus(begin, end));
+  }
+  if (cmd == "dump-nsspeeds") {
+    return make_pair(0, doDumpNSSpeeds(begin, end));
+  }
+  if (cmd == "dump-failedservers") {
+    return make_pair(0, doDumpFailedServers(begin, end));
+  }
+  if (cmd == "dump-rpz") {
+    return make_pair(0, doDumpRPZ(begin, end));
+  }
+  if (cmd == "dump-throttlemap") {
+    return make_pair(0, doDumpThrottleMap(begin, end));
+  }
+  if (cmd == "wipe-cache" || cmd == "flushname") {
+    return make_pair(0, doWipeCache(begin, end, 0xffff));
+  }
+  if (cmd == "wipe-cache-typed") {
     uint16_t qtype = QType::chartocode(begin->c_str());
     ++begin;
-    return doWipeCache(begin, end, qtype);
+    return make_pair(0, doWipeCache(begin, end, qtype));
   }
-
-  if(cmd=="reload-lua-script")
+  if (cmd == "reload-lua-script") {
     return doQueueReloadLuaScript(begin, end);
-
-  if(cmd=="reload-lua-config") {
-    if(begin != end)
+  }
+  if (cmd == "reload-lua-config") {
+    if (begin != end)
       ::arg().set("lua-config-file") = *begin;
 
     try {
@@ -1846,170 +1842,145 @@ string RecursorControlParser::getAnswer(int s, const string& question, RecursorC
       loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads);
       startLuaConfigDelayedThreads(delayedLuaThreads, g_luaconfs.getCopy().generation);
       g_log<<Logger::Warning<<"Reloaded Lua configuration file '"<<::arg()["lua-config-file"]<<"', requested via control channel"<<endl;
-      return "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n";
+      return make_pair(0, "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n");
     }
     catch(std::exception& e) {
-      return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e.what()+"\n";
+      return make_pair(1, "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e.what()+"\n");
     }
     catch(const PDNSException& e) {
-      return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e.reason+"\n";
+      return make_pair(1, "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e.reason+"\n");
     }
   }
-
-  if(cmd=="set-carbon-server")
-    return doSetCarbonServer(begin, end);
-
-  if(cmd=="trace-regex")
-    return doTraceRegex(begin, end);
-
-  if(cmd=="unload-lua-script") {
+  if (cmd == "set-carbon-server") {
+    return make_pair(0, doSetCarbonServer(begin, end));
+  }
+  if (cmd == "trace-regex") {
+    return make_pair(0, doTraceRegex(begin, end));
+  }
+  if (cmd == "unload-lua-script") {
     vector<string> empty;
     empty.push_back(string());
     return doQueueReloadLuaScript(empty.begin(), empty.end());
   }
-
-  if(cmd=="reload-acls") {
-    if(!::arg()["chroot"].empty()) {
+  if (cmd == "reload-acls") {
+    if (!::arg()["chroot"].empty()) {
       g_log<<Logger::Error<<"Unable to reload ACL when chroot()'ed, requested via control channel"<<endl;
-      return "Unable to reload ACL when chroot()'ed, please restart\n";
+      return make_pair(1, "Unable to reload ACL when chroot()'ed, please restart\n");
     }
 
     try {
       parseACLs();
-    } 
-    catch(std::exception& e) 
-    {
+    }
+    catch(std::exception& e) {
       g_log<<Logger::Error<<"Reloading ACLs failed (Exception: "<<e.what()<<")"<<endl;
-      return e.what() + string("\n");
+      return make_pair(1, e.what() + string("\n"));
     }
-    catch(PDNSException& ae)
-    {
+    catch(PDNSException& ae) {
       g_log<<Logger::Error<<"Reloading ACLs failed (PDNSException: "<<ae.reason<<")"<<endl;
-      return ae.reason + string("\n");
+      return make_pair(1, ae.reason + string("\n"));
     }
-    return "ok\n";
+    return make_pair(0, "ok\n");
   }
-
-
-  if(cmd=="top-remotes")
-    return doGenericTopRemotes(pleaseGetRemotes);
-
-  if(cmd=="top-queries")
-    return doGenericTopQueries(pleaseGetQueryRing);
-
-  if(cmd=="top-pub-queries")
-    return doGenericTopQueries(pleaseGetQueryRing, getRegisteredName);
-
-  if(cmd=="top-servfail-queries")
-    return doGenericTopQueries(pleaseGetServfailQueryRing);
-
-  if(cmd=="top-pub-servfail-queries")
-    return doGenericTopQueries(pleaseGetServfailQueryRing, getRegisteredName);
-
-  if(cmd=="top-bogus-queries")
-    return doGenericTopQueries(pleaseGetBogusQueryRing);
-
-  if(cmd=="top-pub-bogus-queries")
-    return doGenericTopQueries(pleaseGetBogusQueryRing, getRegisteredName);
-
-
-  if(cmd=="top-servfail-remotes")
-    return doGenericTopRemotes(pleaseGetServfailRemotes);
-
-  if(cmd=="top-bogus-remotes")
-    return doGenericTopRemotes(pleaseGetBogusRemotes);
-
-  if(cmd=="top-largeanswer-remotes")
-    return doGenericTopRemotes(pleaseGetLargeAnswerRemotes);
-
-  if(cmd=="top-timeouts")
-    return doGenericTopRemotes(pleaseGetTimeouts);
-
-
-  if(cmd=="current-queries")
-    return doCurrentQueries();
-  
-  if(cmd=="ping") {
-    return broadcastAccFunction<string>(nopFunction);
+  if (cmd == "top-remotes") {
+    return make_pair(0, doGenericTopRemotes(pleaseGetRemotes));
   }
-
-  if(cmd=="reload-zones") {
-    if(!::arg()["chroot"].empty()) {
+  if (cmd == "top-queries") {
+    return make_pair(0, doGenericTopQueries(pleaseGetQueryRing));
+  }
+  if (cmd == "top-pub-queries") {
+    return make_pair(0, doGenericTopQueries(pleaseGetQueryRing, getRegisteredName));
+  }
+  if (cmd == "top-servfail-queries") {
+    return make_pair(0, doGenericTopQueries(pleaseGetServfailQueryRing));
+  }
+  if (cmd == "top-pub-servfail-queries") {
+    return make_pair(0, doGenericTopQueries(pleaseGetServfailQueryRing, getRegisteredName));
+  }
+  if (cmd == "top-bogus-queries") {
+    return make_pair(0, doGenericTopQueries(pleaseGetBogusQueryRing));
+  }
+  if (cmd == "top-pub-bogus-queries") {
+    return make_pair(0, doGenericTopQueries(pleaseGetBogusQueryRing, getRegisteredName));
+  }
+  if (cmd == "top-servfail-remotes") {
+    return make_pair(0, doGenericTopRemotes(pleaseGetServfailRemotes));
+  }
+  if (cmd == "top-bogus-remotes") {
+    return make_pair(0, doGenericTopRemotes(pleaseGetBogusRemotes));
+  }
+  if (cmd == "top-largeanswer-remotes") {
+    return make_pair(0, doGenericTopRemotes(pleaseGetLargeAnswerRemotes));
+  }
+  if (cmd == "top-timeouts") {
+    return make_pair(0, doGenericTopRemotes(pleaseGetTimeouts));
+  }
+  if (cmd == "current-queries") {
+    return make_pair(0, doCurrentQueries());
+  }
+  if (cmd == "ping") {
+    return make_pair(0, broadcastAccFunction<string>(nopFunction));
+  }
+  if (cmd == "reload-zones") {
+    if (!::arg()["chroot"].empty()) {
       g_log<<Logger::Error<<"Unable to reload zones and forwards when chroot()'ed, requested via control channel"<<endl;
-      return "Unable to reload zones and forwards when chroot()'ed, please restart\n";
+      return make_pair(1, "Unable to reload zones and forwards when chroot()'ed, please restart\n");
     }
-    return reloadAuthAndForwards();
+    return make_pair(0, reloadAuthAndForwards());
   }
-
-  if(cmd=="set-ecs-minimum-ttl") {
-    return setMinimumECSTTL(begin, end);
+  if (cmd == "set-ecs-minimum-ttl") {
+    return make_pair(0, setMinimumECSTTL(begin, end));
   }
-
-  if(cmd=="set-max-cache-entries") {
-    return setMaxCacheEntries(begin, end);
+  if (cmd == "set-max-cache-entries") {
+    return make_pair(0, setMaxCacheEntries(begin, end));
   }
-  if(cmd=="set-max-packetcache-entries") {
-    return setMaxPacketCacheEntries(begin, end);
+  if (cmd == "set-max-packetcache-entries") {
+    return make_pair(0, setMaxPacketCacheEntries(begin, end));
   }
-  
-  if(cmd=="set-minimum-ttl") {
-    return setMinimumTTL(begin, end);
+  if (cmd == "set-minimum-ttl") {
+    return make_pair(0, setMinimumTTL(begin, end));
   }
-  
-  if(cmd=="get-qtypelist") {
-    return g_rs.getQTypeReport();
+  if (cmd == "get-qtypelist") {
+    return make_pair(0, g_rs.getQTypeReport());
   }
-
-  if(cmd=="add-nta") {
-    return doAddNTA(begin, end);
+  if (cmd == "add-nta") {
+    return make_pair(0, doAddNTA(begin, end));
   }
-
-  if(cmd=="clear-nta") {
-    return doClearNTA(begin, end);
+  if (cmd == "clear-nta") {
+    return make_pair(0, doClearNTA(begin, end));
   }
-
-  if(cmd=="get-ntas") {
-    return getNTAs();
+  if (cmd == "get-ntas") {
+    return make_pair(0, getNTAs());
   }
-
-  if(cmd=="add-ta") {
-    return doAddTA(begin, end);
+  if (cmd == "add-ta") {
+    return make_pair(0, doAddTA(begin, end));
   }
-
-  if(cmd=="clear-ta") {
-    return doClearTA(begin, end);
+  if (cmd == "clear-ta") {
+    return make_pair(0, doClearTA(begin, end));
   }
-
-  if(cmd=="get-tas") {
-    return getTAs();
+  if (cmd == "get-tas") {
+    return make_pair(0, getTAs());
+  }
+  if (cmd == "set-dnssec-log-bogus") {
+    return make_pair(0, doSetDnssecLogBogus(begin, end));
   }
-
-  if (cmd=="set-dnssec-log-bogus")
-    return doSetDnssecLogBogus(begin, end);
-
   if (cmd == "get-dont-throttle-names") {
-    return getDontThrottleNames();
+    return make_pair(0, getDontThrottleNames());
   }
-
   if (cmd == "get-dont-throttle-netmasks") {
-    return getDontThrottleNetmasks();
+    return make_pair(0, getDontThrottleNetmasks());
   }
-
   if (cmd == "add-dont-throttle-names") {
-    return addDontThrottleNames(begin, end);
+    return make_pair(0, addDontThrottleNames(begin, end));
   }
-
   if (cmd == "add-dont-throttle-netmasks") {
-    return addDontThrottleNetmasks(begin, end);
+    return make_pair(0, addDontThrottleNetmasks(begin, end));
   }
-
   if (cmd == "clear-dont-throttle-names") {
-    return clearDontThrottleNames(begin, end);
+    return make_pair(0, clearDontThrottleNames(begin, end));
   }
-
   if (cmd == "clear-dont-throttle-netmasks") {
-    return clearDontThrottleNetmasks(begin, end);
+    return make_pair(0, clearDontThrottleNetmasks(begin, end));
   }
 
-  return "Unknown command '"+cmd+"', try 'help'\n";
+  return make_pair(1, "Unknown command '"+cmd+"', try 'help'\n");
 }
index de42be53ef3ede0a444c063150763fef54a7129b..ce70cdf7864a00f354122f918efa9f55b29b66e7 100644 (file)
@@ -82,53 +82,57 @@ static void initArguments(int argc, char** argv)
 }
 
 int main(int argc, char** argv)
-try
 {
-  initArguments(argc, argv);
-  RecursorControlChannel rccS;
-  string sockname="pdns_recursor";
-
-  if (arg()["config-name"] != "")
-    sockname+="-"+arg()["config-name"];
-
-  if(!arg()["process"].empty())
-    sockname+="."+arg()["process"];
-
-  sockname.append(".controlsocket");
-
-  rccS.connect(arg()["socket-dir"], sockname);
-
-  const vector<string>&commands=arg().getCommands();
-  string command;
-  int fd = -1;
-  for(unsigned int i=0; i< commands.size(); ++i) {
-    if(i>0)
-      command+=" ";
-    command+=commands[i];
-    if (commands[i] == "dump-cache" && i+1 < commands.size()) {
-      ++i;
-      if (commands[i] == "stdout") {
-        fd = STDOUT_FILENO;
-      } else {
-        fd = open(commands[i].c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660);
-      }
-      if (fd == -1) {
-        int err = errno;
-        throw PDNSException("Error opening dump file for writing: " + stringerror(err));
+  try {
+    initArguments(argc, argv);
+    RecursorControlChannel rccS;
+    string sockname="pdns_recursor";
+
+    if (arg()["config-name"] != "")
+      sockname+="-"+arg()["config-name"];
+
+    if(!arg()["process"].empty())
+      sockname+="."+arg()["process"];
+
+    sockname.append(".controlsocket");
+
+    rccS.connect(arg()["socket-dir"], sockname);
+
+    const vector<string>&commands=arg().getCommands();
+    string command;
+    int fd = -1;
+    for(unsigned int i=0; i< commands.size(); ++i) {
+      if(i>0)
+        command+=" ";
+      command+=commands[i];
+      if (commands[i] == "dump-cache" && i+1 < commands.size()) {
+        ++i;
+        if (commands[i] == "stdout") {
+          fd = STDOUT_FILENO;
+        } else {
+          fd = open(commands[i].c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660);
+        }
+        if (fd == -1) {
+          int err = errno;
+          throw PDNSException("Error opening dump file for writing: " + stringerror(err));
+        }
       }
     }
+
+    auto timeout = arg().asNum("timeout");
+    rccS.send(make_pair(0, command), nullptr, timeout, fd);
+
+    auto receive = rccS.recv(0, timeout);
+    if (receive.first != 0) {
+      cerr << receive.second;
+    } else {
+      cout << receive.second;
+    }
+    return receive.first;
   }
-  rccS.send(command, nullptr, arg().asNum("timeout"), fd);
-  string receive=rccS.recv(0, arg().asNum("timeout"));
-  if(receive.compare(0, 7, "Unknown") == 0) {
-    cerr<<receive<<endl;
+  catch(PDNSException& ae) {
+    cerr<<"Fatal: "<<ae.reason<<"\n";
     return 1;
   }
-  cout<<receive;
-  return 0;
-}
-catch(PDNSException& ae)
-{
-  cerr<<"Fatal: "<<ae.reason<<"\n";
-  return 1;
 }
+
index a8705b32c302957db86a51fef85c2531d45bd84b..5c2109c516e8461cfaaf983ea89645539fa60c8a 100644 (file)
@@ -1077,7 +1077,7 @@ extern thread_local std::unique_ptr<addrringbuf_t> t_servfailremotes, t_largeans
 
 extern thread_local std::unique_ptr<boost::circular_buffer<pair<DNSName,uint16_t> > > t_queryring, t_servfailqueryring, t_bogusqueryring;
 extern thread_local std::shared_ptr<NetmaskGroup> t_allowFrom;
-string doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end);
+std::pair<int, string> doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end);
 string doTraceRegex(vector<string>::const_iterator begin, vector<string>::const_iterator end);
 void parseACLs();
 extern RecursorStats g_stats;