From e3b485213d06a5d9a07650174a2be9e20cb39e57 Mon Sep 17 00:00:00 2001 From: Kasumi Hanazuki Date: Fri, 24 Nov 2023 10:42:02 +0900 Subject: [PATCH] [ruby/resolv] Implement dohpath SvcParam (https://github.com/ruby/resolv/pull/33) * Implement dohpath SvcParam [RFC 9461] This patch implements "dohpath" SvcParam proposed in [draft-ietf-add-svcb-dns-08]. This parameter specifies a URI template for the :path used in DNS-over-HTTPS requests. "dohpath" is employed by [DDR], also a to-be-published Proposed Standard that specifies how to upgrade DNS transport to a more secure one, i.d., DNS-over-TLS or DNS-over-HTTPS. DDR is deployed in the public DNS resolvers including Cloudflare DNS, Google Public DNS, and Quad9. [RFC 9461]: https://datatracker.ietf.org/doc/rfc9461/ [DDR]: https://datatracker.ietf.org/doc/draft-ietf-add-ddr/ https://github.com/ruby/resolv/commit/da9c023539 Co-authored-by: Sorah Fukumori --- lib/resolv.rb | 29 +++++++++++++++++++++++++++++ test/resolv/test_svcb_https.rb | 29 ++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/resolv.rb b/lib/resolv.rb index 6fe9822c32..9e8335389a 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -2027,6 +2027,35 @@ class Resolv end end + ## + # "dohpath" SvcParam -- DNS over HTTPS path template [RFC9461] + + class DoHPath < SvcParam + KeyName = :dohpath + KeyNumber = 7 + ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc: + + ## + # URI template for DoH queries. + + attr_reader :template + + ## + # Initialize "dohpath" ScvParam. + + def initialize(template) + @template = template.encode('utf-8') + end + + def encode(msg) # :nodoc: + msg.put_bytes(@template) + end + + def self.decode(msg) # :nodoc: + template = msg.get_bytes.force_encoding('utf-8') + return self.new(template) + end + end end ## diff --git a/test/resolv/test_svcb_https.rb b/test/resolv/test_svcb_https.rb index 9b8b5769f6..5dc3163d9e 100644 --- a/test/resolv/test_svcb_https.rb +++ b/test/resolv/test_svcb_https.rb @@ -83,7 +83,6 @@ class TestResolvSvcbHttps < Test::Unit::TestCase assert_equal expected, msg.encode end - ## Test vectors from [RFC9460] def test_alias_mode @@ -201,4 +200,32 @@ class TestResolvSvcbHttps < Test::Unit::TestCase assert_equal wire, msg.encode end + + ## For [RFC9461] + + def test_dohpath + wire = wrap_rdata 64, 1, "\x00\x01\x03one\x03one\x03one\x03one\x00" + + "\x00\x01\x00\x03\x02h2" + + "\x00\x03\x00\x02\x01\xbb" + + "\x00\x04\x00\x08\x01\x01\x01\x01\x01\x00\x00\x01" + + "\x00\x06\x00\x20" + + ("\x26\x06\x47\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11" + + "\x26\x06\x47\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01") + + "\x00\x07\x00\x10/dns-query{?dns}" + msg = Resolv::DNS::Message.decode(wire) + _, _, rr = msg.answer.first + + assert_equal 1, rr.priority + assert_equal Resolv::DNS::Name.create('one.one.one.one.'), rr.target + assert_equal 5, rr.params.count + assert_equal ['h2'], rr.params[:alpn].protocol_ids + assert_equal 443, rr.params[:port].port + assert_equal [Resolv::IPv4.create('1.1.1.1'), Resolv::IPv4.create('1.0.0.1')], + rr.params[:ipv4hint].addresses + assert_equal [Resolv::IPv6.create('2606:4700:4700::1111'), Resolv::IPv6.create('2606:4700:4700::1001')], + rr.params[:ipv6hint].addresses + assert_equal '/dns-query{?dns}', rr.params[:dohpath].template + + assert_equal wire, msg.encode + end end