On Sun, Jul 03, 2022 at 07:47:27AM +0200, Florian Obser wrote:

> anyone?

Looks good and works for me, ok.

        -Otto

> 
> On 2022-06-25 13:15 +02, Florian Obser <flor...@openbsd.org> wrote:
> > 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