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?


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

Reply via email to