diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h index b8910263aef0..ce2f2e062a4c 100644 --- a/include/arpa/nameser.h +++ b/include/arpa/nameser.h @@ -49,7 +49,7 @@ */ /* - * $Id: nameser.h,v 1.7.18.1 2005/04/27 05:00:50 sra Exp $ + * $Id: nameser.h,v 1.7.18.2 2008/04/03 23:15:15 marka Exp $ * $FreeBSD$ */ @@ -424,9 +424,10 @@ typedef enum __ns_cert_types { #define NS_NXT_MAX 127 /*% - * EDNS0 extended flags, host order. + * EDNS0 extended flags and option codes, host order. */ #define NS_OPT_DNSSEC_OK 0x8000U +#define NS_OPT_NSID 3 /*% * Inline versions of get/put short/long. Pointer is advanced. diff --git a/include/resolv.h b/include/resolv.h index ec18f5f00a44..20f7954ecdb8 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -50,7 +50,7 @@ /*% * @(#)resolv.h 8.1 (Berkeley) 6/2/93 - * $Id: resolv.h,v 1.19.18.3 2005/08/25 04:43:51 marka Exp $ + * $Id: resolv.h,v 1.19.18.4 2008/04/03 23:15:15 marka Exp $ * $FreeBSD$ */ @@ -245,6 +245,7 @@ union res_sockaddr_union { #define RES_NOCHECKNAME 0x00008000 /*%< do not check names for sanity. */ #define RES_KEEPTSIG 0x00010000 /*%< do not strip TSIG records */ #define RES_BLAST 0x00020000 /*%< blast all recursive servers */ +#define RES_NSID 0x00040000 /*%< request name server ID */ #define RES_NOTLDQUERY 0x00100000 /*%< don't unqualified name as a tld */ #define RES_USE_DNSSEC 0x00200000 /*%< use DNSSEC using OK bit in OPT */ /* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */ @@ -386,6 +387,7 @@ extern const struct res_sym __p_rcode_syms[]; #define sym_ntos __sym_ntos #define sym_ston __sym_ston #define res_nopt __res_nopt +#define res_nopt_rdata __res_nopt_rdata #define res_ndestroy __res_ndestroy #define res_nametoclass __res_nametoclass #define res_nametotype __res_nametotype @@ -474,6 +476,8 @@ int res_findzonecut2(res_state, const char *, ns_class, int, union res_sockaddr_union *, int); void res_nclose(res_state); int res_nopt(res_state, int, u_char *, int, int); +int res_nopt_rdata(res_state, int, u_char *, int, u_char *, + u_short, u_short, u_char *); void res_send_setqhook(res_send_qhook); void res_send_setrhook(res_send_rhook); int __res_vinit(res_state, int); diff --git a/lib/libc/include/isc/eventlib.h b/lib/libc/include/isc/eventlib.h index 598c71ca80fc..50038231c852 100644 --- a/lib/libc/include/isc/eventlib.h +++ b/lib/libc/include/isc/eventlib.h @@ -18,7 +18,7 @@ /* eventlib.h - exported interfaces for eventlib * vix 09sep95 [initial] * - * $Id: eventlib.h,v 1.3.18.2 2005/07/28 07:38:07 marka Exp $ + * $Id: eventlib.h,v 1.3.18.3 2008/01/23 02:12:01 marka Exp $ */ #ifndef _EVENTLIB_H @@ -29,6 +29,8 @@ #include #include +#include + #ifndef __P # define __EVENTLIB_P_DEFINED # ifdef __STDC__ diff --git a/lib/libc/include/isc/platform.h b/lib/libc/include/isc/platform.h new file mode 100644 index 000000000000..a0513be8dde0 --- /dev/null +++ b/lib/libc/include/isc/platform.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: platform.h.in,v 1.2.6.2 2008/01/23 02:15:02 tbox Exp $ */ +/* $FreeBSD$ */ + +/*! \file */ + +#ifndef ISC_PLATFORM_H +#define ISC_PLATFORM_H + +/* + * Define if the OS does not define struct timespec. + */ +#undef ISC_PLATFORM_NEEDTIMESPEC +#ifdef ISC_PLATFORM_NEEDTIMESPEC +#include /* For time_t */ +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + +#endif diff --git a/lib/libc/inet/inet_net_pton.c b/lib/libc/inet/inet_net_pton.c index 06d1da95124b..74df38b95d68 100644 --- a/lib/libc/inet/inet_net_pton.c +++ b/lib/libc/inet/inet_net_pton.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.1 2005/04/27 05:00:53 sra Exp $"; +static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.2 2008/08/26 04:42:43 marka Exp $"; #endif #include __FBSDID("$FreeBSD$"); @@ -135,11 +135,11 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { assert(n >= 0 && n <= 9); bits *= 10; bits += n; + if (bits > 32) + goto enoent; } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); if (ch != '\0') goto enoent; - if (bits > 32) - goto emsgsize; } /* Firey death and destruction unless we prefetched EOS. */ diff --git a/lib/libc/resolv/res_debug.c b/lib/libc/resolv/res_debug.c index a367a61a8fb9..c2707bb6ca9c 100644 --- a/lib/libc/resolv/res_debug.c +++ b/lib/libc/resolv/res_debug.c @@ -91,7 +91,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_debug.c,v 1.10.18.5 2005/07/28 07:38:11 marka Exp $"; +static const char rcsid[] = "$Id: res_debug.c,v 1.10.18.6 2008/04/03 23:15:15 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -187,10 +187,56 @@ do_section(const res_state statp, p_type(ns_rr_type(rr)), p_class(ns_rr_class(rr))); else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) { + u_int16_t optcode, optlen, rdatalen = ns_rr_rdlen(rr); u_int32_t ttl = ns_rr_ttl(rr); + fprintf(file, "; EDNS: version: %u, udp=%u, flags=%04x\n", (ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff); + + while (rdatalen >= 4) { + const u_char *cp = ns_rr_rdata(rr); + int i; + + GETSHORT(optcode, cp); + GETSHORT(optlen, cp); + + if (optcode == NS_OPT_NSID) { + fputs("; NSID: ", file); + if (optlen == 0) { + fputs("; NSID\n", file); + } else { + fputs("; NSID: ", file); + for (i = 0; i < optlen; i++) + fprintf(file, "%02x ", + cp[i]); + fputs(" (",file); + for (i = 0; i < optlen; i++) + fprintf(file, "%c", + isprint(cp[i])? + cp[i] : '.'); + fputs(")\n", file); + } + } else { + if (optlen == 0) { + fprintf(file, "; OPT=%u\n", + optcode); + } else { + fprintf(file, "; OPT=%u: ", + optcode); + for (i = 0; i < optlen; i++) + fprintf(file, "%02x ", + cp[i]); + fputs(" (",file); + for (i = 0; i < optlen; i++) + fprintf(file, "%c", + isprint(cp[i]) ? + cp[i] : '.'); + fputs(")\n", file); + } + } + rdatalen -= 4 + optlen; + } } else { n = ns_sprintrr(handle, &rr, NULL, NULL, buf, buflen); @@ -202,7 +248,7 @@ do_section(const res_state statp, buf = malloc(buflen += 1024); if (buf == NULL) { fprintf(file, - ";; memory allocation failure\n"); + ";; memory allocation failure\n"); return; } continue; @@ -379,7 +425,7 @@ static const struct res_sym __p_default_section_syms[] = { {ns_s_an, "ANSWER", (char *)0}, {ns_s_ns, "AUTHORITY", (char *)0}, {ns_s_ar, "ADDITIONAL", (char *)0}, - {0, (char *)0, (char *)0} + {0, (char *)0, (char *)0} }; static const struct res_sym __p_update_section_syms[] = { @@ -387,7 +433,7 @@ static const struct res_sym __p_update_section_syms[] = { {S_PREREQ, "PREREQUISITE", (char *)0}, {S_UPDATE, "UPDATE", (char *)0}, {S_ADDT, "ADDITIONAL", (char *)0}, - {0, (char *)0, (char *)0} + {0, (char *)0, (char *)0} }; const struct res_sym __p_key_syms[] = { @@ -615,6 +661,7 @@ p_option(u_long option) { case RES_USE_INET6: return "inet6"; #ifdef RES_USE_EDNS0 /*%< KAME extension */ case RES_USE_EDNS0: return "edns0"; + case RES_NSID: return "nsid"; #endif #ifdef RES_USE_DNAME case RES_USE_DNAME: return "dname"; diff --git a/lib/libc/resolv/res_mkquery.c b/lib/libc/resolv/res_mkquery.c index f823026dce8e..7bd9cda55707 100644 --- a/lib/libc/resolv/res_mkquery.c +++ b/lib/libc/resolv/res_mkquery.c @@ -66,7 +66,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_mkquery.c,v 1.5.18.1 2005/04/27 05:01:11 sra Exp $"; +static const char rcsid[] = "$Id: res_mkquery.c,v 1.5.18.2 2008/04/03 23:15:15 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -201,9 +201,6 @@ res_nmkquery(res_state statp, #ifdef RES_USE_EDNS0 /* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */ -#ifndef T_OPT -#define T_OPT 41 -#endif int res_nopt(res_state statp, @@ -228,15 +225,16 @@ res_nopt(res_state statp, if ((ep - cp) < 1 + RRFIXEDSZ) return (-1); - *cp++ = 0; /*%< "." */ - ns_put16(T_OPT, cp); /*%< TYPE */ + *cp++ = 0; /*%< "." */ + ns_put16(ns_t_opt, cp); /*%< TYPE */ cp += INT16SZ; if (anslen > 0xffff) anslen = 0xffff; /* limit to 16bit value */ - ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */ + ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */ cp += INT16SZ; - *cp++ = NOERROR; /*%< extended RCODE */ - *cp++ = 0; /*%< EDNS version */ + *cp++ = NOERROR; /*%< extended RCODE */ + *cp++ = 0; /*%< EDNS version */ + if (statp->options & RES_USE_DNSSEC) { #ifdef DEBUG if (statp->options & RES_DEBUG) @@ -246,12 +244,60 @@ res_nopt(res_state statp, } ns_put16(flags, cp); cp += INT16SZ; - ns_put16(0, cp); /*%< RDLEN */ + + ns_put16(0U, cp); /*%< RDLEN */ cp += INT16SZ; + hp->arcount = htons(ntohs(hp->arcount) + 1); return (cp - buf); } + +/* + * Construct variable data (RDATA) block for OPT psuedo-RR, append it + * to the buffer, then update the RDLEN field (previously set to zero by + * res_nopt()) with the new RDATA length. + */ +int +res_nopt_rdata(res_state statp, + int n0, /*%< current offset in buffer */ + u_char *buf, /*%< buffer to put query */ + int buflen, /*%< size of buffer */ + u_char *rdata, /*%< ptr to start of opt rdata */ + u_short code, /*%< OPTION-CODE */ + u_short len, /*%< OPTION-LENGTH */ + u_char *data) /*%< OPTION_DATA */ +{ + register u_char *cp, *ep; + +#ifdef DEBUG + if ((statp->options & RES_DEBUG) != 0U) + printf(";; res_nopt_rdata()\n"); +#endif + + cp = buf + n0; + ep = buf + buflen; + + if ((ep - cp) < (4 + len)) + return (-1); + + if (rdata < (buf + 2) || rdata >= ep) + return (-1); + + ns_put16(code, cp); + cp += INT16SZ; + + ns_put16(len, cp); + cp += INT16SZ; + + memcpy(cp, data, len); + cp += len; + + len = cp - rdata; + ns_put16(len, rdata - 2); /* Update RDLEN field */ + + return (cp - buf); +} #endif /*! \file */ diff --git a/lib/libc/resolv/res_query.c b/lib/libc/resolv/res_query.c index 3813291c8ab9..746a2be76b18 100644 --- a/lib/libc/resolv/res_query.c +++ b/lib/libc/resolv/res_query.c @@ -66,7 +66,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_query.c,v 1.7.18.1 2005/04/27 05:01:11 sra Exp $"; +static const char rcsid[] = "$Id: res_query.c,v 1.7.18.2 2008/04/03 23:15:15 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -115,8 +115,9 @@ res_nquery(res_state statp, { u_char buf[MAXPACKET]; HEADER *hp = (HEADER *) answer; - int n; u_int oflags; + u_char *rdata; + int n; oflags = statp->_flags; @@ -131,8 +132,14 @@ res_nquery(res_state statp, buf, sizeof(buf)); #ifdef RES_USE_EDNS0 if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 && - (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U) + (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC|RES_NSID))) { n = res_nopt(statp, n, buf, sizeof(buf), anslen); + rdata = &buf[n]; + if (n > 0 && (statp->options & RES_NSID) != 0U) { + n = res_nopt_rdata(statp, n, buf, sizeof(buf), rdata, + NS_OPT_NSID, 0, NULL); + } + } #endif if (n <= 0) { #ifdef DEBUG @@ -142,6 +149,7 @@ res_nquery(res_state statp, RES_SET_H_ERRNO(statp, NO_RECOVERY); return (n); } + n = res_nsend(statp, buf, n, answer, anslen); if (n < 0) { #ifdef RES_USE_EDNS0 diff --git a/lib/libc/resolv/res_send.c b/lib/libc/resolv/res_send.c index 78410d1c44ef..d4f0c3347dfc 100644 --- a/lib/libc/resolv/res_send.c +++ b/lib/libc/resolv/res_send.c @@ -66,7 +66,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_send.c,v 1.9.18.8 2006/10/16 23:00:58 marka Exp $"; +static const char rcsid[] = "$Id: res_send.c,v 1.9.18.10 2008/01/27 02:06:26 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -302,7 +302,7 @@ int res_nsend(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz) { - int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; + int gotsomewhere, terrno, tries, v_circuit, resplen, ns, n; #ifdef USE_KQUEUE int kq; #endif @@ -420,7 +420,7 @@ res_nsend(res_state statp, /* * Send request, RETRY times, or until successful. */ - for (try = 0; try < statp->retry; try++) { + for (tries = 0; tries < statp->retry; tries++) { for (ns = 0; ns < statp->nscount; ns++) { struct sockaddr *nsap; int nsaplen; @@ -471,7 +471,7 @@ res_nsend(res_state statp, if (v_circuit) { /* Use VC; at most one attempt per server. */ - try = statp->retry; + tries = statp->retry; n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, ns); if (n < 0) @@ -486,7 +486,7 @@ res_nsend(res_state statp, kq, #endif buf, buflen, ans, anssiz, &terrno, - ns, try, &v_circuit, &gotsomewhere); + ns, tries, &v_circuit, &gotsomewhere); if (n < 0) goto fail; if (n == 0) @@ -632,6 +632,9 @@ send_vc(res_state statp, u_short len; u_char *cp; void *tmp; +#ifdef SO_NOSIGPIPE + int on = 1; +#endif nsap = get_nsaddr(statp, ns); nsaplen = get_salen(nsap); @@ -679,6 +682,17 @@ send_vc(res_state statp, return (-1); } } +#ifdef SO_NOSIGPIPE + /* + * Disable generation of SIGPIPE when writing to a closed + * socket. Write should return -1 and set errno to EPIPE + * instead. + * + * Push on even if setsockopt(SO_NOSIGPIPE) fails. + */ + (void)_setsockopt(statp->_vcsock, SOL_SOCKET, SO_NOSIGPIPE, &on, + sizeof(on)); +#endif errno = 0; if (_connect(statp->_vcsock, nsap, nsaplen) < 0) { *terrno = errno; @@ -811,7 +825,7 @@ send_dg(res_state statp, int kq, #endif const u_char *buf, int buflen, u_char *ans, - int anssiz, int *terrno, int ns, int try, int *v_circuit, + int anssiz, int *terrno, int ns, int tries, int *v_circuit, int *gotsomewhere) { const HEADER *hp = (const HEADER *) buf; @@ -915,7 +929,7 @@ send_dg(res_state statp, /* * Wait for reply. */ - seconds = (statp->retrans << try); + seconds = (statp->retrans << tries); if (ns > 0) seconds /= statp->nscount; if (seconds <= 0)