]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add control command for toggling response dropping
authorMichał Kępień <michal@isc.org>
Fri, 11 Apr 2025 14:14:57 +0000 (09:14 -0500)
committerMichał Kępień <michal@isc.org>
Fri, 11 Apr 2025 14:14:57 +0000 (09:14 -0500)
Implement a reusable control command that makes it possible to
dynamically disable/enable sending responses to clients.  This is a
typical use case for custom DNS servers employed in various BIND 9
system tests.

bin/tests/system/isctest/asyncserver.py

index 9300e9bd03bf67e5bb4ab3471611eb6da6aac0ab..fed86f6f33c90ecdbca3b18297c1032321806ced 100644 (file)
@@ -1069,3 +1069,42 @@ class ControlCommand(abc.ABC):
 
     def __str__(self) -> str:
         return self.__class__.__name__
+
+
+class ToggleResponsesCommand(ControlCommand):
+    """
+    Disable/enable sending responses from the server.
+    """
+
+    control_subdomain = "send-responses"
+
+    def __init__(self) -> None:
+        self._current_handler: Optional[IgnoreAllQueries] = None
+
+    def handle(
+        self, args: List[str], server: ControllableAsyncDnsServer, qctx: QueryContext
+    ) -> Optional[str]:
+        if len(args) != 1:
+            logging.error("Invalid %s query %s", self, qctx.qname)
+            qctx.response.set_rcode(dns.rcode.SERVFAIL)
+            return "invalid query; use exactly one of 'enable' or 'disable' in QNAME"
+
+        mode = args[0]
+
+        if mode == "disable":
+            if self._current_handler:
+                return "sending responses already disabled"
+            self._current_handler = IgnoreAllQueries()
+            server.install_response_handler(self._current_handler, prepend=True)
+            return "sending responses disabled"
+
+        if mode == "enable":
+            if not self._current_handler:
+                return "sending responses already enabled"
+            server.uninstall_response_handler(self._current_handler)
+            self._current_handler = None
+            return "sending responses enabled"
+
+        logging.error("Unrecognized response sending mode '%s'", mode)
+        qctx.response.set_rcode(dns.rcode.SERVFAIL)
+        return f"unrecognized response sending mode '{mode}'"