]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Document that RE2 does full matching, add regression tests
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 3 Feb 2025 11:34:06 +0000 (12:34 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 3 Feb 2025 11:34:06 +0000 (12:34 +0100)
pdns/dnsdistdist/docs/reference/selectors.rst
regression-tests.dnsdist/test_RE2.py [new file with mode: 0644]

index 2830f68dd4cfc3df17ae4007850657db93456ed6..13c706de897639b6d6e618765b3d653007a04cbe 100644 (file)
@@ -331,7 +331,7 @@ Selectors can be combined via :func:`AndRule`, :func:`OrRule` and :func:`NotRule
 
 .. function:: RE2Rule(regex)
 
-  Matches the query name against the supplied regex using the RE2 engine.
+  Matches the query name against the supplied regex using the RE2 engine. Note that this rule requires a full match of the query name, meaning that for example the ``powerdns`` expression with match a query name of ``powerdns`` but not ``prefixpowerdns``, ``sub.powerdns``, ``powerdnssuffix`` or ``powerdns.tld``. In short, the expression is treated as if it started with a ``^`` and ended with a ``$``.
 
   For an example of usage, see :func:`RegexRule`.
 
diff --git a/regression-tests.dnsdist/test_RE2.py b/regression-tests.dnsdist/test_RE2.py
new file mode 100644 (file)
index 0000000..4a658bf
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+import dns
+from dnsdisttests import DNSDistTest
+
+class TestRE2(DNSDistTest):
+    _config_template = """
+    newServer{address="127.0.0.1:%d"}
+
+    -- keep in mind this is a FULL match, as if the expression started with
+    -- a '^' and ended with a '$'
+    addAction(RE2Rule("re2\\\\.tests\\\\.powerdns\\\\.com"), RCodeAction(DNSRCode.REFUSED))
+    """
+
+    def testMatch(self):
+        """
+        RE2: Match
+        """
+        name = 're2.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        query.flags &= ~dns.flags.RD
+        expectedResponse = dns.message.make_response(query)
+        expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+        for method in ("sendUDPQuery", "sendTCPQuery"):
+            sender = getattr(self, method)
+            (_, receivedResponse) = sender(query, response=None, useQueue=False)
+            self.assertEqual(receivedResponse, expectedResponse)
+
+    def testNoMatch(self):
+        """
+        RE2: No match
+        """
+        name = 'sub.re2.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        query.flags &= ~dns.flags.RD
+        response = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    3600,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '127.0.0.1')
+
+        response.answer.append(rrset)
+
+        for method in ("sendUDPQuery", "sendTCPQuery"):
+            sender = getattr(self, method)
+            (receivedQuery, receivedResponse) = sender(query, response=response)
+            receivedQuery.id = query.id
+            self.assertEqual(receivedQuery, query)
+            self.assertEqual(receivedResponse, response)