From 3181f54059d8f111597b6e6ebec0e24f7939ada7 Mon Sep 17 00:00:00 2001 From: itojun <> Date: Mon, 11 Jun 2001 10:06:01 +0000 Subject: support EDNS0 (RFC2671) buffer size notification on DNS queries. "options edns0" in /etc/resolv.conf will enable the behavior. no behavior change if you don't have the line. see resolv.conf(5) for more details. EDNS0 is useful for avoiding TCP DNS queries/replies on larger DNS responses. also, draft-ietf-dnsext-message-size-* plans to mandate EDNS0 support for DNS clients that support IPv6 transport. --- src/lib/libc/net/getaddrinfo.c | 5 ++++- src/lib/libc/net/res_debug.c | 6 ++++-- src/lib/libc/net/res_init.c | 6 ++++-- src/lib/libc/net/res_mkquery.c | 41 +++++++++++++++++++++++++++++++++++++++-- src/lib/libc/net/res_query.c | 7 +++++-- 5 files changed, 56 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/lib/libc/net/getaddrinfo.c b/src/lib/libc/net/getaddrinfo.c index 1326473fb7..0a0b112589 100644 --- a/src/lib/libc/net/getaddrinfo.c +++ b/src/lib/libc/net/getaddrinfo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getaddrinfo.c,v 1.27 2000/08/31 17:41:51 itojun Exp $ */ +/* $OpenBSD: getaddrinfo.c,v 1.28 2001/06/11 10:05:58 itojun Exp $ */ /* $KAME: getaddrinfo.c,v 1.31 2000/08/31 17:36:43 itojun Exp $ */ /* @@ -1511,6 +1511,7 @@ _yp_getaddrinfo(name, pai) extern const char *__hostalias __P((const char *)); extern int h_errno; +extern int res_opt __P((int, u_char *, int, int)); /* * Formulate a normal query, send, and await answer. @@ -1562,6 +1563,8 @@ res_queryN(name, target) n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, buf, sizeof(buf)); + if (n > 0 && (_res.options & RES_USE_EDNS0) != 0) + n = res_opt(n, buf, sizeof(buf), anslen); if (n <= 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c index e1894b1508..54be69cef7 100644 --- a/src/lib/libc/net/res_debug.c +++ b/src/lib/libc/net/res_debug.c @@ -1,4 +1,4 @@ -/* $OpenBSD: res_debug.c,v 1.10 2000/07/07 20:59:47 deraadt Exp $ */ +/* $OpenBSD: res_debug.c,v 1.11 2001/06/11 10:05:59 itojun Exp $ */ /* * ++Copyright++ 1985, 1990, 1993 @@ -82,7 +82,7 @@ static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $"; #else -static char rcsid[] = "$OpenBSD: res_debug.c,v 1.10 2000/07/07 20:59:47 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: res_debug.c,v 1.11 2001/06/11 10:05:59 itojun Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -1028,6 +1028,8 @@ __p_option(option) case RES_DNSRCH: return "dnsrch"; case RES_INSECURE1: return "insecure1"; case RES_INSECURE2: return "insecure2"; + case RES_USE_INET6: return "inet6"; + case RES_USE_EDNS0: return "edns0"; default: sprintf(nbuf, "?0x%lx?", (u_long)option); return (nbuf); } diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c index bba8cfaad1..c44539604a 100644 --- a/src/lib/libc/net/res_init.c +++ b/src/lib/libc/net/res_init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: res_init.c,v 1.20 2000/11/10 15:33:04 provos Exp $ */ +/* $OpenBSD: res_init.c,v 1.21 2001/06/11 10:06:00 itojun Exp $ */ /* * ++Copyright++ 1985, 1989, 1993 @@ -64,7 +64,7 @@ static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $"; #else -static char rcsid[] = "$OpenBSD: res_init.c,v 1.20 2000/11/10 15:33:04 provos Exp $"; +static char rcsid[] = "$OpenBSD: res_init.c,v 1.21 2001/06/11 10:06:00 itojun Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -608,6 +608,8 @@ res_setoptions(options, source) #endif } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { _res.options |= RES_USE_INET6; + } else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) { + _res.options |= RES_USE_EDNS0; } else { /* XXX - print a warning here? */ } diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c index 3e7e2ae5d3..61595a6e8c 100644 --- a/src/lib/libc/net/res_mkquery.c +++ b/src/lib/libc/net/res_mkquery.c @@ -1,4 +1,4 @@ -/* $OpenBSD: res_mkquery.c,v 1.8 1997/04/13 22:37:21 provos Exp $ */ +/* $OpenBSD: res_mkquery.c,v 1.9 2001/06/11 10:06:00 itojun Exp $ */ /* * ++Copyright++ 1985, 1993 @@ -60,7 +60,7 @@ static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $"; #else -static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.8 1997/04/13 22:37:21 provos Exp $"; +static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.9 2001/06/11 10:06:00 itojun Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -193,3 +193,40 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) } return (cp - buf); } + +/* 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; +} diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c index 01d1f691cb..433e80f648 100644 --- a/src/lib/libc/net/res_query.c +++ b/src/lib/libc/net/res_query.c @@ -1,4 +1,4 @@ -/* $OpenBSD: res_query.c,v 1.13 1999/09/27 23:58:26 alex Exp $ */ +/* $OpenBSD: res_query.c,v 1.14 2001/06/11 10:06:01 itojun Exp $ */ /* * ++Copyright++ 1988, 1993 @@ -60,7 +60,7 @@ static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $"; #else -static char rcsid[] = "$OpenBSD: res_query.c,v 1.13 1999/09/27 23:58:26 alex Exp $"; +static char rcsid[] = "$OpenBSD: res_query.c,v 1.14 2001/06/11 10:06:01 itojun Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -87,6 +87,7 @@ static char rcsid[] = "$OpenBSD: res_query.c,v 1.13 1999/09/27 23:58:26 alex Exp const char *hostalias __P((const char *)); int h_errno; +extern int res_opt __P((int, u_char *, int, int)); /* * Formulate a normal query, send, and await answer. @@ -122,6 +123,8 @@ res_query(name, class, type, answer, anslen) n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, buf, sizeof(buf)); + if (n > 0 && (_res.options & RES_USE_EDNS0) != 0) + n = res_opt(n, buf, sizeof(buf), anslen); if (n <= 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) -- cgit v1.2.3-55-g6feb