diff options
author | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2017-02-18 19:23:06 +0000 |
---|---|---|
committer | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2017-02-18 19:23:06 +0000 |
commit | 65c30be6a8c6e017d12a1c3f6a46d8ec4254028e (patch) | |
tree | dd0da15e85a99071d0e6ef136040ebd5cd2d4498 | |
parent | 1d1cdb40482e7cba1643711c258d520c594c256f (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.c | 4 | ||||
-rw-r--r-- | lib/libc/asr/asr_private.h | 4 | ||||
-rw-r--r-- | lib/libc/asr/asr_run.3 | 7 | ||||
-rw-r--r-- | lib/libc/asr/asr_utils.c | 22 | ||||
-rw-r--r-- | lib/libc/asr/res_mkquery.c | 6 | ||||
-rw-r--r-- | lib/libc/asr/res_send_async.c | 8 | ||||
-rw-r--r-- | lib/libc/net/resolver.3 | 7 | ||||
-rw-r--r-- | share/man/man5/resolv.conf.5 | 34 |
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 |