From: Remi Gacogne Date: Mon, 3 Feb 2025 11:34:06 +0000 (+0100) Subject: dnsdist: Document that RE2 does full matching, add regression tests X-Git-Tag: dnsdist-2.0.0-alpha1~130^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2f485cb5c4baa7e7d074c5cd9bc32a4b95dcd0e;p=thirdparty%2Fpdns.git dnsdist: Document that RE2 does full matching, add regression tests --- diff --git a/pdns/dnsdistdist/docs/reference/selectors.rst b/pdns/dnsdistdist/docs/reference/selectors.rst index 2830f68dd4..13c706de89 100644 --- a/pdns/dnsdistdist/docs/reference/selectors.rst +++ b/pdns/dnsdistdist/docs/reference/selectors.rst @@ -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 index 0000000000..4a658bfed5 --- /dev/null +++ b/regression-tests.dnsdist/test_RE2.py @@ -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)