]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix access to frontends while in client mode 16090/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 5 Sep 2025 14:38:49 +0000 (16:38 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 5 Sep 2025 14:42:36 +0000 (16:42 +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>
pdns/dnsdistdist/dnsdist-lua.cc
regression-tests.dnsdist/test_DOH.py

index 5b09ba8ab670a1f50dffa9fccccf8bb6171fc39d..151f935647508b0344dba5be6a15f8b250c47bc2 100644 (file)
@@ -2490,10 +2490,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 {
@@ -2572,10 +2572,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 {
@@ -2641,10 +2641,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();
@@ -2871,8 +2871,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'