]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: create RemoteLoggers in client mode, but avoid connecting
authorChris Hofstaedtler <chris.hofstaedtler@deduktiva.com>
Mon, 5 Mar 2018 13:10:32 +0000 (14:10 +0100)
committerChris Hofstaedtler <chris.hofstaedtler@deduktiva.com>
Mon, 5 Mar 2018 13:10:32 +0000 (14:10 +0100)
Fixes a nullptr deref under --check-config.

pdns/dnsdist-lua-bindings.cc
pdns/fstrm_logger.cc
pdns/fstrm_logger.hh
pdns/remote_logger.cc
regression-tests.dnsdist/dnsdisttests.py

index e8cc99f5a43afc437a2ac2cef537a125be55b116..bb1415c7a4871ef34c5196920a9755f57b0ced1f 100644 (file)
@@ -266,29 +266,20 @@ void setupLuaBindings(bool client)
 
   /* RemoteLogger */
   g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote, boost::optional<uint16_t> timeout, boost::optional<uint64_t> maxQueuedEntries, boost::optional<uint8_t> reconnectWaitTime) {
-      if (client) {
-        return std::shared_ptr<RemoteLoggerInterface>();
-      }
-      return std::shared_ptr<RemoteLoggerInterface>(new RemoteLogger(ComboAddress(remote), timeout ? *timeout : 2, maxQueuedEntries ? *maxQueuedEntries : 100, reconnectWaitTime ? *reconnectWaitTime : 1));
+      return std::shared_ptr<RemoteLoggerInterface>(new RemoteLogger(ComboAddress(remote), timeout ? *timeout : 2, maxQueuedEntries ? *maxQueuedEntries : 100, reconnectWaitTime ? *reconnectWaitTime : 1, client));
     });
 
   g_lua.writeFunction("newFrameStreamUnixLogger", [client](const std::string& address) {
-      if (client) {
-        return std::shared_ptr<RemoteLoggerInterface>();
-      }
 #ifdef HAVE_FSTRM
-      return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_UNIX, address));
+      return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_UNIX, address, !client));
 #else
       throw std::runtime_error("fstrm support is required to build an AF_UNIX FrameStreamLogger");
 #endif /* HAVE_FSTRM */
     });
 
   g_lua.writeFunction("newFrameStreamTcpLogger", [client](const std::string& address) {
-      if (client) {
-        return std::shared_ptr<RemoteLoggerInterface>();
-      }
 #if defined(HAVE_FSTRM) && defined(HAVE_FSTRM_TCP_WRITER_INIT)
-      return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_INET, address));
+      return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_INET, address, !client));
 #else
       throw std::runtime_error("fstrm with TCP support is required to build an AF_INET FrameStreamLogger");
 #endif /* HAVE_FSTRM */
index fb232b390082ab8669820b15fed2259b5607e1d7..617aa73d5cfd76df42c687f3c7d52b2500c39e0a 100644 (file)
@@ -9,7 +9,7 @@
 
 #ifdef HAVE_FSTRM
 
-FrameStreamLogger::FrameStreamLogger(const int family, const std::string& address): d_family(family), d_address(address)
+FrameStreamLogger::FrameStreamLogger(const int family, const std::string& address, bool connect): d_family(family), d_address(address)
 {
   fstrm_res res;
 
@@ -78,14 +78,16 @@ FrameStreamLogger::FrameStreamLogger(const int family, const std::string& addres
       throw std::runtime_error("FrameStreamLogger: fstrm_iothr_options_set_queue_model failed: " + std::to_string(res));
     }
 
-    d_iothr = fstrm_iothr_init(d_iothropt, &d_writer);
-    if (!d_iothr) {
-      throw std::runtime_error("FrameStreamLogger: fstrm_iothr_init() failed.");
-    }
+    if (connect) {
+      d_iothr = fstrm_iothr_init(d_iothropt, &d_writer);
+      if (!d_iothr) {
+        throw std::runtime_error("FrameStreamLogger: fstrm_iothr_init() failed.");
+      }
 
-    d_ioqueue = fstrm_iothr_get_input_queue(d_iothr);
-    if (!d_ioqueue) {
-      throw std::runtime_error("FrameStreamLogger: fstrm_iothr_get_input_queue() failed.");
+      d_ioqueue = fstrm_iothr_get_input_queue(d_iothr);
+      if (!d_ioqueue) {
+        throw std::runtime_error("FrameStreamLogger: fstrm_iothr_get_input_queue() failed.");
+      }
     }
   } catch (std::runtime_error &e) {
     this->cleanup();
@@ -130,6 +132,9 @@ FrameStreamLogger::~FrameStreamLogger()
 
 void FrameStreamLogger::queueData(const std::string& data)
 {
+  if (!d_ioqueue || !d_iothr) {
+    return;
+  }
   uint8_t *frame = (uint8_t*)malloc(data.length());
   if (!frame) {
     warnlog("FrameStreamLogger: cannot allocate memory for stream.");
index f661e719e4c38a975b6d4e9e3b76d37a1873e35c..6f4c40a1ec9fb11b64ad5f829fe36cf43c4f1403 100644 (file)
@@ -35,7 +35,7 @@
 class FrameStreamLogger : public RemoteLoggerInterface, boost::noncopyable
 {
 public:
-  FrameStreamLogger(int family, const std::string& address);
+  FrameStreamLogger(int family, const std::string& address, bool connect);
   virtual ~FrameStreamLogger();
   virtual void queueData(const std::string& data) override;
   virtual std::string toString() override
index 9844cc132a953a75d80ecbae4730d2e3c342ce87..6c472e7745cd3fb85058db5c5a7c51fa8e605b5d 100644 (file)
@@ -41,10 +41,6 @@ void RemoteLogger::busyReconnectLoop()
 
 void RemoteLogger::worker()
 {
-  if (d_asyncConnect) {
-    busyReconnectLoop();
-  }
-
   while(true) {
     std::string data;
     {
index eaea70b598fa7178fd2d93b88f480e5bedda37e9..5dfec19f5b20564a7952671d611ddd669fab1cb0 100644 (file)
@@ -70,6 +70,12 @@ class DNSDistTest(unittest.TestCase):
             dnsdistcmd.extend(['--acl', acl])
         print(' '.join(dnsdistcmd))
 
+        # validate config with --check-config, which sets client=true, possibly exposing bugs.
+        testcmd = dnsdistcmd + ['--check-config']
+        output = subprocess.check_output(testcmd, close_fds=True)
+        if output != b'Configuration \'dnsdist_test.conf\' OK!\n':
+            raise AssertionError('dnsdist --check-config failed: %s' % output)
+
         if shutUp:
             with open(os.devnull, 'w') as fdDevNull:
                 cls._dnsdist = subprocess.Popen(dnsdistcmd, close_fds=True, stdout=fdDevNull)