diff --git a/dns/rdtypes/svcbbase.py b/dns/rdtypes/svcbbase.py index 05652413..a2b15b92 100644 --- a/dns/rdtypes/svcbbase.py +++ b/dns/rdtypes/svcbbase.py @@ -35,6 +35,7 @@ class ParamKey(dns.enum.IntEnum): ECH = 5 IPV6HINT = 6 DOHPATH = 7 + OHTTP = 8 @classmethod def _maximum(cls): @@ -396,6 +397,36 @@ def to_wire(self, file, origin=None): # pylint: disable=W0613 file.write(self.ech) +@dns.immutable.immutable +class OHTTPParam(Param): + # We don't ever expect to instantiate this class, but we need + # a from_value() and a from_wire_parser(), so we just return None + # from the class methods when things are OK. + + @classmethod + def emptiness(cls): + return Emptiness.ALWAYS + + @classmethod + def from_value(cls, value): + if value is None or value == "": + return None + else: + raise ValueError("ohttp with non-empty value") + + def to_text(self): + raise NotImplementedError # pragma: no cover + + @classmethod + def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613 + if parser.remaining() != 0: + raise dns.exception.FormError + return None + + def to_wire(self, file, origin=None): # pylint: disable=W0613 + raise NotImplementedError # pragma: no cover + + _class_for_key = { ParamKey.MANDATORY: MandatoryParam, ParamKey.ALPN: ALPNParam, @@ -404,6 +435,7 @@ def to_wire(self, file, origin=None): # pylint: disable=W0613 ParamKey.IPV4HINT: IPv4HintParam, ParamKey.ECH: ECHParam, ParamKey.IPV6HINT: IPv6HintParam, + ParamKey.OHTTP: OHTTPParam, } diff --git a/tests/example b/tests/example index adc42aa9..bc324d25 100644 --- a/tests/example +++ b/tests/example @@ -259,6 +259,10 @@ svcb01 SVCB ( 100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345" ech="abcd" ipv4hint=1.2.3.4,4.3.2.1 ipv6hint=1::2,3::4 key12345="foo" ) +svcb02 SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb03 SVCB 16 foo.example.org. alpn=foo\092,bar,h2 +svcb04 SVCB 16 foo.example.org. dohpath=/dns-query{?dns} +svcb05 SVCB 16 foo.example.org. ohttp https01 HTTPS 0 svc https02 HTTPS 1 . port=8002 ech="abcd" -resinfo RESINFO qnamemin exterr=15,16,17 infourl=https://resolver.example.com/guide \ No newline at end of file +resinfo RESINFO qnamemin exterr=15,16,17 infourl=https://resolver.example.com/guide diff --git a/tests/example1.good b/tests/example1.good index d5d728a6..735eac61 100644 --- a/tests/example1.good +++ b/tests/example1.good @@ -133,6 +133,10 @@ srv01 3600 IN SRV 0 0 0 . srv02 3600 IN SRV 65535 65535 65535 old-slow-box.example.com. sshfp1 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab svcb01 3600 IN SVCB 100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345" ipv4hint="1.2.3.4,4.3.2.1" ech="abcd" ipv6hint="1::2,3::4" key12345="foo" +svcb02 3600 IN SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb03 3600 IN SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb04 3600 IN SVCB 16 foo.example.org. dohpath="/dns-query{?dns}" +svcb05 3600 IN SVCB 16 foo.example.org. ohttp t 301 IN A 73.80.65.49 tlsa1 3600 IN TLSA 3 1 1 a9cdf989b504fe5dca90c0d2167b6550570734f7c763e09fdf88904e06157065 tlsa2 3600 IN TLSA 1 0 1 efddf0d915c7bdc5782c0881e1b2a95ad099fbdd06d7b1f77982d9364338d955 diff --git a/tests/example2.good b/tests/example2.good index 76890e72..bfb1bfb3 100644 --- a/tests/example2.good +++ b/tests/example2.good @@ -133,6 +133,10 @@ srv01.example. 3600 IN SRV 0 0 0 . srv02.example. 3600 IN SRV 65535 65535 65535 old-slow-box.example.com. sshfp1.example. 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab svcb01.example. 3600 IN SVCB 100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345" ipv4hint="1.2.3.4,4.3.2.1" ech="abcd" ipv6hint="1::2,3::4" key12345="foo" +svcb02.example. 3600 IN SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb03.example. 3600 IN SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb04.example. 3600 IN SVCB 16 foo.example.org. dohpath="/dns-query{?dns}" +svcb05.example. 3600 IN SVCB 16 foo.example.org. ohttp t.example. 301 IN A 73.80.65.49 tlsa1.example. 3600 IN TLSA 3 1 1 a9cdf989b504fe5dca90c0d2167b6550570734f7c763e09fdf88904e06157065 tlsa2.example. 3600 IN TLSA 1 0 1 efddf0d915c7bdc5782c0881e1b2a95ad099fbdd06d7b1f77982d9364338d955 diff --git a/tests/example3.good b/tests/example3.good index d5d728a6..735eac61 100644 --- a/tests/example3.good +++ b/tests/example3.good @@ -133,6 +133,10 @@ srv01 3600 IN SRV 0 0 0 . srv02 3600 IN SRV 65535 65535 65535 old-slow-box.example.com. sshfp1 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab svcb01 3600 IN SVCB 100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345" ipv4hint="1.2.3.4,4.3.2.1" ech="abcd" ipv6hint="1::2,3::4" key12345="foo" +svcb02 3600 IN SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb03 3600 IN SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb04 3600 IN SVCB 16 foo.example.org. dohpath="/dns-query{?dns}" +svcb05 3600 IN SVCB 16 foo.example.org. ohttp t 301 IN A 73.80.65.49 tlsa1 3600 IN TLSA 3 1 1 a9cdf989b504fe5dca90c0d2167b6550570734f7c763e09fdf88904e06157065 tlsa2 3600 IN TLSA 1 0 1 efddf0d915c7bdc5782c0881e1b2a95ad099fbdd06d7b1f77982d9364338d955 diff --git a/tests/example4.good b/tests/example4.good index 264ccb28..96b48dc3 100644 --- a/tests/example4.good +++ b/tests/example4.good @@ -134,6 +134,10 @@ srv01 3600 IN SRV 0 0 0 . srv02 3600 IN SRV 65535 65535 65535 old-slow-box.example.com. sshfp1 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab svcb01 3600 IN SVCB 100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345" ipv4hint="1.2.3.4,4.3.2.1" ech="abcd" ipv6hint="1::2,3::4" key12345="foo" +svcb02 3600 IN SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb03 3600 IN SVCB 16 foo.example.org. alpn="foo\\,bar,h2" +svcb04 3600 IN SVCB 16 foo.example.org. dohpath="/dns-query{?dns}" +svcb05 3600 IN SVCB 16 foo.example.org. ohttp t 301 IN A 73.80.65.49 tlsa1 3600 IN TLSA 3 1 1 a9cdf989b504fe5dca90c0d2167b6550570734f7c763e09fdf88904e06157065 tlsa2 3600 IN TLSA 1 0 1 efddf0d915c7bdc5782c0881e1b2a95ad099fbdd06d7b1f77982d9364338d955