And from an actual implementation.
enum encoding {
sbpr_text,
sbpr_port,
sbpr_ipv4s,
sbpr_ipv6s,
sbpr_base64
};
static const struct {
const char * name;
unsigned int value;
enum encoding encoding;
bool initial;
} sbpr[] = {
{ "key0=", 0, sbpr_text, true },
{ "alpn=", 1, sbpr_text, true },
{ "port=", 2, sbpr_port, true },
{ "esnikeys=", 3, sbpr_base64, true },
{ "ipv4hint=", 4, sbpr_ipv4s, true },
{ "ipv6hint=", 6, sbpr_ipv6s, true },
};
switch (sbpr[i].encoding) {
case sbpr_text:
RETERR(multitxt_fromtext(region, target));
break;
case sbpr_port:
ul = strtoul(region->base, &e, 10);
if (*e != '\0') {
return (DNS_R_SYNTAX);
}
if (ul > 0xffff) {
return (ISC_R_RANGE);
}
RETERR(uint16_tobuffer(ul, target));
break;
case sbpr_ipv4s:
do {
snprintf(tbuf, sizeof(tbuf), "%*s",
(int)(region->length), region->base);
e = strchr(tbuf, ',');
if (e != NULL) {
*e++ = 0;
isc_textregion_consume(region,
e - tbuf);
}
if (inet_pton(AF_INET, tbuf, abuf) != 1) {
return (DNS_R_SYNTAX);
}
mem_tobuffer(target, abuf, 4);
} while (e != NULL);
break;
case sbpr_ipv6s:
do {
snprintf(tbuf, sizeof(tbuf), "%*s",
(int)(region->length), region->base);
e = strchr(tbuf, ',');
if (e != NULL) {
*e++ = 0;
isc_textregion_consume(region,
e - tbuf);
}
if (inet_pton(AF_INET6, tbuf, abuf) != 1) {
return (DNS_R_SYNTAX);
}
mem_tobuffer(target, abuf, 16);
} while (e != NULL);
break;
case sbpr_base64:
RETERR(isc_base64_decodestring(region->base,
target));
break;
default:
INSIST(0);
ISC_UNREACHABLE();
}
switch(encoding) {
case sbpr_text:
RETERR(multitxt_totext(&r, target));
break;
case sbpr_port:
num = uint16_fromregion(&r);
n = snprintf(buf, sizeof(buf), "%u", num);
INSIST(n > 0 && (unsigned)n < sizeof(buf));
RETERR(str_totext(buf, target));
break;
case sbpr_ipv4s:
while (r.length > 0U) {
INSIST(r.length >= 4U);
inet_ntop(AF_INET, r.base, buf, sizeof(buf));
RETERR(str_totext(buf, target));
isc_region_consume(&r, 4);
if (r.length != 0U) {
RETERR(str_totext(",", target));
}
}
break;
case sbpr_ipv6s:
while (r.length > 0U) {
INSIST(r.length >= 16U);
inet_ntop(AF_INET6, r.base, buf, sizeof(buf));
RETERR(str_totext(buf, target));
isc_region_consume(&r, 16);
if (r.length != 0U) {
RETERR(str_totext(",", target));
}
}
break;
case sbpr_base64:
RETERR(isc_base64_totext(&r, 0, "", target));
break;
default:
INSIST(0);
ISC_UNREACHABLE();
}
> On 27 Sep 2019, at 9:31 am, Mark Andrews <[email protected]> wrote:
>
> Implementing the encoder isn’t hard but it needs to be clearer that there are
> specific encodings. It is easy to miss this. I did initially.
>
> --
> Mark Andrews
>
>> On 26 Sep 2019, at 20:41, Vladimír Čunát <[email protected]> wrote:
>>
>>
>> On 9/26/19 12:30 PM, Jan Včelák wrote:
>>>> The current draft attempts to minimize complexity for implementers by
>>>> offering a fully generic encoding for unknown key types. For example,
>>>> "alpn=h3" can also be expressed as "key1=h3", and "port=8003" can also be
>>>> expressed as "key2=\031\067". This encoding may not be convenient, but
>>>> hopefully it will reduce the burden of supporting new parameter types.
>>>>
>>> I agree we need generic encoding. There is a way to express unknown
>>> record types (
>>> https://tools.ietf.org/html/rfc3597#section-5
>>> ) and the
>>> syntax used there is more compact than what you propose. It uses hex
>>> strings instead of escaped decimal values. However its clumsy to work
>>> with records in that syntax and you proposal is better in that sense.
>>>
>> I'm curious, Is there much motivation for a bit more compactness of the
>> *presentation* format? I consider its design primarily meant for humans.
>>
>>
>>> I think this may become the most complex record type we have in DNS so
>>> far. None of the existing registered record types contain a list of
>>> key-value pairs of arbitrary length. Given that there is also a
>>> registry for key types involved it will be fun to implement the
>>> encoder/decoder. But we will have to deal with it. I'm interested in
>>> what others in this working group think.
>>>
>> I think we should get "implementation experience" from multiple parties at
>> least before publishing the RFC (though that's a point far ahead, I suppose).
>> --Vladimir
>>
>> _______________________________________________
>> DNSOP mailing list
>> [email protected]
>> https://www.ietf.org/mailman/listinfo/dnsop
> _______________________________________________
> DNSOP mailing list
> [email protected]
> https://www.ietf.org/mailman/listinfo/dnsop
--
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742 INTERNET: [email protected]
_______________________________________________
DNSOP mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/dnsop