From 0f0259e0c058b6b0708f152b7deed4ebcd3b70a5 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Mon, 28 Apr 2025 23:51:41 +0200 Subject: [PATCH] Support new SVCB parameters: ohttp, dohpath, tls-supported-groups Signed-off-by: Chris Hofstaedtler --- modules/tinydnsbackend/data | 2 + modules/tinydnsbackend/data.cdb | Bin 1357024 -> 1357218 bytes pdns/dnsparser.cc | 22 +++- pdns/dnswriter.cc | 9 ++ pdns/rcpgenerator.cc | 55 +++++++- pdns/svc-records.cc | 25 +++- pdns/svc-records.hh | 14 +- pdns/test-dnsrecords_cc.cc | 6 + pdns/test-dnswriter_cc.cc | 99 ++++++++++++-- pdns/test-rcpgenerator_cc.cc | 122 ++++++++++++++++++ pdns/test-svc_records_cc.cc | 92 ++++++++++--- .../tinydns-data-check/expected_result | 6 +- .../tests/svcb-servicemode/expected_result | 2 + .../svcb-servicemode/expected_result.dnssec | 2 + regression-tests/zones/example.com | 2 + 15 files changed, 420 insertions(+), 38 deletions(-) diff --git a/modules/tinydnsbackend/data b/modules/tinydnsbackend/data index 4e683714b9..b901b72757 100644 --- a/modules/tinydnsbackend/data +++ b/modules/tinydnsbackend/data @@ -20110,6 +20110,8 @@ :bar.svcb.example.com:64:\000\001\000\000\001\000\003\002h2:120 :bar.svcb.example.com:64:\000\003\000\000\001\000\003\002h3\000\003\000\002\005\334:120 :bar.svcb.example.com:64:\000\004\000\000\001\000\003\002h3\000\003\000\002\005\335:120 +:bar.svcb.example.com:64:\000\005\000\000\002\000\000\000\003\000\002\037D\000\007\000\020/dns-query{?dns}\000\010\000\000\000\011\000\004\000\035\000\027:120 +:bar.svcb.example.com:64:\000\006\000\003\345\000\006quoted\003\346\000\003foo\003\347\000\003bar:120 :baz.svcb.example.com:64:\000\000\004foo1\004svcb\007example\003net\000:120 :dsdelegation.example.com:43:m\341\010\001\312\361\352\256\315\253\347afpx\217\220\042EK\365\375\237\332:120 :escapedtext.example.com:16:\005begin\022the\040\042middle\042\040p\134art\007the\040end:120 diff --git a/modules/tinydnsbackend/data.cdb b/modules/tinydnsbackend/data.cdb index a65f96efaae52a351d3996410201efb4d7cb766a..5fe831147baf90a72ab8d6bd93bdc55d2df1a416 100644 GIT binary patch delta 5656 zc-m!G3s_BA`(JzQ(>c|t_7#6k#x$NEp}V!#Lv_lFNk1H60oy>7s*9jFgZ< zB(mI!37H`w6yuh@gvo^5>KV*`?X|Yg_xz{lSd%I}vd#!02Hcl>na)lo4bE!l+3@vDQ+c%xwg)SlNgdK!Re+bUxdj z&PO;2V7oH!Dp2O`)b{bFw)iE*rtShERM=Y}iWGh=7|DcbfIt}e3>JtIwZjCkK}k4T zAV*R;hWcX+G(o^*8ecn&&IgAHgn4kdK$u1>5=ak}E*HQtW!)<3&yEv_0)>eJIHl}s zG73bBkaWr@c$+}Z*e6RMw;^DcK#rs`R{%?u1^elIM1erM-*kkoi#aBMY{f371qPQ2 z?qyDI&i~}A~rcF<2U~Qwy@D-h}e5We$p00~wM52V7 zRs`nF}VH)8q5``i4xlIo ziRA1fQZX;=&_#K^h8z+JsrO*i!W2TDaHk5{nl;9i@6et82P=Cx~;x~er6(W^x zl}PV*EXBfgB9Ss8S)>wf6bW-NT_j4Fwo&FjJLm>JIU*=0M?{r~DHO?lFFhuLTZ(;} z`XkO$g<>v=xJQi2nNTSLZi(c+2i&EMf@>(lfI8KFB7!(&;WH7$D~VrFMZ`BW4z`Ho zI#zxV!G5J6R-)Z+DG`Ehw$z5AM0z2j4Yrm0AM8W}LR=;F`bf0tyd?4*@aZZMC7OIC z+7rDbvQc3_i4@ZGjYO2m9wd>oEgdEihLyn*>3-Aq5>cjU5}g-kNTe6UITA1`0hRM5 za$Ve(NaQ{@Etly1kCq7YrWgr4QwmLx=Bn$5=b%dZRV=uk zG7ou1nZ`6x1p=BW!jBT^i2#iZ%9MSqjWU_=;brn1fURY4M3J(sOc=$u$mCXJcaRC= zY!8{7d6PGtuk0$5BM`gGq&EV3$>iRL^plAaJ^?aq&LElg!Z4Y1fADCT6b_AJX#o5| zrb9c)04G5S;{XXF`RU(3-&k`C}xk9E=uaecER1IFNmBGv1~N=) z_&5iIjk~JTPEc$z+j4vx7*T9?=lGBCyS>Pr=Svv2(-B(6QIWrE14FaWeP`Ye!j-2` zYggV~3y0>TuRZuO4*Dk`ZBIVj62@;pi~IB8ENq{N>H~N`>kg^$9B8L?KDueX9<5p)7{jYT7d2{9gKzJ%jB!=|GH zTh*|@kU8tSjvcHCyC6f4k>9oovj7H{9^OgwErH?W$Dzf)F~D%VDz;rZ4(=ZpYZVND z!F!We{+G;usTrc?n$E9>z_5Ja^A=~If!Nm}m5O1*-JKILv_8W@Hp`gyv^Z({BPhKWCnEj{m z?ac*C1gr4xYkYt9z|k+p|F$|0Z*g~Kc&B(Q&8l-x-=%5(S;9ef+_@y%fBM&~&~^F+ zm$t{|MTe`nG)p$1^GlpJ{l}0wakyoqqoW$_t;o|-XEf1f{{?xd^fns24QuYT!aIx!{k!Ne#(PJyQ>+2OfB(c0 zOjWT$MT<2`1(_RGj>TN!Qycos!AYClFU8__tD&y@{8@c~NwvjLBW zYb=OuTtoBRUc>$Cvq*`9tsVv9fP=SR&auGN@>d6Rt5A;Wr{JSYtj&|L9^@LfF&y-d zUHzr*^U9v~L)-C?$k*QxWn1pK13SaoE?7SZ*HIO}zViy4_F4A6hhN}&418ISeK_rW zuljk7|8v9g`BzUHwdn6_PdU_ntYAyc7Q4>W?zD&ER29?qpwJv4TyK2@zxG0J6c3-h72Q81l-OEt z+0TJlJFb@ZJcM#i3+}Ar4ZP*-GaqN%8KDQWFMaE$J<1X6brjW?3WKbmcaFJBxv*H+ zh##DD4WJUKNxYcC!jR3#Sr*+bVB|qG$U&T>!_WTR?ZqH_ zXulCP_7d%MY|HLX?*@O-rk#E)rn2sOx1cG9Rd?7#ae}3lE}sJlo0p8_0)p z4m&YMZJ+zya2>HHD)yw8FJ{~W#BQ|?5%~=|3SriH2k%= zM+eP2(c8bUw2lc|IFQ%s^6g3mzt`r>Z)HPlx2>q;qd3SFc0Gx-?WIAGEy?=y)#fG* zWY~r@wI`l*kalrQBTDj>=0WzGPlDR}N!?lfFZiRXDBroE@2OAc)mxgtGWFFb;H52(l7`Iq@c95(pUlV38*n$+78*GQ)=FVpQSo$ zt0!2%i}q2S{z4f!Qni)7a4QGOUuIa&PO+k$np+?(YA?)M%Yo}hx30MGZwU>Qa$Fhq)^PJY7*J(9F(hM?Ir@Rr z$X-`JsLZ)Fk__i1n@eh>=mFR8XHj+5)S=faG@v@nGFQaCqTmTkwYqxm<2`M3#BRVn zQ++8m`Q49}#9oU(sH-zFZvMctRH3Ygl9RJ%5iaen|F&7V7d7DSff?S7ij6U17sY)l z)}cp#ODR_DUn#028?5AKR&Zo0ik9R97OXZ!6@HY1?8HJ>GYWT-wHns#(|-lI?PdHm zn~#d!<(aIoFP#H*J?vdZPO<`Z1s7JnGxzY4m$jxhZs@*6Er((6~^etSOS!Ma_q$yeStsAhtE4zia|s$|bhmM1_s zCI>l($b&5Omkx2@Wn`Do_Ybw||1dMZC(W~WT9c;S^*{#D>!}Xg{)p|Kug2|~UG*eE4kV`}#cgPhya}QlE HlqL9o>o2d% delta 5626 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 bfepXwkh3A2x)hUt_f8>IH=Makmf-&YQ&hB_ diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 8d9e2968d7..4c70d8052d 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -639,9 +639,10 @@ void PacketReader::xfrSvcParamKeyVals(set &kvs) { kvs.insert(SvcParam(key, std::move(alpns))); break; } + case SvcParam::ohttp: case SvcParam::no_default_alpn: { if (len != 0) { - throw std::out_of_range("invalid length for no-default-alpn"); + throw std::out_of_range("invalid length for " + SvcParam::keyToString(key)); } kvs.insert(SvcParam(key)); break; @@ -655,7 +656,7 @@ void PacketReader::xfrSvcParamKeyVals(set &kvs) { kvs.insert(SvcParam(key, port)); break; } - case SvcParam::ipv4hint: /* fall-through */ + case SvcParam::ipv4hint: case SvcParam::ipv6hint: { size_t addrLen = (key == SvcParam::ipv4hint ? 4 : 16); if (len % addrLen != 0) { @@ -685,6 +686,23 @@ void PacketReader::xfrSvcParamKeyVals(set &kvs) { kvs.insert(SvcParam(key, blob)); break; } + case SvcParam::tls_supported_groups: { + if (len % 2 != 0) { + throw std::out_of_range("invalid length for " + SvcParam::keyToString(key)); + } + vector groups; + groups.reserve(len / 2); + auto stop = d_pos + len; + while (d_pos < stop) + { + uint16_t group = 0; + xfr16BitInt(group); + groups.push_back(group); + } + auto param = SvcParam(key, std::move(groups)); + kvs.insert(std::move(param)); + break; + } default: { std::string blob; blob.reserve(len); diff --git a/pdns/dnswriter.cc b/pdns/dnswriter.cc index 495c17146d..5447c40728 100644 --- a/pdns/dnswriter.cc +++ b/pdns/dnswriter.cc @@ -441,6 +441,15 @@ template void GenericDNSPacketWriter::xfrSvcPara xfr16BitInt(param.getECH().size()); // size xfrBlobNoSpaces(param.getECH()); break; + case SvcParam::ohttp: + xfr16BitInt(0); // no size + break; + case SvcParam::tls_supported_groups: + xfr16BitInt(2 * param.getTLSSupportedGroups().size()); // size + for (const auto& group: param.getTLSSupportedGroups()) { + xfr16BitInt(group); + } + break; default: xfr16BitInt(param.getValue().size()); xfrBlob(param.getValue()); diff --git a/pdns/rcpgenerator.cc b/pdns/rcpgenerator.cc index 7578730748..7bbbd62e23 100644 --- a/pdns/rcpgenerator.cc +++ b/pdns/rcpgenerator.cc @@ -382,6 +382,7 @@ void RecordTextReader::xfrSvcParamKeyVals(set& val) // NOLINT(readabil switch (key) { case SvcParam::no_default_alpn: + case SvcParam::ohttp: if (d_pos != d_end && d_string.at(d_pos) != ' ') { throw RecordTextException(k + " key can not have values"); } @@ -535,6 +536,40 @@ void RecordTextReader::xfrSvcParamKeyVals(set& val) // NOLINT(readabil val.insert(SvcParam(key, value)); break; } + case SvcParam::tls_supported_groups: { + string string_value; + xfrRFC1035CharString(string_value); + if (string_value.empty()) { + throw RecordTextException("Value is required for SVC Param " + k); + } + + vector parts; + stringtok(parts, string_value, ","); + + vector values; + values.reserve(parts.size()); + for (const auto& part : parts) { + uint16_t int_part{0}; + try { + pdns::checked_stoi_into(int_part, part); + } catch (const std::invalid_argument&) { + throw RecordTextException("Value in invalid format for SVC Param " + k); + } + values.emplace_back(int_part); + } + + val.insert(SvcParam(key, std::move(values))); + break; + } + case SvcParam::dohpath: { + string value; + xfrRFC1035CharString(value); + if (value.empty()) { + throw RecordTextException("Value is required for SVC Param " + k); + } + val.insert(SvcParam(key, value)); + break; + } default: { string value; xfrRFC1035CharString(value); @@ -950,7 +985,7 @@ void RecordTextWriter::xfrSvcParamKeyVals(const set& val) { d_string.append(1, ' '); d_string.append(SvcParam::keyToString(param.getKey())); - if (param.getKey() != SvcParam::no_default_alpn) { + if (param.getKey() != SvcParam::no_default_alpn && param.getKey() != SvcParam::ohttp) { d_string.append(1, '='); } @@ -995,6 +1030,24 @@ void RecordTextWriter::xfrSvcParamKeyVals(const set& val) { d_string = str + '"' + d_string + '"'; break; } + case SvcParam::ohttp: + // no value + break; + case SvcParam::tls_supported_groups: { + auto str = d_string; + d_string.clear(); + bool first = true; + for (auto const &group: param.getTLSSupportedGroups()) { + if (!first) { + str += ','; + } + str += std::to_string(group); + first = false; + } + d_string = str; + break; + } + case SvcParam::dohpath: default: auto str = d_string; d_string.clear(); diff --git a/pdns/svc-records.cc b/pdns/svc-records.cc index 73b112f470..5e676b2f86 100644 --- a/pdns/svc-records.cc +++ b/pdns/svc-records.cc @@ -30,7 +30,10 @@ const std::map SvcParam::SvcParams = { {"port", SvcParam::SvcParamKey::port}, {"ipv4hint", SvcParam::SvcParamKey::ipv4hint}, {"ech", SvcParam::SvcParamKey::ech}, - {"ipv6hint", SvcParam::SvcParamKey::ipv6hint} + {"ipv6hint", SvcParam::SvcParamKey::ipv6hint}, + {"dohpath", SvcParam::SvcParamKey::dohpath}, + {"ohttp", SvcParam::SvcParamKey::ohttp}, + {"tls-supported-groups", SvcParam::SvcParamKey::tls_supported_groups}, }; SvcParam::SvcParamKey SvcParam::keyFromString(const std::string& k) { @@ -65,14 +68,14 @@ std::string SvcParam::keyToString(const SvcParam::SvcParamKey& k) { SvcParam::SvcParam(const SvcParamKey &key) { d_key = key; - if (d_key != SvcParamKey::no_default_alpn) { + if (d_key != SvcParamKey::no_default_alpn && d_key != SvcParamKey::ohttp) { throw std::invalid_argument("can not create non-empty SvcParam for key '" + keyToString(key) + "'"); } } SvcParam::SvcParam(const SvcParamKey &key, const std::string &value) { d_key = key; - if (d_key != SvcParamKey::ech && d_key < 7) { + if (d_key != SvcParamKey::ech && d_key != SvcParamKey::dohpath && d_key < 10) { throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with a string value"); } if (d_key == SvcParamKey::ech) { @@ -130,6 +133,13 @@ SvcParam::SvcParam(const SvcParamKey &key, std::vector &&value) { d_ipHints = std::move(value); } +SvcParam::SvcParam(const SvcParamKey &key, std::vector &&value) : d_key(key) { + if (d_key != SvcParamKey::tls_supported_groups) { + throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with a uint16 value-vector"); + } + d_tls_supported_groups = std::move(value); +} + SvcParam::SvcParam(const SvcParamKey &key, const uint16_t value) { d_key = key; if (d_key != SvcParamKey::port) { @@ -179,8 +189,15 @@ const std::string& SvcParam::getECH() const { } const std::string& SvcParam::getValue() const { - if (d_key < 7) { + if (d_key != SvcParamKey::dohpath && d_key < 10) { throw std::invalid_argument("getValue called for non-single value key '" + keyToString(d_key) + "'"); } return d_value; } + +const std::vector& SvcParam::getTLSSupportedGroups() const { + if (d_key != SvcParam::tls_supported_groups) { + throw std::invalid_argument("getTLSSupportedGroups called for non-tls-supported-groups key '" + keyToString(d_key) + "'"); + } + return d_tls_supported_groups; +} diff --git a/pdns/svc-records.hh b/pdns/svc-records.hh index bd5530cef0..eb39be8a61 100644 --- a/pdns/svc-records.hh +++ b/pdns/svc-records.hh @@ -28,7 +28,7 @@ class SvcParam { public: enum SvcParamKey: uint16_t { - // TODO link to IANA registry + // https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys /* When adding new values, you *must* update SvcParam::SvcParam(const std::string &key, const std::string &value) * in svc-record.cc with the new numbers */ @@ -38,7 +38,10 @@ class SvcParam { port = 3, ipv4hint = 4, ech = 5, - ipv6hint = 6 + ipv6hint = 6, + dohpath = 7, + ohttp = 8, + tls_supported_groups = 9, /* https://datatracker.ietf.org/doc/draft-ietf-tls-key-share-prediction/ */ }; //! empty Param, unusable @@ -59,9 +62,12 @@ class SvcParam { //! To create a multi-value SvcParam with key values (like mandatory) SvcParam(const SvcParamKey &key, std::set &&value); - //! To create and ipv{4,6}hists SvcParam + //! To create an ipv{4,6}hists SvcParam SvcParam(const SvcParamKey &key, std::vector &&value); + //! To create a tls-supported-groups SvcParam + SvcParam(const SvcParamKey &key, std::vector &&value); + //! To create a port SvcParam SvcParam(const SvcParamKey &key, const uint16_t value); @@ -91,6 +97,7 @@ class SvcParam { const std::set& getMandatory() const; const std::string& getECH() const; const std::string& getValue() const; + const std::vector& getTLSSupportedGroups() const; bool getAutoHint() const { return d_autohint; }; void setAutoHint(const bool value) { d_autohint = value; }; @@ -103,6 +110,7 @@ class SvcParam { std::set d_mandatory; // For mandatory std::vector d_ipHints; // For ipv{6,4}hints std::string d_ech; // For Encrypted Client Hello + std::vector d_tls_supported_groups; // For tls-supported-groups uint16_t d_port{0}; // For port // Set to true if we encountered an "auto" field in hints diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index d787e86331..65204bff1a 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -259,6 +259,12 @@ BOOST_AUTO_TEST_CASE(test_record_types) { (CASE_L(QType::SVCB, R"XXX(16 foo.example.org. alpn=f\\\092oo\092,bar,h2)XXX", R"XXX(16 foo.example.org. alpn=f\\\\oo\\,bar,h2)XXX", "\x00\x10\3foo\7example\3org\x00\x00\x01\x00\x0c\x08\x66\\oo,bar\x02h2")) // END SVCB draft test vectors + (CASE_S(QType::SVCB, "1 foo.powerdns.org. dohpath=\"path\"", "\0\x01\3foo\x08powerdns\x03org\x00\x00\x07\0\x04path")) + (CASE_L(QType::SVCB, "1 foo.powerdns.org. dohpath=/q{?dns}", "1 foo.powerdns.org. dohpath=\"/q{?dns}\"", "\0\x01\3foo\x08powerdns\x03org\x00\x00\x07\0\x08/q{?dns}")) + (CASE_S(QType::SVCB, "1 foo.powerdns.org. ohttp", "\0\x01\3foo\x08powerdns\x03org\x00\x00\x08\x00\x00")) + (CASE_S(QType::SVCB, "1 foo.powerdns.org. tls-supported-groups=29,23", "\0\x01\3foo\x08powerdns\x03org\x00\x00\x09\x00\x04\x00\x1d\x00\x17")) + (CASE_S(QType::SVCB, "1 foo.powerdns.org. port=8004 tls-supported-groups=29,23", "\0\x01\3foo\x08powerdns\x03org\x00\x00\x03\x00\x02\x1f\x44\0\x09\x00\x04\x00\x1d\x00\x17")) + (CASE_S(QType::HHIT, "1234abcd", "\xd7\x6d\xf8\x69\xb7\x1d")) (CASE_L(QType::HHIT, "1234 abcd", "1234abcd", "\xd7\x6d\xf8\x69\xb7\x1d")) (CASE_S(QType::BRID, "1234abcd", "\xd7\x6d\xf8\x69\xb7\x1d")) diff --git a/pdns/test-dnswriter_cc.cc b/pdns/test-dnswriter_cc.cc index b7cee5a0fb..94ed16699a 100644 --- a/pdns/test-dnswriter_cc.cc +++ b/pdns/test-dnswriter_cc.cc @@ -248,6 +248,84 @@ BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ipv6hint) { 32,1,13,184,0,0,0,0,0,0,0,0,0,0,0,2})); } +BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_dohpath) { + DNSName name("powerdns.com."); + vector packet; + DNSPacketWriter pwR(packet, name, QType::SVCB, QClass::IN, 0); + pwR.getHeader()->qr = 1; + + set params({SvcParam(SvcParam::dohpath, "a very bogus dohpath value")}); + + pwR.startRecord(name, QType::SVCB); + pwR.commit(); + auto start = pwR.getContent().size(); + + pwR.xfrSvcParamKeyVals(params); + pwR.commit(); + auto cit = pwR.getContent().begin(); + for (size_t i = 0; i({0, 7, 0, 26, + 'a',' ','v','e','r','y',' ','b','o','g','u','s',' ', + 'd','o','h','p','a','t','h',' ','v','a','l','u','e' + })); +} + +BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ohttp) { + DNSName name("powerdns.com."); + vector packet; + DNSPacketWriter pwR(packet, name, QType::SVCB, QClass::IN, 0); + pwR.getHeader()->qr = 1; + + set params({SvcParam(SvcParam::ohttp)}); + + pwR.startRecord(name, QType::SVCB); + pwR.commit(); + auto start = pwR.getContent().size(); + + pwR.xfrSvcParamKeyVals(params); + pwR.commit(); + auto cit = pwR.getContent().begin(); + for (size_t i = 0; i({0, 8, 0, 0})); +} + +BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_tls_supported_groups) { + DNSName name("powerdns.com."); + vector packet; + DNSPacketWriter pwR(packet, name, QType::SVCB, QClass::IN, 0); + pwR.getHeader()->qr = 1; + + vector groups({29, 23}); + set params({SvcParam(SvcParam::tls_supported_groups, std::move(groups))}); + + pwR.startRecord(name, QType::SVCB); + pwR.commit(); + auto start = pwR.getContent().size(); + + pwR.xfrSvcParamKeyVals(params); + pwR.commit(); + auto cit = pwR.getContent().begin(); + for (size_t i = 0; i content(cit, pwR.getContent().end()); + BOOST_CHECK(content == vector({ + 0, 9, // key 9 + 0, 4, // size + 0, 0x1d, // 29 + 0, 0x17, // 23 + })); +} + BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_generic) { DNSName name("powerdns.com."); vector packet; @@ -263,11 +341,12 @@ BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_generic) { pwR.xfrSvcParamKeyVals(params); pwR.commit(); auto cit = pwR.getContent().begin(); - for (size_t i = 0; i c(cit, pwR.getContent().end()); - BOOST_CHECK(c == vector({2,154,0,11, + vector content(cit, pwR.getContent().end()); + BOOST_CHECK(content == vector({2,154,0,11, 'm','y','c','o','o','l','v','a','l','u','e' })); } @@ -289,11 +368,12 @@ BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_multiple) { pwR.xfrSvcParamKeyVals(params); pwR.commit(); auto cit = pwR.getContent().begin(); - for (size_t i = 0; i c(cit, pwR.getContent().end()); - BOOST_CHECK(c == vector({ + vector content(cit, pwR.getContent().end()); + BOOST_CHECK(content == vector({ 0,1,0,10,2,'h','2',3,'h','2','c',2,'h','3', // alpn 0,3,0,2,0,53, // port 0,6,0,32, // ipv6 @@ -317,11 +397,12 @@ BOOST_AUTO_TEST_CASE(test_NodeOrLocatorID) { writer.xfrNodeOrLocatorID(in); writer.commit(); auto cit = writer.getContent().begin(); - for (size_t i = 0; i c(cit, writer.getContent().end()); - BOOST_CHECK(c == vector({ + vector content(cit, writer.getContent().end()); + BOOST_CHECK(content == vector({ 0, 0, 0, 0, 0, 0, 0, 1})); } diff --git a/pdns/test-rcpgenerator_cc.cc b/pdns/test-rcpgenerator_cc.cc index 02960d9fcc..1d58f0ca7d 100644 --- a/pdns/test-rcpgenerator_cc.cc +++ b/pdns/test-rcpgenerator_cc.cc @@ -102,6 +102,46 @@ BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_alpn) { BOOST_CHECK_THROW(rtr7.xfrSvcParamKeyVals(v), RecordTextException); } +BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_dohpath) { + string source("dohpath=\"foo/bar\""); + set vals; + RecordTextReader(source).xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 1U); + BOOST_CHECK_EQUAL(vals.begin()->getKey(), SvcParam::dohpath); + BOOST_CHECK_EQUAL(vals.begin()->getValue(), "foo/bar"); + + // Check the writer + string target; + RecordTextWriter rtw(target); + rtw.xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(target, source); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("dohpath=").xfrSvcParamKeyVals(vals), RecordTextException); + + // Generic + vals.clear(); + RecordTextReader ("key7=\"foo/bar\"").xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 1U); + BOOST_CHECK_EQUAL(vals.begin()->getKey(), SvcParam::dohpath); + BOOST_CHECK_EQUAL(vals.begin()->getValue(), "foo/bar"); + + vals.clear(); + RecordTextReader ("key7=foo/bar").xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 1U); + BOOST_CHECK_EQUAL(vals.begin()->getKey(), SvcParam::dohpath); + BOOST_CHECK_EQUAL(vals.begin()->getValue(), "foo/bar"); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key7").xfrSvcParamKeyVals(vals), RecordTextException); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key7=").xfrSvcParamKeyVals(vals), RecordTextException); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key7=\"\"").xfrSvcParamKeyVals(vals), RecordTextException); +} + BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_mandatory) { string source("mandatory=alpn"); RecordTextReader rtr(source); @@ -399,6 +439,88 @@ BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ipv6hint) { BOOST_CHECK_THROW(rtr9.xfrSvcParamKeyVals(v), RecordTextException); } +BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_tls_supported_groups) { + string source("tls-supported-groups=29,23"); + std::vector expected_value{29, 23}; + set vals; + RecordTextReader (source).xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 1U); + BOOST_CHECK_EQUAL(vals.begin()->getKey(), SvcParam::tls_supported_groups); + BOOST_CHECK(vals.begin()->getTLSSupportedGroups() == expected_value); + + // Check the writer + string target; + RecordTextWriter(target).xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(target, source); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("tls-supported-groups=").xfrSvcParamKeyVals(vals), RecordTextException); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("tls-supported-groups=foo,bar").xfrSvcParamKeyVals(vals), RecordTextException); + + // Generic + vals.clear(); + RecordTextReader ("key9=29,23").xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 1U); + BOOST_CHECK_EQUAL(vals.begin()->getKey(), SvcParam::tls_supported_groups); + BOOST_CHECK(vals.begin()->getTLSSupportedGroups() == expected_value); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key9").xfrSvcParamKeyVals(vals), RecordTextException); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key9=").xfrSvcParamKeyVals(vals), RecordTextException); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key9=\"\"").xfrSvcParamKeyVals(vals), RecordTextException); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key9=foo,bar").xfrSvcParamKeyVals(vals), RecordTextException); +} + +BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ohttp) { + string source("ohttp"); + set vals; + RecordTextReader(source).xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 1U); + BOOST_CHECK(vals.begin()->getKey() == SvcParam::ohttp); + + // Check the writer + string target; + RecordTextWriter(target).xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(target, source); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("ohttp=").xfrSvcParamKeyVals(vals), RecordTextException); + + // Generic + vals.clear(); + RecordTextReader("key8").xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 1U); + BOOST_CHECK_EQUAL(vals.begin()->getKey(), SvcParam::ohttp); + BOOST_CHECK(vals.begin()->getKey() == SvcParam::SvcParamKey::ohttp); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key8=").xfrSvcParamKeyVals(vals), RecordTextException); + + vals.clear(); + RecordTextReader("key8 ipv4hint=1.2.3.4").xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 2U); + BOOST_CHECK_EQUAL(std::count_if(vals.begin(), vals.end(), [](const SvcParam& param) { return param.getKey() == SvcParam::ohttp; }), 1); + + vals.clear(); + RecordTextReader("ipv4hint=1.2.3.4 key8").xfrSvcParamKeyVals(vals); + BOOST_CHECK_EQUAL(vals.size(), 2U); + BOOST_CHECK_EQUAL(std::count_if(vals.begin(), vals.end(), [](const SvcParam& param) { return param.getKey() == SvcParam::ohttp; }), 1); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key8=port=123 ipv4hint=1.2.3.4").xfrSvcParamKeyVals(vals), RecordTextException); + + vals.clear(); + BOOST_CHECK_THROW(RecordTextReader("key8=port=123").xfrSvcParamKeyVals(vals), RecordTextException); +} + BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_port) { string source("port=53"); RecordTextReader rtr(source); diff --git a/pdns/test-svc_records_cc.cc b/pdns/test-svc_records_cc.cc index 920b1083a6..a7440f1a4a 100644 --- a/pdns/test-svc_records_cc.cc +++ b/pdns/test-svc_records_cc.cc @@ -46,6 +46,18 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_keyFromString) { BOOST_CHECK(k == 6); BOOST_CHECK(k == SvcParam::ipv6hint); + k = SvcParam::keyFromString("dohpath"); + BOOST_CHECK(k == 7); + BOOST_CHECK(k == SvcParam::dohpath); + + k = SvcParam::keyFromString("ohttp"); + BOOST_CHECK(k == 8); + BOOST_CHECK(k == SvcParam::ohttp); + + k = SvcParam::keyFromString("tls-supported-groups"); + BOOST_CHECK(k == 9); + BOOST_CHECK(k == SvcParam::tls_supported_groups); + k = SvcParam::keyFromString("key0"); BOOST_CHECK(k == 0); BOOST_CHECK(k == SvcParam::mandatory); @@ -67,7 +79,10 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_keyToString) { BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::ipv4hint), "ipv4hint"); BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::ech), "ech"); BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::ipv6hint), "ipv6hint"); - BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::SvcParamKey(7)), "key7"); + BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::dohpath), "dohpath"); + BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::ohttp), "ohttp"); + BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::tls_supported_groups), "tls-supported-groups"); + BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::SvcParamKey(10)), "key10"); BOOST_CHECK_EQUAL(SvcParam::keyToString(SvcParam::SvcParamKey(666)), "key666"); } @@ -87,6 +102,8 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_value) { BOOST_CHECK_THROW(SvcParam(SvcParam::port, val), std::invalid_argument); BOOST_CHECK_THROW(SvcParam(SvcParam::ipv4hint, val), std::invalid_argument); BOOST_CHECK_THROW(SvcParam(SvcParam::ipv6hint, val), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ohttp, val), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::tls_supported_groups, val), std::invalid_argument); SvcParam param(SvcParam::keyFromString("no-default-alpn")); BOOST_CHECK_NO_THROW(param = SvcParam(SvcParam::ech, base64val)); @@ -96,6 +113,7 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_value) { BOOST_CHECK_THROW(param.getIPHints(), std::invalid_argument); BOOST_CHECK_THROW(param.getMandatory(), std::invalid_argument); BOOST_CHECK_THROW(param.getPort(), std::invalid_argument); + BOOST_CHECK_THROW(param.getTLSSupportedGroups(), std::invalid_argument); // TODO test bad base64 value // BOOST_CHECK_THROW(SvcParam(SvcParam::ech, val), std::invalid_argument); @@ -111,20 +129,24 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_value) { BOOST_CHECK_THROW(param.getIPHints(), std::invalid_argument); BOOST_CHECK_THROW(param.getMandatory(), std::invalid_argument); BOOST_CHECK_THROW(param.getPort(), std::invalid_argument); + BOOST_CHECK_THROW(param.getTLSSupportedGroups(), std::invalid_argument); } BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_set_string_value) { set val({"foo", "bar", "baz"}); - BOOST_CHECK_THROW(SvcParam(SvcParam::alpn, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::no_default_alpn, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::port, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::ipv4hint, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::ech, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::ipv6hint, std::move(val)), std::invalid_argument); - - set mandatoryVal = {"alpn", "key666"}; - set mandatoryExpected = {SvcParam::alpn, (SvcParam::SvcParamKey)666}; + BOOST_CHECK_THROW(SvcParam(SvcParam::alpn, set(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::no_default_alpn, set(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::port, set(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ipv4hint, set(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ech, set(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ipv6hint, set(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::dohpath, set(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ohttp, set(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::tls_supported_groups, set(val)), std::invalid_argument); + + set mandatoryVal = {"alpn", "ohttp", "key666"}; + set mandatoryExpected = {SvcParam::alpn, SvcParam::ohttp, (SvcParam::SvcParamKey)666}; SvcParam param(SvcParam::keyFromString("no-default-alpn")); BOOST_CHECK_NO_THROW(param = SvcParam(SvcParam::keyFromString("mandatory"), std::move(mandatoryVal))); @@ -135,18 +157,22 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_set_string_value) { BOOST_CHECK_THROW(param.getIPHints(), std::invalid_argument); BOOST_CHECK_THROW(param.getPort(), std::invalid_argument); BOOST_CHECK_THROW(param.getValue(), std::invalid_argument); + BOOST_CHECK_THROW(param.getTLSSupportedGroups(), std::invalid_argument); } BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_vector_string_value) { auto val = vector({"h3, h2"}); auto checkVal = val; - BOOST_CHECK_THROW(SvcParam(SvcParam::mandatory, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::no_default_alpn, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::port, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::ipv4hint, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::ech, std::move(val)), std::invalid_argument); - BOOST_CHECK_THROW(SvcParam(SvcParam::ipv6hint, std::move(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::mandatory, vector(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::no_default_alpn, vector(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::port, vector(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ipv4hint, vector(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ech, vector(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ipv6hint, vector(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::dohpath, vector(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ohttp, vector(val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::tls_supported_groups, vector(val)), std::invalid_argument); SvcParam param(SvcParam::keyFromString("no-default-alpn")); BOOST_CHECK_NO_THROW(param = SvcParam(SvcParam::keyFromString("alpn"), std::move(val))); @@ -158,6 +184,7 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_vector_string_value) { BOOST_CHECK_THROW(param.getIPHints(), std::invalid_argument); BOOST_CHECK_THROW(param.getPort(), std::invalid_argument); BOOST_CHECK_THROW(param.getValue(), std::invalid_argument); + BOOST_CHECK_THROW(param.getTLSSupportedGroups(), std::invalid_argument); } BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_set_comboaddress_value) { @@ -177,6 +204,9 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_set_comboaddress_value) { BOOST_CHECK_THROW(SvcParam(SvcParam::no_default_alpn, std::move(v4Val)), std::invalid_argument); BOOST_CHECK_THROW(SvcParam(SvcParam::port, std::move(v4Val)), std::invalid_argument); BOOST_CHECK_THROW(SvcParam(SvcParam::ech, std::move(v4Val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::dohpath, vector(v4Val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ohttp, vector(v4Val)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::tls_supported_groups, vector(v4Val)), std::invalid_argument); BOOST_CHECK_THROW(SvcParam(SvcParam::ipv6hint, std::move(v4Val)), std::invalid_argument); BOOST_CHECK_THROW(SvcParam(SvcParam::ipv4hint, std::move(v6Val)), std::invalid_argument); @@ -193,6 +223,7 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_set_comboaddress_value) { BOOST_CHECK_THROW(param.getECH(), std::invalid_argument); BOOST_CHECK_THROW(param.getPort(), std::invalid_argument); BOOST_CHECK_THROW(param.getValue(), std::invalid_argument); + BOOST_CHECK_THROW(param.getTLSSupportedGroups(), std::invalid_argument); BOOST_CHECK_NO_THROW(param = SvcParam(SvcParam::ipv6hint, std::move(v6Val))); retval.clear(); @@ -203,6 +234,7 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_set_comboaddress_value) { BOOST_CHECK_THROW(param.getECH(), std::invalid_argument); BOOST_CHECK_THROW(param.getPort(), std::invalid_argument); BOOST_CHECK_THROW(param.getValue(), std::invalid_argument); + BOOST_CHECK_THROW(param.getTLSSupportedGroups(), std::invalid_argument); } BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_uint16_value) { @@ -214,6 +246,9 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_uint16_value) { BOOST_CHECK_THROW(SvcParam(SvcParam::ipv4hint, port), std::invalid_argument); BOOST_CHECK_THROW(SvcParam(SvcParam::ech, port), std::invalid_argument); BOOST_CHECK_THROW(SvcParam(SvcParam::ipv6hint, port), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::dohpath, port), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ohttp, port), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::tls_supported_groups, port), std::invalid_argument); SvcParam param(SvcParam::keyFromString("no-default-alpn")); BOOST_CHECK_NO_THROW(param = SvcParam(SvcParam::port, port)); @@ -223,6 +258,31 @@ BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_uint16_value) { BOOST_CHECK_THROW(param.getECH(), std::invalid_argument); BOOST_CHECK_THROW(param.getIPHints(), std::invalid_argument); BOOST_CHECK_THROW(param.getValue(), std::invalid_argument); + BOOST_CHECK_THROW(param.getTLSSupportedGroups(), std::invalid_argument); +} + +BOOST_AUTO_TEST_CASE(test_SvcParam_ctor_vector_uint16_value) { + vector groups({29, 23}); + auto checkVal = groups; + + BOOST_CHECK_THROW(SvcParam(SvcParam::mandatory, vector(groups)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::alpn, vector(groups)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::no_default_alpn, vector(groups)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ipv4hint, vector(groups)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ech, vector(groups)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ipv6hint, vector(groups)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::dohpath, vector(groups)), std::invalid_argument); + BOOST_CHECK_THROW(SvcParam(SvcParam::ohttp, vector(groups)), std::invalid_argument); + + SvcParam param(SvcParam::keyFromString("no-default-alpn")); + BOOST_CHECK_NO_THROW(param = SvcParam(SvcParam::tls_supported_groups, vector(groups))); + auto retval = param.getTLSSupportedGroups(); + BOOST_CHECK_EQUAL_COLLECTIONS(checkVal.begin(), checkVal.end(), retval.begin(), retval.end()); + BOOST_CHECK_THROW(param.getMandatory(), std::invalid_argument); + BOOST_CHECK_THROW(param.getALPN(), std::invalid_argument); + BOOST_CHECK_THROW(param.getECH(), std::invalid_argument); + BOOST_CHECK_THROW(param.getIPHints(), std::invalid_argument); + BOOST_CHECK_THROW(param.getValue(), std::invalid_argument); } BOOST_AUTO_TEST_SUITE_END() diff --git a/regression-tests.nobackend/tinydns-data-check/expected_result b/regression-tests.nobackend/tinydns-data-check/expected_result index c0711c41e1..58b9b2f924 100644 --- a/regression-tests.nobackend/tinydns-data-check/expected_result +++ b/regression-tests.nobackend/tinydns-data-check/expected_result @@ -1,4 +1,4 @@ -f3e86fd522b08d4812505da489ecb5b0 ../regression-tests/zones/example.com +196ff1338193d25caf18c4ad61620ed7 ../regression-tests/zones/example.com 5cce94d1d050925d3bb8c5271a10961b ../regression-tests/zones/test.com e5e3ee998d151fe194b98997eaa36c53 ../regression-tests/zones/test.dyndns dee3e8b568549d9450134b555ca73990 ../regression-tests/zones/sub.test.dyndns @@ -15,5 +15,5 @@ a98864b315f16bcf49ce577426063c42 ../regression-tests/zones/cdnskey-cds-test.com 9aeed2c26d0c3ba3baf22dfa9568c451 ../regression-tests/zones/2.0.192.in-addr.arpa 99c73e8b5db5781fec1ac3fa6a2662a9 ../regression-tests/zones/cryptokeys.org 1f9e19be0cff67330f3a0a5347654f91 ../regression-tests/zones/hiddencryptokeys.org -291489428c41bb9391e22bead5e94511 ../modules/tinydnsbackend/data -cac5364329a0c45f7ac4c8eeeb0cf774 ../modules/tinydnsbackend/data.cdb +c0c013171adc9e838fe0263150205406 ../modules/tinydnsbackend/data +979d7e1b1f025ce8964dc29f76723232 ../modules/tinydnsbackend/data.cdb diff --git a/regression-tests/tests/svcb-servicemode/expected_result b/regression-tests/tests/svcb-servicemode/expected_result index 3956637ce2..fe9acb1847 100644 --- a/regression-tests/tests/svcb-servicemode/expected_result +++ b/regression-tests/tests/svcb-servicemode/expected_result @@ -1,6 +1,8 @@ 0 bar.svcb.example.com. 120 IN SVCB 1 . alpn=h2 0 bar.svcb.example.com. 120 IN SVCB 3 . alpn=h3 port=1500 0 bar.svcb.example.com. 120 IN SVCB 4 . alpn=h3 port=1501 +0 bar.svcb.example.com. 120 IN SVCB 5 . no-default-alpn port=8004 dohpath="/dns-query{?dns}" ohttp tls-supported-groups=29,23 +0 bar.svcb.example.com. 120 IN SVCB 6 . key997="quoted" key998="foo" key999="bar" 2 . 32768 IN OPT 2 bar.svcb.example.com. 120 IN A 192.0.2.1 2 bar.svcb.example.com. 120 IN AAAA 2001:db8::3:1 diff --git a/regression-tests/tests/svcb-servicemode/expected_result.dnssec b/regression-tests/tests/svcb-servicemode/expected_result.dnssec index 666a28619e..ad3ce68521 100644 --- a/regression-tests/tests/svcb-servicemode/expected_result.dnssec +++ b/regression-tests/tests/svcb-servicemode/expected_result.dnssec @@ -2,6 +2,8 @@ 0 bar.svcb.example.com. 120 IN SVCB 1 . alpn=h2 0 bar.svcb.example.com. 120 IN SVCB 3 . alpn=h3 port=1500 0 bar.svcb.example.com. 120 IN SVCB 4 . alpn=h3 port=1501 +0 bar.svcb.example.com. 120 IN SVCB 5 . no-default-alpn port=8004 dohpath="/dns-query{?dns}" ohttp tls-supported-groups=29,23 +0 bar.svcb.example.com. 120 IN SVCB 6 . key997="quoted" key998="foo" key999="bar" 2 . 32768 IN OPT 2 bar.svcb.example.com. 120 IN A 192.0.2.1 2 bar.svcb.example.com. 120 IN AAAA 2001:db8::3:1 diff --git a/regression-tests/zones/example.com b/regression-tests/zones/example.com index 96993cecb0..f4f13ae300 100644 --- a/regression-tests/zones/example.com +++ b/regression-tests/zones/example.com @@ -20223,6 +20223,8 @@ foo1.svcb IN A 192.0.2.2 ; Should show up in additional bar.svcb IN SVCB 1 . alpn=h2 bar.svcb IN SVCB 3 . alpn=h3 port=1500 bar.svcb IN SVCB 4 . alpn=h3 port="1501" +bar.svcb IN SVCB 5 . port="8004" no-default-alpn dohpath=/dns-query{?dns} ohttp tls-supported-groups=29,23 +bar.svcb IN SVCB 6 . key00997="quoted" key0998=foo key999=bar bar.svcb IN AAAA 2001:db8::3:1 bar.svcb IN AAAA 2001:db8::3:4 bar.svcb IN A 192.0.2.1 -- 2.47.3