summaryrefslogtreecommitdiff
path: root/lib/libc/asr
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 /lib/libc/asr
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@
Diffstat (limited to 'lib/libc/asr')
-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
6 files changed, 39 insertions, 12 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);