See https://datatracker.ietf.org/doc/draft-ietf-dnsop-svcb-https/

$ ./obj/dig @8.8.8.8 +norec _dns.resolver.arpa svcb

; <<>> dig 9.10.8-P1 <<>> @8.8.8.8 +norec _dns.resolver.arpa svcb
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21245
;; flags: qr aa ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 4

;; QUESTION SECTION:
;_dns.resolver.arpa.            IN      SVCB

;; ANSWER SECTION:
_dns.resolver.arpa.     86400   IN      SVCB    1 dns.google. alpn="dot"
_dns.resolver.arpa.     86400   IN      SVCB    2 dns.google. alpn="h2,h3" 
dohpath="/dns-query{?dns}"

;; ADDITIONAL SECTION:
dns.google.             86400   IN      A       8.8.8.8
dns.google.             86400   IN      A       8.8.4.4
dns.google.             86400   IN      AAAA    2001:4860:4860::8888
dns.google.             86400   IN      AAAA    2001:4860:4860::8844

;; Query time: 11 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat Jun 25 13:08:21 CEST 2022
;; MSG SIZE  rcvd: 224

$ ./obj/dig +dnssec cloudflare.com https

; <<>> dig 9.10.8-P1 <<>> +dnssec cloudflare.com https
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22508
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;cloudflare.com.                        IN      HTTPS

;; ANSWER SECTION:
cloudflare.com.         217     IN      HTTPS   1 . alpn="h3,h3-29,h2" 
ipv4hint=104.16.132.229,104.16.133.229 
ipv6hint=2606:4700::6810:84e5,2606:4700::6810:85e5
cloudflare.com.         217     IN      RRSIG   HTTPS 13 2 300 20220626120906 
20220624100906 34505 cloudflare.com. 
PbQwTGVBW2MIXubouK2vUo92UNvlJ874KCrqah/Or21Jo2oDxfgI15jA 
8z/Q6mseLPWIlTxex+KoIqv9y+FNjg==

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Jun 25 13:10:29 CEST 2022
;; MSG SIZE  rcvd: 221

OK?

diff --git lib/dns/include/dns/types.h lib/dns/include/dns/types.h
index 63ea8d67f51..7085ce29f2e 100644
--- lib/dns/include/dns/types.h
+++ lib/dns/include/dns/types.h
@@ -139,6 +139,8 @@ enum {
        dns_rdatatype_openpgpkey = 61,
        dns_rdatatype_csync = 62,
        dns_rdatatype_zonemd = 63,
+       dns_rdatatype_svcb = 64,
+       dns_rdatatype_https = 65,
        dns_rdatatype_spf = 99,
        dns_rdatatype_unspec = 103,
        dns_rdatatype_nid = 104,
diff --git lib/dns/rdata.c lib/dns/rdata.c
index c27409efc3c..d731eb3a846 100644
--- lib/dns/rdata.c
+++ lib/dns/rdata.c
@@ -775,6 +775,7 @@ dns_rdatatype_fromtext(dns_rdatatype_t *typep, 
isc_textregion_t *source) {
                {"gpos",        27},
                {"hinfo",       13},
                {"hip",         55},
+               {"https",       65},
                {"ipseckey",    45},
                {"isdn",        20},
                {"ixfr",        251},
@@ -822,6 +823,7 @@ dns_rdatatype_fromtext(dns_rdatatype_t *typep, 
isc_textregion_t *source) {
                {"spf",         99},
                {"srv",         33},
                {"sshfp",       44},
+               {"svcb",        64},
                {"ta",          32768},
                {"talink",      58},
                {"tkey",        249},
@@ -1006,6 +1008,10 @@ dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t 
*target) {
                return (isc_str_tobuffer("CSYNC", target));
        case 63:
                return (isc_str_tobuffer("ZONEMD", target));
+       case 64:
+               return (isc_str_tobuffer("SVCB", target));
+       case 65:
+               return (isc_str_tobuffer("HTTPS", target));
        case 99:
                return (isc_str_tobuffer("SPF", target));
        case 100:
diff --git lib/dns/rdata/in_1/https_65.c lib/dns/rdata/in_1/https_65.c
new file mode 100644
index 00000000000..23d80f8d352
--- /dev/null
+++ lib/dns/rdata/in_1/https_65.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 Florian Obser <flor...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* draft-ietf-dnsop-svcb-https-10 */
+
+#ifndef RDATA_IN_1_HTTPS_65_C
+#define RDATA_IN_1_HTTPS_65_C
+
+static inline isc_result_t
+totext_in_https(ARGS_TOTEXT) {
+       REQUIRE(rdata->type == dns_rdatatype_https);
+       REQUIRE(rdata->rdclass == dns_rdataclass_in);
+       REQUIRE(rdata->length != 0);
+
+       return (totext_in_svcb_https(rdata, tctx, target));
+}
+
+static inline isc_result_t
+fromwire_in_https(ARGS_FROMWIRE) {
+       REQUIRE(type == dns_rdatatype_https);
+       REQUIRE(rdclass == dns_rdataclass_in);
+       return (fromwire_in_svcb_https(rdclass, type, source, dctx, options,
+           target));
+}
+
+static inline isc_result_t
+towire_in_https(ARGS_TOWIRE) {
+       REQUIRE(rdata->type == dns_rdatatype_https);
+       REQUIRE(rdata->length != 0);
+
+       return (towire_in_svcb_https(rdata, cctx, target));
+}
+
+
+#endif /* RDATA_IN_1_HTTPS_65_C */
diff --git lib/dns/rdata/in_1/svcb_64.c lib/dns/rdata/in_1/svcb_64.c
new file mode 100644
index 00000000000..721289bc6c8
--- /dev/null
+++ lib/dns/rdata/in_1/svcb_64.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2022 Florian Obser <flor...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: srv_33.c,v 1.13 2020/09/14 08:40:44 florian Exp $ */
+
+/* draft-ietf-dnsop-svcb-https-10, based on srv_33.c */
+
+#ifndef RDATA_IN_1_SVCB_64_C
+#define RDATA_IN_1_SVCB_64_C
+
+#define SVC_PARAM_MANDATORY    0
+#define SVC_PARAM_ALPN         1
+#define SVC_PARAM_NO_DEF_ALPN  2
+#define SVC_PARAM_PORT         3
+#define SVC_PARAM_IPV4HINT     4
+#define SVC_PARAM_ECH          5
+#define SVC_PARAM_IPV6HINT     6
+#define SVC_PARAM_DOHPATH      7
+
+static inline const char*
+svc_param_key_to_text(uint16_t key)
+{
+       static char buf[sizeof "key65535"];
+
+       switch (key) {
+       case SVC_PARAM_MANDATORY:
+               return ("mandatory");
+       case SVC_PARAM_ALPN:
+               return ("alpn");
+       case SVC_PARAM_NO_DEF_ALPN:
+               return ("no-default-alpn");
+       case SVC_PARAM_PORT:
+               return ("port");
+       case SVC_PARAM_IPV4HINT:
+               return ("ipv4hint");
+       case SVC_PARAM_ECH:
+               return ("ech");
+       case SVC_PARAM_IPV6HINT:
+               return ("ipv6hint");
+       case SVC_PARAM_DOHPATH:
+               return ("dohpath");
+       default:
+               snprintf(buf, sizeof buf, "key%u", key);
+               return (buf);
+       }
+}
+
+static inline isc_result_t
+totext_in_svcb_https(ARGS_TOTEXT) {
+       isc_region_t region;
+       dns_name_t name;
+       dns_name_t prefix;
+       int sub;
+       char buf[sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255"];
+       unsigned short num;
+
+       dns_name_init(&name, NULL);
+       dns_name_init(&prefix, NULL);
+
+       /*
+        * Priority.
+        */
+       dns_rdata_toregion(rdata, &region);
+       num = uint16_fromregion(&region);
+       isc_region_consume(&region, 2);
+       snprintf(buf, sizeof buf, "%u", num);
+       RETERR(isc_str_tobuffer(buf, target));
+       RETERR(isc_str_tobuffer(" ", target));
+
+       /*
+        * Target.
+        */
+       dns_name_fromregion(&name, &region);
+       isc_region_consume(&region, name_length(&name));
+       sub = name_prefix(&name, tctx->origin, &prefix);
+       RETERR(dns_name_totext(&prefix, sub, target));
+
+       while (region.length > 0) {
+               isc_region_t val_region;
+               uint16_t svc_param_key, svc_param_value_len, man_key, port;
+
+               RETERR(isc_str_tobuffer(" ", target));
+
+               svc_param_key = uint16_fromregion(&region);
+               isc_region_consume(&region, 2);
+
+               svc_param_value_len = uint16_fromregion(&region);
+               isc_region_consume(&region, 2);
+
+               RETERR(isc_str_tobuffer(svc_param_key_to_text(svc_param_key),
+                   target));
+
+               val_region = region;
+               val_region.length = svc_param_value_len;
+
+               isc_region_consume(&region, svc_param_value_len);
+
+               switch (svc_param_key) {
+               case SVC_PARAM_MANDATORY:
+                       INSIST(val_region.length % 2 == 0);
+                       RETERR(isc_str_tobuffer("=", target));
+                       while (val_region.length > 0) {
+                               man_key = uint16_fromregion(&val_region);
+                               isc_region_consume(&val_region, 2);
+                               RETERR(isc_str_tobuffer(svc_param_key_to_text(
+                                   man_key), target));
+                               if (val_region.length != 0)
+                                       RETERR(isc_str_tobuffer(",", target));
+                       }
+                       break;
+               case SVC_PARAM_ALPN:
+                       RETERR(isc_str_tobuffer("=\"", target));
+                       while (val_region.length > 0) {
+                               txt_totext(&val_region, 0, target);
+                               if (val_region.length != 0)
+                                       RETERR(isc_str_tobuffer(",", target));
+                       }
+                       RETERR(isc_str_tobuffer("\"", target));
+                       break;
+               case SVC_PARAM_NO_DEF_ALPN:
+                       INSIST(val_region.length == 0);
+                       break;
+               case SVC_PARAM_PORT:
+                       INSIST(val_region.length == 2);
+                       RETERR(isc_str_tobuffer("=", target));
+                       port = uint16_fromregion(&val_region);
+                       isc_region_consume(&val_region, 2);
+                       snprintf(buf, sizeof buf, "%u", port);
+                       RETERR(isc_str_tobuffer(buf, target));
+                       break;
+               case SVC_PARAM_IPV4HINT:
+                       INSIST(val_region.length % 4 == 0);
+                       RETERR(isc_str_tobuffer("=", target));
+                       while (val_region.length > 0) {
+                               inet_ntop(AF_INET, val_region.base, buf,
+                                   sizeof buf);
+                               RETERR(isc_str_tobuffer(buf, target));
+                               isc_region_consume(&val_region, 4);
+                               if (val_region.length != 0)
+                                       RETERR(isc_str_tobuffer(",", target));
+                       }
+                       break;
+               case SVC_PARAM_ECH:
+                       RETERR(isc_str_tobuffer("=", target));
+                       RETERR(isc_base64_totext(&val_region, 0, "", target));
+                       break;
+               case SVC_PARAM_IPV6HINT:
+                       INSIST(val_region.length % 16 == 0);
+                       RETERR(isc_str_tobuffer("=", target));
+                       while (val_region.length > 0) {
+                               inet_ntop(AF_INET6, val_region.base, buf,
+                                   sizeof buf);
+                               RETERR(isc_str_tobuffer(buf, target));
+                               isc_region_consume(&val_region, 16);
+                               if (val_region.length != 0)
+                                       RETERR(isc_str_tobuffer(",", target));
+                       }
+                       break;
+               case SVC_PARAM_DOHPATH:
+                       RETERR(isc_str_tobuffer("=", target));
+                       RETERR(multitxt_totext(&val_region, target));
+                       break;
+               default:
+                       RETERR(isc_str_tobuffer("=", target));
+                       RETERR(multitxt_totext(&val_region, target));
+                       break;
+               }
+       }
+       return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+totext_in_svcb(ARGS_TOTEXT) {
+       REQUIRE(rdata->type == dns_rdatatype_svcb);
+       REQUIRE(rdata->rdclass == dns_rdataclass_in);
+       REQUIRE(rdata->length != 0);
+
+       return (totext_in_svcb_https(rdata, tctx, target));
+}
+
+static inline isc_result_t
+fromwire_in_svcb_https(ARGS_FROMWIRE) {
+       dns_name_t name;
+       isc_region_t sr;
+       unsigned int svc_param_value_len;
+       int alias_mode = 0;
+
+       UNUSED(type);
+       UNUSED(rdclass);
+
+       dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
+
+       dns_name_init(&name, NULL);
+
+       /*
+        * SvcPriority.
+        */
+       isc_buffer_activeregion(source, &sr);
+       if (sr.length < 2)
+               return (ISC_R_UNEXPECTEDEND);
+       RETERR(isc_mem_tobuffer(target, sr.base, 2));
+       alias_mode = uint16_fromregion(&sr) == 0;
+       isc_buffer_forward(source, 2);
+
+       /*
+        * TargetName.
+        */
+       RETERR(dns_name_fromwire(&name, source, dctx, options, target));
+       if (alias_mode) {
+               /*
+                * In AliasMode, recipients MUST ignore any SvcParams that
+                * are present.
+                */
+               return (ISC_R_SUCCESS);
+       }
+
+       isc_buffer_activeregion(source, &sr);
+       while (sr.length > 0) {
+               /*
+                * SvcParamKey.
+                */
+               if (sr.length < 2)
+                       return (ISC_R_UNEXPECTEDEND);
+
+               RETERR(isc_mem_tobuffer(target, sr.base, 2));
+               isc_region_consume(&sr, 2);
+               isc_buffer_forward(source, 2);
+
+               /*
+                * SvcParamValue length.
+                */
+               if (sr.length < 2)
+                       return (ISC_R_UNEXPECTEDEND);
+
+               RETERR(isc_mem_tobuffer(target, sr.base, 2));
+               svc_param_value_len = uint16_fromregion(&sr);
+               isc_region_consume(&sr, 2);
+               isc_buffer_forward(source, 2);
+
+               if (sr.length < svc_param_value_len)
+                       return (ISC_R_UNEXPECTEDEND);
+
+               RETERR(isc_mem_tobuffer(target, sr.base, svc_param_value_len));
+               isc_region_consume(&sr, svc_param_value_len);
+               isc_buffer_forward(source, svc_param_value_len);
+       }
+
+       return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+fromwire_in_svcb(ARGS_FROMWIRE) {
+       REQUIRE(type == dns_rdatatype_svcb);
+       REQUIRE(rdclass == dns_rdataclass_in);
+       return (fromwire_in_svcb_https(rdclass, type, source, dctx, options,
+           target));
+}
+
+static inline isc_result_t
+towire_in_svcb_https(ARGS_TOWIRE) {
+       dns_name_t name;
+       dns_offsets_t offsets;
+       isc_region_t sr;
+
+       dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
+
+       /*
+        * SvcPriority.
+        */
+       dns_rdata_toregion(rdata, &sr);
+       RETERR(isc_mem_tobuffer(target, sr.base, 2));
+       isc_region_consume(&sr, 2);
+
+       /*
+        * TargetName.
+        */
+       dns_name_init(&name, offsets);
+       dns_name_fromregion(&name, &sr);
+       RETERR(dns_name_towire(&name, cctx, target));
+       isc_region_consume(&sr, name_length(&name));
+
+       /*
+        * SvcParams.
+        */
+       return (isc_mem_tobuffer(target, sr.base, sr.length));
+}
+
+static inline isc_result_t
+towire_in_svcb(ARGS_TOWIRE) {
+       REQUIRE(rdata->type == dns_rdatatype_svcb);
+       REQUIRE(rdata->length != 0);
+
+       return (towire_in_svcb_https(rdata, cctx, target));
+}
+#endif /* RDATA_IN_1_SVCB_64_C */

-- 
I'm not entirely sure you are real.

Reply via email to