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