]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix access to frontends while in client mode 16095/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 5 Sep 2025 14:38:49 +0000 (16:38 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 8 Sep 2025 12:33:16 +0000 (14:33 +0200)
Since 2.0 we return `nil` instead of an object containing a `NULL`
pointer when the requested object does not exist, to make it possible
to check the validity of the returned object from `Lua`. It makes
sense in all contexts except when we are in client mode, because
then accessing the object in the remaining parts of the configuration
will trigger an error. Our DNS over HTTPS documentation itself contains
such a Lua configuration snippet, which is now broken.
This commit reverts back to sending an object containg a `NULL`
pointer when accessing the frontends in the client mode case.

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
(cherry picked from commit e6b9a30bbe1e198702308d9904d067eb89b646f1)

pdns/dnsdistdist/dnsdist-lua.cc
regression-tests.dnsdist/test_DOH.py

index 67fc230fc8ec3cfbe43f743c480b7c623478fcb9..060852c39e6256d5bb448dcd316166a28f8be572 100644 (file)
@@ -2484,10 +2484,10 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
   });
 
 #ifdef HAVE_DNS_OVER_QUIC
-  luaCtx.writeFunction("getDOQFrontend", [client](uint64_t index) {
+  luaCtx.writeFunction("getDOQFrontend", [client](uint64_t index) -> boost::optional<std::shared_ptr<DOQFrontend>> {
     boost::optional<std::shared_ptr<DOQFrontend>> result{boost::none};
     if (client) {
-      return result;
+      return std::shared_ptr<DOQFrontend>();
     }
     setLuaNoSideEffect();
     try {
@@ -2566,10 +2566,10 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
   });
 
 #ifdef HAVE_DNS_OVER_HTTP3
-  luaCtx.writeFunction("getDOH3Frontend", [client](uint64_t index) {
+  luaCtx.writeFunction("getDOH3Frontend", [client](uint64_t index) -> boost::optional<std::shared_ptr<DOH3Frontend>> {
     boost::optional<std::shared_ptr<DOH3Frontend>> result{boost::none};
     if (client) {
-      return result;
+      return std::shared_ptr<DOH3Frontend>();
     }
     setLuaNoSideEffect();
     try {
@@ -2635,10 +2635,10 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 #endif
   });
 
-  luaCtx.writeFunction("getDOHFrontend", [client]([[maybe_unused]] uint64_t index) {
+  luaCtx.writeFunction("getDOHFrontend", [client]([[maybe_unused]] uint64_t index) -> boost::optional<std::shared_ptr<DOHFrontend>> {
     boost::optional<std::shared_ptr<DOHFrontend>> result{boost::none};
     if (client) {
-      return result;
+      return std::shared_ptr<DOHFrontend>();
     }
 #ifdef HAVE_DNS_OVER_HTTPS
     setLuaNoSideEffect();
@@ -2865,8 +2865,11 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 #endif
   });
 
-  luaCtx.writeFunction("getTLSFrontend", []([[maybe_unused]] uint64_t index) {
+  luaCtx.writeFunction("getTLSFrontend", [client]([[maybe_unused]] uint64_t index) -> boost::optional<std::shared_ptr<TLSFrontend>> {
     boost::optional<std::shared_ptr<TLSFrontend>> result{boost::none};
+    if (client) {
+      return std::shared_ptr<TLSFrontend>();
+    }
 #ifdef HAVE_DNS_OVER_TLS
     setLuaNoSideEffect();
     try {
index b07a5875c5035c751bd55ef2b53c9770289e3961..fe8f1d0320fc5b5ebe1586369daf611b0fbcf8a8 100644 (file)
@@ -4,6 +4,7 @@ import base64
 import dns
 import os
 import time
+import subprocess
 import unittest
 import clientsubnetoption
 
@@ -755,6 +756,27 @@ class DOHTests(object):
         self.assertIn('foo: bar', headers)
         self.assertNotIn(self._customResponseHeader2, headers)
 
+    def testFrontendAccessViaBuiltInClient(self):
+        """
+        DOH: Built-in client
+        """
+        if self._yaml_config_template:
+            return
+
+        output = None
+        try:
+            confFile = os.path.join('configs', 'dnsdist_%s.conf' % (self.__class__.__name__))
+            testcmd = [os.environ['DNSDISTBIN'], '--client', '-C', confFile ]
+            process = subprocess.Popen(testcmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
+            output = process.communicate(input=b'showVersion()\n')
+        except subprocess.CalledProcessError as exc:
+            raise AssertionError('%s failed (%d): %s' % (testcmd, process.returncode, process.output))
+
+        if process.returncode != 0:
+          raise AssertionError('%s failed (%d): %s' % (testcmd, process.returncode, output))
+
+        self.assertTrue(output[0].startswith(b'dnsdist '))
+
 class TestDoHNGHTTP2(DOHTests, DNSDistDOHTest):
     _dohLibrary = 'nghttp2'