From babc498cc885419b361ac611a3a20343e7c04262 Mon Sep 17 00:00:00 2001 From: itojun Date: Wed, 9 Aug 2000 14:40:52 +0000 Subject: [PATCH] implement EDNS0 support, as EDNS0 support will be made mandatory for IPv6 transport-ready resolvers/DNS servers. need careful configuration when enable it. (default config is not affected). see manpage for details. XXX visible symbol __res_opt() is added, however, it is not supposed to be called from outside, libc minor is not bumped. --- include/arpa/nameser.h | 3 ++- include/resolv.h | 6 ++++- lib/libc/net/getaddrinfo.c | 8 +++++-- lib/libc/net/res_debug.c | 7 ++++-- lib/libc/net/res_init.c | 12 +++++++--- lib/libc/net/res_mkquery.c | 44 +++++++++++++++++++++++++++++++++--- lib/libc/net/res_query.c | 8 +++++-- lib/libc/net/resolver.3 | 10 +++++++- share/man/man5/resolv.conf.5 | 12 +++++++++- 9 files changed, 94 insertions(+), 16 deletions(-) diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h index dc10f9ce4ffa..9e40b4404fda 100644 --- a/include/arpa/nameser.h +++ b/include/arpa/nameser.h @@ -77,7 +77,7 @@ /* * @(#)nameser.h 8.1 (Berkeley) 6/2/93 - * $NetBSD: nameser.h,v 1.13 1998/11/13 15:45:10 christos Exp $ + * $NetBSD: nameser.h,v 1.14 2000/08/09 14:41:00 itojun Exp $ */ #ifndef _ARPA_NAMESER_H_ @@ -181,6 +181,7 @@ #define T_SRV 33 /* Server selection */ #define T_ATMA 34 /* ATM Address */ #define T_NAPTR 35 /* Naming Authority PoinTeR */ +#define T_OPT 41 /* OPT pseudo-RR, RFC2761 */ /* non standard */ #define T_UINFO 100 /* user (finger) information */ #define T_UID 101 /* user ID */ diff --git a/include/resolv.h b/include/resolv.h index e7ff4d85c80c..a4c5fe22e4e6 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -1,4 +1,4 @@ -/* $NetBSD: resolv.h,v 1.18 1999/07/01 18:15:41 itojun Exp $ */ +/* $NetBSD: resolv.h,v 1.19 2000/08/09 14:40:52 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -182,6 +182,8 @@ struct __res_state_ext { #define RES_INSECURE2 0x00000800 /* type 2 security disabled */ #define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */ #define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */ +/* KAME extensions: use higher bit to avoid conflict with ISC use */ +#define RES_USE_EDNS0 0x40000000 /* use EDNS0 */ #define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) @@ -274,6 +276,7 @@ extern const struct res_sym __p_type_syms[]; #define res_nameinquery __res_nameinquery #define res_queriesmatch __res_queriesmatch #define res_close __res_close +#define res_opt __res_opt #ifdef BIND_RES_POSIX3 #define dn_expand __dn_expand @@ -335,6 +338,7 @@ int res_nameinquery __P((const char *, int, int, int res_queriesmatch __P((const u_char *, const u_char *, const u_char *, const u_char *)); void res_close __P((void)); +int res_opt __P((int, u_char *, int, int)); __END_DECLS #endif /* !_RESOLV_H_ */ diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index c5b854ee605f..e1cf8b5ca5c9 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -1,4 +1,4 @@ -/* $NetBSD: getaddrinfo.c,v 1.46 2000/07/09 04:48:17 itojun Exp $ */ +/* $NetBSD: getaddrinfo.c,v 1.47 2000/08/09 14:41:00 itojun Exp $ */ /* $KAME: getaddrinfo.c,v 1.28 2000/07/09 04:37:24 itojun Exp $ */ /* @@ -79,7 +79,7 @@ #include #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: getaddrinfo.c,v 1.46 2000/07/09 04:48:17 itojun Exp $"); +__RCSID("$NetBSD: getaddrinfo.c,v 1.47 2000/08/09 14:41:00 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -1629,6 +1629,10 @@ res_queryN(name, target) n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, buf, sizeof(buf)); +#ifdef RES_USE_EDNS0 + if (n > 0 && (_res.options & RES_USE_EDNS0) != 0) + n = res_opt(n, buf, sizeof(buf), anslen); +#endif if (n <= 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c index b62bf0771ef5..81e612c338d4 100644 --- a/lib/libc/net/res_debug.c +++ b/lib/libc/net/res_debug.c @@ -1,4 +1,4 @@ -/* $NetBSD: res_debug.c,v 1.28 2000/07/08 03:28:01 itojun Exp $ */ +/* $NetBSD: res_debug.c,v 1.29 2000/08/09 14:41:02 itojun Exp $ */ /*- * Copyright (c) 1985, 1990, 1993 @@ -81,7 +81,7 @@ static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; static char rcsid[] = "Id: res_debug.c,v 8.20 1997/06/01 20:34:37 vixie Exp "; #else -__RCSID("$NetBSD: res_debug.c,v 1.28 2000/07/08 03:28:01 itojun Exp $"); +__RCSID("$NetBSD: res_debug.c,v 1.29 2000/08/09 14:41:02 itojun Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -1108,6 +1108,9 @@ __p_option(option) case RES_DNSRCH: return "dnsrch"; case RES_INSECURE1: return "insecure1"; case RES_INSECURE2: return "insecure2"; +#ifdef RES_USE_EDNS0 + case RES_USE_EDNS0: return "edns0"; +#endif default: (void)snprintf(nbuf, sizeof nbuf, "?0x%lx?", (u_long)option); return (nbuf); diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c index 0ca44e26f4a3..b7cbe1b506dd 100644 --- a/lib/libc/net/res_init.c +++ b/lib/libc/net/res_init.c @@ -1,4 +1,4 @@ -/* $NetBSD: res_init.c,v 1.35 2000/07/07 08:03:40 itohy Exp $ */ +/* $NetBSD: res_init.c,v 1.36 2000/08/09 14:41:03 itojun Exp $ */ /*- * Copyright (c) 1985, 1989, 1993 @@ -59,7 +59,7 @@ static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; static char rcsid[] = "Id: res_init.c,v 8.8 1997/06/01 20:34:37 vixie Exp "; #else -__RCSID("$NetBSD: res_init.c,v 1.35 2000/07/07 08:03:40 itohy Exp $"); +__RCSID("$NetBSD: res_init.c,v 1.36 2000/08/09 14:41:03 itojun Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -553,7 +553,13 @@ res_setoptions(options, source) #endif } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { _res.options |= RES_USE_INET6; - } else { + } +#ifdef RES_USE_EDNS0 + else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) { + _res.options |= RES_USE_EDNS0; + } +#endif + else { /* XXX - print a warning here? */ } /* skip to next run of spaces */ diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c index 0828f6b3c834..7f72b37d3bd1 100644 --- a/lib/libc/net/res_mkquery.c +++ b/lib/libc/net/res_mkquery.c @@ -1,4 +1,4 @@ -/* $NetBSD: res_mkquery.c,v 1.19 2000/07/06 03:00:39 christos Exp $ */ +/* $NetBSD: res_mkquery.c,v 1.20 2000/08/09 14:41:04 itojun Exp $ */ /*- * Copyright (c) 1985, 1993 @@ -59,7 +59,7 @@ static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; static char rcsid[] = "Id: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp "; #else -__RCSID("$NetBSD: res_mkquery.c,v 1.19 2000/07/06 03:00:39 christos Exp $"); +__RCSID("$NetBSD: res_mkquery.c,v 1.20 2000/08/09 14:41:04 itojun Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -201,9 +201,47 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) } hp->ancount = htons(1); break; - default: return (-1); } return (cp - buf); } + +#ifdef RES_USE_EDNS0 +/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */ +int +res_opt(n0, buf, buflen, anslen) + int n0; + u_char *buf; /* buffer to put query */ + int buflen; /* size of buffer */ + int anslen; /* answer buffer length */ +{ + register HEADER *hp; + register u_char *cp; + + hp = (HEADER *) buf; + cp = buf + n0; + buflen -= n0; + + if (buflen < 1 + RRFIXEDSZ) + return -1; + + *cp++ = 0; /* "." */ + buflen--; + + __putshort(T_OPT, cp); /* TYPE */ + cp += INT16SZ; + __putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */ + cp += INT16SZ; + *cp++ = NOERROR; /* extended RCODE */ + *cp++ = 0; /* EDNS version */ + __putshort(0, cp); /* MBZ */ + cp += INT16SZ; + __putshort(0, cp); /* RDLEN */ + cp += INT16SZ; + hp->arcount = htons(ntohs(hp->arcount) + 1); + buflen -= RRFIXEDSZ; + + return cp - buf; +} +#endif diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c index b619686c47ce..156832d1e6b2 100644 --- a/lib/libc/net/res_query.c +++ b/lib/libc/net/res_query.c @@ -1,4 +1,4 @@ -/* $NetBSD: res_query.c,v 1.30 2000/07/07 08:03:40 itohy Exp $ */ +/* $NetBSD: res_query.c,v 1.31 2000/08/09 14:41:05 itojun Exp $ */ /*- * Copyright (c) 1988, 1993 @@ -59,7 +59,7 @@ static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; static char rcsid[] = "Id: res_query.c,v 8.10 1997/06/01 20:34:37 vixie Exp "; #else -__RCSID("$NetBSD: res_query.c,v 1.30 2000/07/07 08:03:40 itohy Exp $"); +__RCSID("$NetBSD: res_query.c,v 1.31 2000/08/09 14:41:05 itojun Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -132,6 +132,10 @@ res_query(name, class, type, answer, anslen) n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, buf, sizeof(buf)); +#ifdef RES_USE_EDNS0 + if (n > 0 && (_res.options & RES_USE_EDNS0) != 0) + n = res_opt(n, buf, sizeof(buf), anslen); +#endif if (n <= 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) diff --git a/lib/libc/net/resolver.3 b/lib/libc/net/resolver.3 index fac79ea2e466..783257916e0e 100644 --- a/lib/libc/net/resolver.3 +++ b/lib/libc/net/resolver.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: resolver.3,v 1.12 2000/01/03 11:56:05 itojun Exp $ +.\" $NetBSD: resolver.3,v 1.13 2000/08/09 14:41:05 itojun Exp $ .\" .\" Copyright (c) 1985, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -172,6 +172,14 @@ Enables support for IPv6-only applications. This causes IPv4 addresses to be returned as an IPv4 mapped address. For example, 10.1.1.1 will be returned as ::ffff:10.1.1.1. The option is meaningful with certain kernel configuration only. +.It Dv RES_USE_EDNS0 +Enables support for OPT pseudo-RR for EDNS0 extension. +With the option, resolver code will attach OPT pseudo-RR into DNS queries, +to inform of our receive buffer size. +The option will allow DNS servers to take advantage of non-default receive +buffer size, and to send larger replies. +DNS query packets with EDNS0 extension is not compatible with +non-EDNS0 DNS servers. .El .Pp The diff --git a/share/man/man5/resolv.conf.5 b/share/man/man5/resolv.conf.5 index 06f34b1b8d29..e9bb30069d4d 100644 --- a/share/man/man5/resolv.conf.5 +++ b/share/man/man5/resolv.conf.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: resolv.conf.5,v 1.16 2000/06/15 10:28:50 itojun Exp $ +.\" $NetBSD: resolv.conf.5,v 1.17 2000/08/09 14:41:07 itojun Exp $ .\" .\" Copyright (c) 1986, 1991 The Regents of the University of California. .\" All rights reserved. @@ -143,6 +143,16 @@ where option is one of the following: enable debugging information, by setting RES_DEBUG in _res.options (see .Xr resolver 3 ). +.It Sy edns0 +attach OPT pseudo-RR for ENDS0 extension specified in RFC2671, +to inform DNS server of our receive buffer size. +The option will allow DNS servers to take advantage of non-default receive +buffer size, and to send larger replies. +DNS query packets with EDNS0 extension is not compatible with +non-EDNS0 DNS servers. +The option must be used only when all the DNS servers listed in +.Sy nameserver +lines are able to handle EDNS0 extension. .It Sy inet6 enable support for IPv6-only applications, by setting RES_USE_INET6 in _res.options (see