summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2017-02-18 19:23:06 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2017-02-18 19:23:06 +0000
commit65c30be6a8c6e017d12a1c3f6a46d8ec4254028e (patch)
treedd0da15e85a99071d0e6ef136040ebd5cd2d4498
parent1d1cdb40482e7cba1643711c258d520c594c256f (diff)
Add EDNS0 support.
EDNS allows for various DNS extensions, among which UDP DNS packets size bigger than 512 bytes. The default is still to not advertize anything. ok eric@
-rw-r--r--lib/libc/asr/asr.c4
-rw-r--r--lib/libc/asr/asr_private.h4
-rw-r--r--lib/libc/asr/asr_run.37
-rw-r--r--lib/libc/asr/asr_utils.c22
-rw-r--r--lib/libc/asr/res_mkquery.c6
-rw-r--r--lib/libc/asr/res_send_async.c8
-rw-r--r--lib/libc/net/resolver.37
-rw-r--r--share/man/man5/resolv.conf.534
8 files changed, 59 insertions, 33 deletions
diff --git a/lib/libc/asr/asr.c b/lib/libc/asr/asr.c
index d53edf46795..d91a537599d 100644
--- a/lib/libc/asr/asr.c
+++ b/lib/libc/asr/asr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr.c,v 1.54 2016/06/18 15:25:28 reyk Exp $ */
+/* $OpenBSD: asr.c,v 1.55 2017/02/18 19:23:05 jca Exp $ */
/*
* Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org>
*
@@ -603,6 +603,8 @@ pass0(char **tok, int n, struct asr_ctx *ac)
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);
diff --git a/lib/libc/asr/asr_private.h b/lib/libc/asr/asr_private.h
index 1bee3d9bde9..690d9ed537b 100644
--- a/lib/libc/asr/asr_private.h
+++ b/lib/libc/asr/asr_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_private.h,v 1.41 2017/02/17 22:24:45 eric Exp $ */
+/* $OpenBSD: asr_private.h,v 1.42 2017/02/18 19:23:05 jca Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -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 *);
diff --git a/lib/libc/asr/asr_run.3 b/lib/libc/asr/asr_run.3
index 6f0f314c690..61c1b02c1ab 100644
--- a/lib/libc/asr/asr_run.3
+++ b/lib/libc/asr/asr_run.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: asr_run.3,v 1.2 2014/03/26 18:13:15 eric Exp $
+.\" $OpenBSD: asr_run.3,v 1.3 2017/02/18 19:23:05 jca Exp $
.\"
.\" Copyright (c) 2012-2014, Eric Faurot <eric@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: March 26 2014 $
+.Dd $Mdocdate: February 18 2017 $
.Dt ASR_RUN 3
.Os
.Sh NAME
@@ -314,6 +314,3 @@ so sharing a resolver among threads is not useful.
.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.
diff --git a/lib/libc/asr/asr_utils.c b/lib/libc/asr/asr_utils.c
index 835d5dfb448..e540aae9ab6 100644
--- a/lib/libc/asr/asr_utils.c
+++ b/lib/libc/asr/asr_utils.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_utils.c,v 1.14 2017/02/17 22:24:45 eric Exp $ */
+/* $OpenBSD: asr_utils.c,v 1.15 2017/02/18 19:23:05 jca Exp $ */
/*
* Copyright (c) 2009-2012 Eric Faurot <eric@faurot.net>
*
@@ -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.
@@ -415,6 +423,18 @@ _asr_pack_query(struct asr_pack *p, uint16_t type, uint16_t class, const char *d
}
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);
+}
+
+int
_asr_sockaddr_from_str(struct sockaddr *sa, int family, const char *str)
{
struct in_addr ina;
diff --git a/lib/libc/asr/res_mkquery.c b/lib/libc/asr/res_mkquery.c
index 3b169c13194..340c1f11f74 100644
--- a/lib/libc/asr/res_mkquery.c
+++ b/lib/libc/asr/res_mkquery.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_mkquery.c,v 1.9 2015/09/09 15:49:34 deraadt Exp $ */
+/* $OpenBSD: res_mkquery.c,v 1.10 2017/02/18 19:23:05 jca Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -61,10 +61,14 @@ res_mkquery(int op, const char *dname, int class, int type,
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);
diff --git a/lib/libc/asr/res_send_async.c b/lib/libc/asr/res_send_async.c
index ff7d917b6f5..b75253c101e 100644
--- a/lib/libc/asr/res_send_async.c
+++ b/lib/libc/asr/res_send_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_send_async.c,v 1.30 2017/02/17 00:29:22 krw Exp $ */
+/* $OpenBSD: res_send_async.c,v 1.31 2017/02/18 19:23:05 jca Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -377,10 +377,14 @@ setup_query(struct asr_query *as, const char *name, const char *dom,
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;
@@ -449,8 +453,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;
close(as->as_fd);
diff --git a/lib/libc/net/resolver.3 b/lib/libc/net/resolver.3
index c395c9929b4..68e509f4f0d 100644
--- a/lib/libc/net/resolver.3
+++ b/lib/libc/net/resolver.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: resolver.3,v 1.35 2017/01/24 12:43:00 jmc Exp $
+.\" $OpenBSD: resolver.3,v 1.36 2017/02/18 19:23:05 jca Exp $
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: January 24 2017 $
+.Dd $Mdocdate: February 18 2017 $
.Dt RES_INIT 3
.Os
.Sh NAME
@@ -193,9 +193,8 @@ allowing them to take advantage of a non-default receive buffer size,
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),
diff --git a/share/man/man5/resolv.conf.5 b/share/man/man5/resolv.conf.5
index 20fa6a11f5b..8710196a656 100644
--- a/share/man/man5/resolv.conf.5
+++ b/share/man/man5/resolv.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: resolv.conf.5,v 1.51 2017/01/24 12:43:00 jmc Exp $
+.\" $OpenBSD: resolv.conf.5,v 1.52 2017/02/18 19:23:05 jca Exp $
.\" $NetBSD: resolv.conf.5,v 1.7 1996/03/06 18:22:16 scottr Exp $
.\"
.\" Copyright (c) 1986, 1991 The Regents of the University of California.
@@ -30,7 +30,7 @@
.\"
.\" @(#)resolver.5 5.12 (Berkeley) 5/10/91
.\"
-.Dd $Mdocdate: January 24 2017 $
+.Dd $Mdocdate: February 18 2017 $
.Dt RESOLV.CONF 5
.Os
.Sh NAME
@@ -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