On Sat, Feb 18, 2017 at 03:53:54PM +0100, Jeremie Courreges-Anglas wrote:
>
>
> Seems to work fine here. We already use a 4096 bytes input buffer, the
> edns0 option makes libc advertize this to the DNS resolver. nsd,
> unbound, dig(1) and ports/net/isc-bind support this feature. I'm not
> suggesting that we use it by default right now, but this could be
> a desirable change.
>
> ok?
Yes, I like it a lot.
One small comment tough: better use T_OPT rather than 41 in _asr_pack_edns0().
Besides that, ok eric@
>
> Index: share/man/man5/resolv.conf.5
> ===================================================================
> RCS file: /d/cvs/src/share/man/man5/resolv.conf.5,v
> retrieving revision 1.51
> diff -u -p -r1.51 resolv.conf.5
> --- share/man/man5/resolv.conf.5 24 Jan 2017 12:43:00 -0000 1.51
> +++ share/man/man5/resolv.conf.5 18 Feb 2017 14:33:37 -0000
> @@ -258,21 +258,21 @@ lines are able to handle the extension.
> On
> .Ox
> this option does nothing.
> -.\" .Pp
> -.\" To verify whether a server supports EDNS,
> -.\" query it using the
> -.\" .Xr dig 1
> -.\" query option
> -.\" .Li +edns=0 :
> -.\" the reply indicates compliance (EDNS version 0)
> -.\" and whether a UDP packet larger than 512 bytes can be used.
> -.\" Note that EDNS0 can cause the server to send packets
> -.\" large enough to require fragmentation.
> -.\" Other factors such as packet filters may impede these,
> -.\" particularly if there is a reduced MTU,
> -.\" as is often the case with
> -.\" .Xr pppoe 4
> -.\" or with tunnels.
> +.Pp
> +To verify whether a server supports EDNS,
> +query it using the
> +.Xr dig 1
> +query option
> +.Li +edns=0 :
> +the reply indicates compliance (EDNS version 0)
> +and whether a UDP packet larger than 512 bytes can be used.
> +Note that EDNS0 can cause the server to send packets
> +large enough to require fragmentation.
> +Other factors such as packet filters may impede these,
> +particularly if there is a reduced MTU,
> +as is often the case with
> +.Xr pppoe 4
> +or with tunnels.
> .It Cm inet6
> Enables support for IPv6-only applications, by setting RES_USE_INET6 in
> _res.options (see
> Index: lib/libc/asr/asr.c
> ===================================================================
> RCS file: /d/cvs/src/lib/libc/asr/asr.c,v
> retrieving revision 1.54
> diff -u -p -r1.54 asr.c
> --- lib/libc/asr/asr.c 18 Jun 2016 15:25:28 -0000 1.54
> +++ lib/libc/asr/asr.c 16 Feb 2017 15:36:30 -0000
> @@ -603,6 +603,8 @@ pass0(char **tok, int n, struct asr_ctx
> for (i = 1; i < n; i++) {
> if (!strcmp(tok[i], "tcp"))
> ac->ac_options |= RES_USEVC;
> + else if (!strcmp(tok[i], "edns0"))
> + ac->ac_options |= RES_USE_EDNS0;
> else if ((!strncmp(tok[i], "ndots:", 6))) {
> e = NULL;
> d = strtonum(tok[i] + 6, 1, 16, &e);
> Index: lib/libc/asr/asr_private.h
> ===================================================================
> RCS file: /d/cvs/src/lib/libc/asr/asr_private.h,v
> retrieving revision 1.41
> diff -u -p -r1.41 asr_private.h
> --- lib/libc/asr/asr_private.h 17 Feb 2017 22:24:45 -0000 1.41
> +++ lib/libc/asr/asr_private.h 18 Feb 2017 10:44:56 -0000
> @@ -294,6 +294,7 @@ enum asr_state {
> ASR_STATE_HALT,
> };
>
> +#define MAXPACKETSZ 4096
>
> __BEGIN_HIDDEN_DECLS
>
> @@ -301,6 +302,7 @@ __BEGIN_HIDDEN_DECLS
> void _asr_pack_init(struct asr_pack *, char *, size_t);
> int _asr_pack_header(struct asr_pack *, const struct asr_dns_header *);
> int _asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *);
> +int _asr_pack_edns0(struct asr_pack *, uint16_t);
> void _asr_unpack_init(struct asr_unpack *, const char *, size_t);
> int _asr_unpack_header(struct asr_unpack *, struct asr_dns_header *);
> int _asr_unpack_query(struct asr_unpack *, struct asr_dns_query *);
> Index: lib/libc/asr/asr_run.3
> ===================================================================
> RCS file: /d/cvs/src/lib/libc/asr/asr_run.3,v
> retrieving revision 1.2
> diff -u -p -r1.2 asr_run.3
> --- lib/libc/asr/asr_run.3 26 Mar 2014 18:13:15 -0000 1.2
> +++ lib/libc/asr/asr_run.3 18 Feb 2017 14:39:22 -0000
> @@ -314,6 +314,3 @@ so sharing a resolver among threads is n
> .Xr getrrsetbyname 3 ,
> .Xr res_send 3 ,
> .Xr resolv.conf 5
> -.Sh CAVEATS
> -This DNS resolver implementation doesn't support
> -the EDNS0 protocol extension yet.
> Index: lib/libc/asr/asr_utils.c
> ===================================================================
> RCS file: /d/cvs/src/lib/libc/asr/asr_utils.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 asr_utils.c
> --- lib/libc/asr/asr_utils.c 17 Feb 2017 22:24:45 -0000 1.14
> +++ lib/libc/asr/asr_utils.c 18 Feb 2017 10:44:23 -0000
> @@ -381,6 +381,14 @@ pack_u16(struct asr_pack *p, uint16_t v)
> }
>
> static int
> +pack_u32(struct asr_pack *p, uint32_t v)
> +{
> + v = htonl(v);
> +
> + return (pack_data(p, &v, 4));
> +}
> +
> +static int
> pack_dname(struct asr_pack *p, const char *dname)
> {
> /* dname compression would be nice to have here.
> @@ -410,6 +418,18 @@ _asr_pack_query(struct asr_pack *p, uint
> pack_dname(p, dname);
> pack_u16(p, type);
> pack_u16(p, class);
> +
> + return (p->err) ? (-1) : (0);
> +}
> +
> +int
> +_asr_pack_edns0(struct asr_pack *p, uint16_t pktsz)
> +{
> + pack_dname(p, ""); /* root */
> + pack_u16(p, 41); /* OPT */
> + pack_u16(p, pktsz); /* UDP payload size */
> + pack_u32(p, 0); /* extended RCODE and flags */
> + pack_u16(p, 0); /* RDATA len */
>
> return (p->err) ? (-1) : (0);
> }
> Index: lib/libc/asr/res_mkquery.c
> ===================================================================
> RCS file: /d/cvs/src/lib/libc/asr/res_mkquery.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 res_mkquery.c
> --- lib/libc/asr/res_mkquery.c 9 Sep 2015 15:49:34 -0000 1.9
> +++ lib/libc/asr/res_mkquery.c 18 Feb 2017 10:45:47 -0000
> @@ -61,10 +61,14 @@ res_mkquery(int op, const char *dname, i
> if (ac->ac_options & RES_RECURSE)
> h.flags |= RD_MASK;
> h.qdcount = 1;
> + if (ac->ac_options & RES_USE_EDNS0)
> + h.arcount = 1;
>
> _asr_pack_init(&p, buf, buflen);
> _asr_pack_header(&p, &h);
> _asr_pack_query(&p, type, class, dn);
> + if (ac->ac_options & RES_USE_EDNS0)
> + _asr_pack_edns0(&p, MAXPACKETSZ);
>
> _asr_ctx_unref(ac);
>
> Index: lib/libc/asr/res_send_async.c
> ===================================================================
> RCS file: /d/cvs/src/lib/libc/asr/res_send_async.c,v
> retrieving revision 1.30
> diff -u -p -r1.30 res_send_async.c
> --- lib/libc/asr/res_send_async.c 17 Feb 2017 00:29:22 -0000 1.30
> +++ lib/libc/asr/res_send_async.c 18 Feb 2017 10:45:16 -0000
> @@ -377,10 +377,14 @@ setup_query(struct asr_query *as, const
> if (as->as_ctx->ac_options & RES_RECURSE)
> h.flags |= RD_MASK;
> h.qdcount = 1;
> + if (as->as_ctx->ac_options & RES_USE_EDNS0)
> + h.arcount = 1;
>
> _asr_pack_init(&p, as->as.dns.obuf, as->as.dns.obufsize);
> _asr_pack_header(&p, &h);
> _asr_pack_query(&p, type, class, dname);
> + if (as->as_ctx->ac_options & RES_USE_EDNS0)
> + _asr_pack_edns0(&p, MAXPACKETSZ);
> if (p.err) {
> DPRINT("error packing query");
> errno = EINVAL;
> @@ -448,8 +452,6 @@ udp_recv(struct asr_query *as)
> {
> ssize_t n;
> int save_errno;
> -
> -#define MAXPACKETSZ 4096
>
> if (ensure_ibuf(as, MAXPACKETSZ) == -1) {
> save_errno = errno;
> Index: lib/libc/net/resolver.3
> ===================================================================
> RCS file: /d/cvs/src/lib/libc/net/resolver.3,v
> retrieving revision 1.35
> diff -u -p -r1.35 resolver.3
> --- lib/libc/net/resolver.3 24 Jan 2017 12:43:00 -0000 1.35
> +++ lib/libc/net/resolver.3 18 Feb 2017 14:37:06 -0000
> @@ -193,9 +193,8 @@ allowing them to take advantage of a non
> and thus to send larger replies.
> DNS query packets with the EDNS0 extension are not compatible with
> non-EDNS0 DNS servers.
> -On
> .Ox
> -this option does nothing.
> +uses 4096 bytes as input buffer size.
> .It Dv RES_USE_DNSSEC
> Request that the resolver uses
> Domain Name System Security Extensions (DNSSEC),
>
>
> --
> jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
>