diff -pruN /home/reed/src/isc/libbind/libbind/resolv/__dn_comp.c /usr/src/lib/libc/resolv/__dn_comp.c --- /home/reed/src/isc/libbind/libbind/resolv/__dn_comp.c 1969-12-31 18:00:00.000000000 -0600 +++ /usr/src/lib/libc/resolv/__dn_comp.c 2012-10-24 08:34:37.000000000 -0500 @@ -0,0 +1,34 @@ +/* $NetBSD: __dn_comp.c,v 1.5 2007/01/17 16:39:20 seanb Exp $ */ + +/* + * written by matthew green, 22/04/97. + * public domain. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: __dn_comp.c,v 1.5 2007/01/17 16:39:20 seanb Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#if defined(__indr_reference) +__indr_reference(__dn_comp,dn_comp) +#else + +#include +#include +#include + +/* XXX THIS IS A MESS! SEE XXX */ + +#undef dn_comp +int dn_comp(const char *, u_char *, int, u_char **, u_char **); + +int +dn_comp(const char *exp_dn, u_char *comp_dn, int length, u_char **dnptrs, + u_char **lastdnptr) +{ + + return __dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr); +} + +#endif diff -pruN /home/reed/src/isc/libbind/libbind/resolv/__res_close.c /usr/src/lib/libc/resolv/__res_close.c --- /home/reed/src/isc/libbind/libbind/resolv/__res_close.c 1969-12-31 18:00:00.000000000 -0600 +++ /usr/src/lib/libc/resolv/__res_close.c 2005-09-12 20:44:10.000000000 -0500 @@ -0,0 +1,33 @@ +/* $NetBSD: __res_close.c,v 1.4 2005/09/13 01:44:10 christos Exp $ */ + +/* + * written by matthew green, 22/04/97. + * public domain. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: __res_close.c,v 1.4 2005/09/13 01:44:10 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#if defined(__indr_reference) +__indr_reference(__res_close, res_close) +#else + +#include +#include +#include + +/* XXX THIS IS A MESS! SEE XXX */ + +#undef res_close +void res_close(void); + +void +res_close(void) +{ + + __res_close(); +} + +#endif diff -pruN /home/reed/src/isc/libbind/libbind/resolv/__res_send.c /usr/src/lib/libc/resolv/__res_send.c --- /home/reed/src/isc/libbind/libbind/resolv/__res_send.c 1969-12-31 18:00:00.000000000 -0600 +++ /usr/src/lib/libc/resolv/__res_send.c 2005-09-12 20:44:10.000000000 -0500 @@ -0,0 +1,33 @@ +/* $NetBSD: __res_send.c,v 1.4 2005/09/13 01:44:10 christos Exp $ */ + +/* + * written by matthew green, 22/04/97. + * public domain. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: __res_send.c,v 1.4 2005/09/13 01:44:10 christos Exp $"); +#endif + +#if defined(__indr_reference) +__indr_reference(__res_send, res_send) +#else + +#include +#include +#include + +/* XXX THIS IS A MESS! SEE XXX */ + +#undef res_send +int res_send(const u_char *, int, u_char *, int); + +int +res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) +{ + + return __res_send(buf, buflen, ans, anssiz); +} + +#endif diff -pruN /home/reed/src/isc/libbind/libbind/resolv/h_errno.c /usr/src/lib/libc/resolv/h_errno.c --- /home/reed/src/isc/libbind/libbind/resolv/h_errno.c 1969-12-31 18:00:00.000000000 -0600 +++ /usr/src/lib/libc/resolv/h_errno.c 2012-10-24 08:34:37.000000000 -0500 @@ -0,0 +1,58 @@ +/* $NetBSD: h_errno.c,v 1.3 2008/06/21 20:41:48 christos Exp $ */ + +/*- + * Copyright (c) 2004 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: h_errno.c,v 1.3 2008/06/21 20:41:48 christos Exp $"); +#endif + +#include +#include +#include +#include +#include + +#undef h_errno + +extern int h_errno; +extern struct __res_state _nres; + +int * +__h_errno(void) +{ + return &_nres.res_h_errno; +} + +void +__h_errno_set(res_state res, int err) +{ + h_errno = res->res_h_errno = err; +} diff -pruN /home/reed/src/isc/libbind/libbind/resolv/herror.c /usr/src/lib/libc/resolv/herror.c --- /home/reed/src/isc/libbind/libbind/resolv/herror.c 2013-06-05 09:33:54.000000000 -0500 +++ /usr/src/lib/libc/resolv/herror.c 2013-06-05 09:26:14.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: herror.c,v 1.9 2012/03/13 21:13:43 christos Exp $ */ + /* * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -10,7 +12,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -44,13 +50,19 @@ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #if defined(LIBC_SCCS) && !defined(lint) +#ifdef notdef static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: herror.c,v 1.5 2013-01-06 23:14:54 marka Exp $"; +static const char rcsid[] = "Id: herror.c,v 1.4 2005/04/27 04:56:41 sra Exp"; +#else +__RCSID("$NetBSD: herror.c,v 1.9 2012/03/13 21:13:43 christos Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ #include "port_before.h" +#include "namespace.h" #include #include #include @@ -62,7 +74,6 @@ static const char rcsid[] = "$Id: herror #include #include #include -#include #include "port_after.h" @@ -80,6 +91,10 @@ int h_nerr = { sizeof h_errlist / sizeof int h_errno; #endif +#ifdef __weak_alias +__weak_alias(herror,_herror) +#endif + /*% * herror -- * print the error indicated by the h_errno value. @@ -106,7 +121,7 @@ herror(const char *s) { DE_CONST("\n", t); v->iov_base = t; v->iov_len = 1; - writev(STDERR_FILENO, iov, (v - iov) + 1); + (void)writev(STDERR_FILENO, iov, (int)((v - iov) + 1)); } /*% diff -pruN /home/reed/src/isc/libbind/libbind/resolv/mtctxres.c /usr/src/lib/libc/resolv/mtctxres.c --- /home/reed/src/isc/libbind/libbind/resolv/mtctxres.c 2006-03-09 17:57:56.000000000 -0600 +++ /usr/src/lib/libc/resolv/mtctxres.c 2012-10-24 08:34:38.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: mtctxres.c,v 1.4 2007/03/30 20:40:52 ghen Exp $ */ + #include #ifdef DO_PTHREADS #include @@ -7,7 +9,6 @@ #include #include #include -#include #include #ifdef DO_PTHREADS diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_comp.c /usr/src/lib/libc/resolv/res_comp.c --- /home/reed/src/isc/libbind/libbind/resolv/res_comp.c 2013-06-05 09:33:54.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_comp.c 2013-06-05 09:26:14.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: res_comp.c,v 1.12 2012/03/13 21:13:43 christos Exp $ */ + /* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. @@ -10,7 +12,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -63,17 +69,24 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - +#include #if defined(LIBC_SCCS) && !defined(lint) +#ifdef notdef static const char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_comp.c,v 1.6 2013-01-06 23:14:54 marka Exp $"; +static const char rcsid[] = "Id: res_comp.c,v 1.5 2005/07/28 06:51:50 marka Exp"; +#else +__RCSID("$NetBSD: res_comp.c,v 1.12 2012/03/13 21:13:43 christos Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ #include "port_before.h" + +#include "namespace.h" #include #include #include #include +#include #include #include #include @@ -81,6 +94,18 @@ static const char rcsid[] = "$Id: res_co #include #include "port_after.h" +#ifdef __weak_alias +__weak_alias(dn_expand,_dn_expand) +__weak_alias(dn_comp,__dn_comp) +#if 0 +__weak_alias(dn_skipname,__dn_skipname) +__weak_alias(res_hnok,__res_hnok) +__weak_alias(res_ownok,__res_ownok) +__weak_alias(res_mailok,__res_mailok) +__weak_alias(res_dnok,__res_dnok) +#endif +#endif + /*% * Expand compressed domain name 'src' to full domain name. * @@ -111,8 +136,8 @@ dn_comp(const char *src, u_char *dst, in u_char **dnptrs, u_char **lastdnptr) { return (ns_name_compress(src, dst, (size_t)dstsiz, - (const u_char **)dnptrs, - (const u_char **)lastdnptr)); + (void *)dnptrs, + (void *)lastdnptr)); } /*% @@ -124,7 +149,8 @@ dn_skipname(const u_char *ptr, const u_c if (ns_name_skip(&ptr, eom) == -1) return (-1); - return (ptr - saveptr); + _DIAGASSERT(__type_fit(int, ptr - saveptr)); + return (int)(ptr - saveptr); } /*% @@ -156,7 +182,7 @@ res_hnok(const char *dn) { int nch = *dn++; if (periodchar(ch)) { - (void)NULL; + ; } else if (periodchar(pch)) { if (!borderchar(ch)) return (0); diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_compat.c /usr/src/lib/libc/resolv/res_compat.c --- /home/reed/src/isc/libbind/libbind/resolv/res_compat.c 1969-12-31 18:00:00.000000000 -0600 +++ /usr/src/lib/libc/resolv/res_compat.c 2012-10-24 08:34:38.000000000 -0500 @@ -0,0 +1,76 @@ +/* $NetBSD: res_compat.c,v 1.3 2009/11/22 18:04:37 mbalmer Exp $ */ + +/*- + * Copyright (c) 2004 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: res_compat.c,v 1.3 2009/11/22 18:04:37 mbalmer Exp $"); +#endif + +#include +#include +#include +#include +#include +#define __OLD_RES_STATE +#include + +#undef _res + +/* + * Binary Compatibility; this symbol does not appear in a header file + * Most userland programs use this to set res_options before res_init() + * is called. There are hooks to res_init() to consult the data in this + * structure. The hooks are provided indirectly by the two functions below. + * We depend on the fact the first 440 [32 bit machines] bytes are + * shared between the two structures. + */ +#ifndef __BIND_NOSTATIC +struct __res_state _res +#if defined(__BIND_RES_TEXT) + = { RES_TIMEOUT, } /* Motorola, et al. */ +# endif +; + +void *__res_get_old_state(void); +void __res_put_old_state(void *); + +void * +__res_get_old_state(void) +{ + return &_res; +} + +void +__res_put_old_state(void *res) +{ + (void)memcpy(&_res, res, sizeof(_res)); +} +#endif diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_data.c /usr/src/lib/libc/resolv/res_data.c --- /home/reed/src/isc/libbind/libbind/resolv/res_data.c 2009-01-20 19:28:19.000000000 -0600 +++ /usr/src/lib/libc/resolv/res_data.c 2012-10-24 08:34:38.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: res_data.c,v 1.14 2009/10/24 05:35:37 christos Exp $ */ + /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-1999 by Internet Software Consortium. @@ -15,12 +17,18 @@ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp $"; +#ifdef notdef +static const char rcsid[] = "Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp"; +#else +__RCSID("$NetBSD: res_data.c,v 1.14 2009/10/24 05:35:37 christos Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ #include "port_before.h" +#include "namespace.h" #include #include #include @@ -41,6 +49,29 @@ static const char rcsid[] = "$Id: res_da #include "port_after.h" +#include "res_private.h" + +#ifdef __weak_alias +__weak_alias(res_init,_res_init) +__weak_alias(res_mkquery,_res_mkquery) +__weak_alias(res_query,_res_query) +__weak_alias(res_search,_res_search) +__weak_alias(res_send,__res_send) +__weak_alias(res_close,__res_close) +/* XXX: these leaked in the old bind8 libc */ +__weak_alias(res_querydomain,__res_querydomain) +__weak_alias(res_send_setqhook,__res_send_setqhook) +__weak_alias(res_send_setrhook,__res_send_setrhook) +#if 0 +__weak_alias(p_query,__p_query) +__weak_alias(fp_query,__fp_query) +__weak_alias(fp_nquery,__fp_nquery) +__weak_alias(res_isourserver,__res_isourserver) +__weak_alias(res_opt,_res_opt) +__weak_alias(hostalias,__hostalias) +#endif +#endif + const char *_res_opcodes[] = { "QUERY", "IQUERY", @@ -69,25 +100,34 @@ const char *_res_sectioncodes[] = { }; #endif -#undef _res -#ifndef __BIND_NOSTATIC -struct __res_state _res -# if defined(__BIND_RES_TEXT) - = { RES_TIMEOUT, } /*%< Motorola, et al. */ -# endif - ; - -#if defined(DO_PTHREADS) || defined(__linux) -#define _res (*__res_state()) -#endif +#ifndef __BIND_NOSTATIC +extern struct __res_state _nres; /* Proto. */ -int res_ourserver_p(const res_state, const struct sockaddr_in *); +int res_ourserver_p(const res_state, const struct sockaddr *); int res_init(void) { - extern int __res_vinit(res_state, int); + int rv; +#ifdef COMPAT__RES + /* + * Compatibility with program that were accessing _res directly + * to set options. We keep another struct res that is the same + * size as the original res structure, and then copy fields to + * it so that we achieve the same initialization + */ + extern void *__res_get_old_state(void); + extern void __res_put_old_state(void *); + res_state ores = __res_get_old_state(); + + if (ores->options != 0) + _nres.options = ores->options; + if (ores->retrans != 0) + _nres.retrans = ores->retrans; + if (ores->retry != 0) + _nres.retry = ores->retry; +#endif /* * These three fields used to be statically initialized. This made @@ -102,27 +142,31 @@ res_init(void) { * so one can safely assume that the applications were already getting * unexpected results. * - * _res.options is tricky since some apps were known to diddle the bits + * _nres.options is tricky since some apps were known to diddle the bits * before res_init() was first called. We can't replicate that semantic * with dynamic initialization (they may have turned bits off that are * set in RES_DEFAULT). Our solution is to declare such applications * "broken". They could fool us by setting RES_INIT but none do (yet). */ - if (!_res.retrans) - _res.retrans = RES_TIMEOUT; - if (!_res.retry) - _res.retry = 4; - if (!(_res.options & RES_INIT)) - _res.options = RES_DEFAULT; + if (!_nres.retrans) + _nres.retrans = RES_TIMEOUT; + if (!_nres.retry) + _nres.retry = 4; + if (!(_nres.options & RES_INIT)) + _nres.options = RES_DEFAULT; /* * This one used to initialize implicitly to zero, so unless the app * has set it to something in particular, we can randomize it now. */ - if (!_res.id) - _res.id = res_nrandomid(&_res); + if (!_nres.id) + _nres.id = res_nrandomid(&_nres); - return (__res_vinit(&_res, 1)); + rv = __res_vinit(&_nres, 1); +#ifdef COMPAT__RES + __res_put_old_state(&_nres); +#endif + return rv; } void @@ -137,10 +181,10 @@ fp_query(const u_char *msg, FILE *file) void fp_nquery(const u_char *msg, int len, FILE *file) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) return; - res_pquery(&_res, msg, len, file); + res_pquery(&_nres, msg, len, file); } int @@ -153,24 +197,26 @@ res_mkquery(int op, /*!< opcode of que u_char *buf, /*!< buffer to put query */ int buflen) /*!< size of buffer */ { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL); return (-1); } - return (res_nmkquery(&_res, op, dname, class, type, + return (res_nmkquery(&_nres, op, dname, class, type, data, datalen, newrr_in, buf, buflen)); } +#ifdef _LIBRESOLV int res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL); return (-1); } - return (res_nmkupdate(&_res, rrecp_in, buf, buflen)); + return (res_nmkupdate(&_nres, rrecp_in, buf, buflen)); } +#endif int res_query(const char *name, /*!< domain name */ @@ -178,64 +224,68 @@ res_query(const char *name, /*!< domain u_char *answer, /*!< buffer to put answer */ int anslen) /*!< size of answer buffer */ { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL); return (-1); } - return (res_nquery(&_res, name, class, type, answer, anslen)); + return (res_nquery(&_nres, name, class, type, answer, anslen)); } void res_send_setqhook(res_send_qhook hook) { - _res.qhook = hook; + _nres.qhook = hook; } void res_send_setrhook(res_send_rhook hook) { - _res.rhook = hook; + _nres.rhook = hook; } int res_isourserver(const struct sockaddr_in *inp) { - return (res_ourserver_p(&_res, inp)); + return (res_ourserver_p(&_nres, (const struct sockaddr *)(const void *)inp)); } int res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { /* errno should have been set by res_init() in this case. */ return (-1); } - return (res_nsend(&_res, buf, buflen, ans, anssiz)); + return (res_nsend(&_nres, buf, buflen, ans, anssiz)); } +#ifdef _LIBRESOLV int res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, u_char *ans, int anssiz) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { /* errno should have been set by res_init() in this case. */ return (-1); } - return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz)); + return (res_nsendsigned(&_nres, buf, buflen, key, ans, anssiz)); } +#endif void res_close(void) { - res_nclose(&_res); + res_nclose(&_nres); } +#ifdef _LIBRESOLV int res_update(ns_updrec *rrecp_in) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL); return (-1); } - return (res_nupdate(&_res, rrecp_in, NULL)); + return (res_nupdate(&_nres, rrecp_in, NULL)); } +#endif int res_search(const char *name, /*!< domain name */ @@ -243,12 +293,12 @@ res_search(const char *name, /*!< domain u_char *answer, /*!< buffer to put answer */ int anslen) /*!< size of answer */ { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL); return (-1); } - return (res_nsearch(&_res, name, class, type, answer, anslen)); + return (res_nsearch(&_nres, name, class, type, answer, anslen)); } int @@ -258,31 +308,37 @@ res_querydomain(const char *name, u_char *answer, /*!< buffer to put answer */ int anslen) /*!< size of answer */ { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL); return (-1); } - return (res_nquerydomain(&_res, name, domain, + return (res_nquerydomain(&_nres, name, domain, class, type, answer, anslen)); } +int +res_opt(int a, u_char *b, int c, int d) +{ + return res_nopt(&_nres, a, b, c, d); +} + u_int res_randomid(void) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { + if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); - return (-1); + return (u_int)-1; } - return (res_nrandomid(&_res)); + return (res_nrandomid(&_nres)); } const char * hostalias(const char *name) { static char abuf[MAXDNAME]; - return (res_hostalias(&_res, name, abuf, sizeof abuf)); + return (res_hostalias(&_nres, name, abuf, sizeof abuf)); } #ifdef ultrix @@ -290,12 +346,12 @@ int local_hostname_length(const char *hostname) { int len_host, len_domain; - if (!*_res.defdname) + if (!*_nres.defdname) res_init(); len_host = strlen(hostname); - len_domain = strlen(_res.defdname); + len_domain = strlen(_nres.defdname); if (len_host > len_domain && - !strcasecmp(hostname + len_host - len_domain, _res.defdname) && + !strcasecmp(hostname + len_host - len_domain, _nres.defdname) && hostname[len_host - len_domain - 1] == '.') return (len_host - len_domain - 1); return (0); diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_debug.c /usr/src/lib/libc/resolv/res_debug.c --- /home/reed/src/isc/libbind/libbind/resolv/res_debug.c 2013-06-05 09:33:54.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_debug.c 2013-06-05 09:26:14.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $ */ + /* * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2003 Internet Software Consortium. @@ -27,7 +29,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -89,13 +95,19 @@ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ +#include #if defined(LIBC_SCCS) && !defined(lint) +#ifdef notdef static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_debug.c,v 1.20 2013-01-06 23:14:54 marka Exp $"; +static const char rcsid[] = "Id: res_debug.c,v 1.19 2009/02/26 11:20:20 tbox Exp"; +#else +__RCSID("$NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ #include "port_before.h" +#include "namespace.h" #include #include #include @@ -104,6 +116,7 @@ static const char rcsid[] = "$Id: res_de #include #include +#include #include #include #include @@ -126,6 +139,15 @@ static const char rcsid[] = "$Id: res_de extern const char *_res_opcodes[]; extern const char *_res_sectioncodes[]; +#if 0 +#ifdef __weak_alias +__weak_alias(res_pquery,__res_pquery) +__weak_alias(res_nametoclass,__res_nametoclass) +__weak_alias(res_nametotype,__res_nametotype) +#endif +#endif + +#ifndef _LIBC /*% * Print the current options. */ @@ -139,6 +161,7 @@ fp_resstat(const res_state statp, FILE * fprintf(file, " %s", p_option(mask)); putc('\n', file); } +#endif static void do_section(const res_state statp, @@ -154,11 +177,11 @@ do_section(const res_state statp, /* * Print answer records. */ - sflag = (statp->pfcode & pflag); + sflag = (int)(statp->pfcode & pflag); if (statp->pfcode && !sflag) return; - buf = malloc(buflen); + buf = malloc((size_t)buflen); if (buf == NULL) { fprintf(file, ";; memory allocation failure\n"); return; @@ -185,11 +208,14 @@ 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); + size_t rdatalen, ttl; + uint16_t optcode, optlen; + + rdatalen = ns_rr_rdlen(rr); + ttl = ns_rr_ttl(rr); fprintf(file, - "; EDNS: version: %u, udp=%u, flags=%04x\n", + "; EDNS: version: %zu, udp=%u, flags=%04zx\n", (ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff); while (rdatalen >= 4) { @@ -237,13 +263,13 @@ do_section(const res_state statp, } } else { n = ns_sprintrr(handle, &rr, NULL, NULL, - buf, buflen); + buf, (u_int)buflen); if (n < 0) { if (errno == ENOSPC) { free(buf); buf = NULL; if (buflen < 131072) - buf = malloc(buflen += 1024); + buf = malloc((size_t)(buflen += 1024)); if (buf == NULL) { fprintf(file, ";; memory allocation failure\n"); @@ -293,7 +319,7 @@ res_pquery(const res_state statp, const if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode) fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n", - _res_opcodes[opcode], p_rcode(rcode), id); + _res_opcodes[opcode], p_rcode((int)rcode), id); if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX)) putc(';', file); if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) { @@ -317,13 +343,13 @@ res_pquery(const res_state statp, const } if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) { fprintf(file, "; %s: %d", - p_section(ns_s_qd, opcode), qdcount); + p_section(ns_s_qd, (int)opcode), qdcount); fprintf(file, ", %s: %d", - p_section(ns_s_an, opcode), ancount); + p_section(ns_s_an, (int)opcode), ancount); fprintf(file, ", %s: %d", - p_section(ns_s_ns, opcode), nscount); + p_section(ns_s_ns, (int)opcode), nscount); fprintf(file, ", %s: %d", - p_section(ns_s_ar, opcode), arcount); + p_section(ns_s_ar, (int)opcode), arcount); } if ((!statp->pfcode) || (statp->pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { @@ -346,7 +372,7 @@ p_cdnname(const u_char *cp, const u_char char name[MAXDNAME]; int n; - if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0) + if ((n = dn_expand(msg, msg + len, cp, name, (int)sizeof name)) < 0) return (NULL); if (name[0] == '\0') putc('.', file); @@ -365,19 +391,17 @@ p_cdname(const u_char *cp, const u_char length supplied). */ const u_char * -p_fqnname(cp, msg, msglen, name, namelen) - const u_char *cp, *msg; - int msglen; - char *name; - int namelen; +p_fqnname(const u_char *cp, const u_char *msg, int msglen, char *name, + int namelen) { - int n, newlen; + int n; + size_t newlen; if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0) return (NULL); newlen = strlen(name); if (newlen == 0 || name[newlen - 1] != '.') { - if (newlen + 1 >= namelen) /*%< Lack space for final dot */ + if ((int)newlen + 1 >= namelen) /*%< Lack space for final dot */ return (NULL); else strcpy(name + newlen, "."); @@ -392,7 +416,7 @@ p_fqname(const u_char *cp, const u_char char name[MAXDNAME]; const u_char *n; - n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name); + n = p_fqnname(cp, msg, MAXCDNAME, name, (int)sizeof name); if (n == NULL) return (NULL); fputs(name, file); @@ -553,7 +577,7 @@ const struct res_sym __p_rcode_syms[] = int sym_ston(const struct res_sym *syms, const char *name, int *success) { - for ((void)NULL; syms->name != 0; syms++) { + for (; syms->name != 0; syms++) { if (strcasecmp (name, syms->name) == 0) { if (success) *success = 1; @@ -569,7 +593,7 @@ const char * sym_ntos(const struct res_sym *syms, int number, int *success) { char *unname = sym_ntos_unname; - for ((void)NULL; syms->name != 0; syms++) { + for (; syms->name != 0; syms++) { if (number == syms->number) { if (success) *success = 1; @@ -587,7 +611,7 @@ const char * sym_ntop(const struct res_sym *syms, int number, int *success) { char *unname = sym_ntop_unname; - for ((void)NULL; syms->name != 0; syms++) { + for (; syms->name != 0; syms++) { if (number == syms->number) { if (success) *success = 1; @@ -705,7 +729,7 @@ const char * p_time(u_int32_t value) { char *nbuf = p_time_nbuf; - if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0) + if (ns_format_ttl((u_long)value, nbuf, sizeof nbuf) < 0) sprintf(nbuf, "%u", value); return (nbuf); } @@ -727,7 +751,7 @@ p_sockun(union res_sockaddr_union u, cha switch (u.sin.sin_family) { case AF_INET: - inet_ntop(AF_INET, &u.sin.sin_addr, ret, sizeof ret); + inet_ntop(AF_INET, &u.sin.sin_addr, ret, (socklen_t)sizeof ret); break; #ifdef HAS_INET6_STRUCTS case AF_INET6: @@ -756,8 +780,7 @@ static unsigned int poweroften[10] = {1, /*% takes an XeY precision/size value, returns a string representation. */ static const char * -precsize_ntoa(prec) - u_int8_t prec; +precsize_ntoa(u_int32_t prec) { char *retbuf = precsize_ntoa_retbuf; unsigned long val; @@ -910,9 +933,7 @@ latlon2ul(const char **latlonstrptr, int * converts a zone file representation in a string to an RDATA on-the-wire * representation. */ int -loc_aton(ascii, binary) - const char *ascii; - u_char *binary; +loc_aton(const char *ascii, u_char *binary) { const char *cp, *maxcp; u_char *bcp; @@ -1021,9 +1042,7 @@ loc_aton(ascii, binary) /*% takes an on-the-wire LOC RR and formats it in a human readable format. */ const char * -loc_ntoa(binary, ascii) - const u_char *binary; - char *ascii; +loc_ntoa(const u_char *binary, char *ascii) { static const char *error = "?"; static char tmpbuf[sizeof @@ -1105,9 +1124,9 @@ loc_ntoa(binary, ascii) altfrac = altval % 100; altmeters = (altval / 100); - sizestr = strdup(precsize_ntoa(sizeval)); - hpstr = strdup(precsize_ntoa(hpval)); - vpstr = strdup(precsize_ntoa(vpval)); + sizestr = strdup(precsize_ntoa((u_int32_t)sizeval)); + hpstr = strdup(precsize_ntoa((u_int32_t)hpval)); + vpstr = strdup(precsize_ntoa((u_int32_t)vpval)); sprintf(ascii, "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm", @@ -1132,7 +1151,7 @@ loc_ntoa(binary, ascii) /*% Return the number of DNS hierarchy levels in the name. */ int dn_count_labels(const char *name) { - int i, len, count; + size_t len, i, count; len = strlen(name); for (i = 0, count = 0; i < len; i++) { @@ -1151,7 +1170,8 @@ dn_count_labels(const char *name) { /* count to include last label */ if (len > 0 && name[len-1] != '.') count++; - return (count); + _DIAGASSERT(__type_fit(int, count)); + return (int)count; } /*% @@ -1160,21 +1180,22 @@ dn_count_labels(const char *name) { */ char * p_secstodate (u_long secs) { + /* XXX nonreentrant */ char *output = p_secstodate_output; - time_t clock = secs; - struct tm *time; + time_t myclock = secs; + struct tm *mytime; #ifdef HAVE_TIME_R struct tm res; - - time = gmtime_r(&clock, &res); + + mytime = gmtime_r(&myclock, &res); #else - time = gmtime(&clock); + mytime = gmtime(&myclock); #endif - time->tm_year += 1900; - time->tm_mon += 1; + mytime->tm_year += 1900; + mytime->tm_mon += 1; sprintf(output, "%04d%02d%02d%02d%02d%02d", - time->tm_year, time->tm_mon, time->tm_mday, - time->tm_hour, time->tm_min, time->tm_sec); + mytime->tm_year, mytime->tm_mon, mytime->tm_mday, + mytime->tm_hour, mytime->tm_min, mytime->tm_sec); return (output); } @@ -1198,7 +1219,7 @@ res_nametoclass(const char *buf, int *su done: if (successp) *successp = success; - return (result); + return (u_int16_t)(result); } u_int16_t @@ -1221,7 +1242,7 @@ res_nametotype(const char *buf, int *suc done: if (successp) *successp = success; - return (result); + return (u_int16_t)(result); } /*! \file */ diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_debug.h /usr/src/lib/libc/resolv/res_debug.h --- /home/reed/src/isc/libbind/libbind/resolv/res_debug.h 2005-04-26 23:56:41.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_debug.h 2013-06-05 09:26:14.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: res_debug.h,v 1.2 2012/03/13 21:13:43 christos Exp $ */ + /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999 by Internet Software Consortium. @@ -27,7 +29,7 @@ # define Dprint(cond, args) if (cond) {fprintf args;} else {} # define DprintQ(cond, args, query, size) if (cond) {\ fprintf args;\ - res_pquery(statp, query, size, stdout);\ + res_pquery(statp, (query), (int)(size), stdout);\ } else {} #endif diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_findzonecut.c /usr/src/lib/libc/resolv/res_findzonecut.c --- /home/reed/src/isc/libbind/libbind/resolv/res_findzonecut.c 2005-10-10 19:10:16.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_findzonecut.c 1969-12-31 18:00:00.000000000 -0600 @@ -1,722 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_findzonecut.c,v 1.10 2005/10/11 00:10:16 marka Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and 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. - */ - -/* Import. */ - -#include "port_before.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "port_after.h" - -#include - -/* Data structures. */ - -typedef struct rr_a { - LINK(struct rr_a) link; - union res_sockaddr_union addr; -} rr_a; -typedef LIST(rr_a) rrset_a; - -typedef struct rr_ns { - LINK(struct rr_ns) link; - const char * name; - unsigned int flags; - rrset_a addrs; -} rr_ns; -typedef LIST(rr_ns) rrset_ns; - -#define RR_NS_HAVE_V4 0x01 -#define RR_NS_HAVE_V6 0x02 - -/* Forward. */ - -static int satisfy(res_state, const char *, rrset_ns *, - union res_sockaddr_union *, int); -static int add_addrs(res_state, rr_ns *, - union res_sockaddr_union *, int); -static int get_soa(res_state, const char *, ns_class, int, - char *, size_t, char *, size_t, - rrset_ns *); -static int get_ns(res_state, const char *, ns_class, int, rrset_ns *); -static int get_glue(res_state, ns_class, int, rrset_ns *); -static int save_ns(res_state, ns_msg *, ns_sect, - const char *, ns_class, int, rrset_ns *); -static int save_a(res_state, ns_msg *, ns_sect, - const char *, ns_class, int, rr_ns *); -static void free_nsrrset(rrset_ns *); -static void free_nsrr(rrset_ns *, rr_ns *); -static rr_ns * find_ns(rrset_ns *, const char *); -static int do_query(res_state, const char *, ns_class, ns_type, - u_char *, ns_msg *); -static void res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2); - -/* Macros. */ - -#define DPRINTF(x) do {\ - int save_errno = errno; \ - if ((statp->options & RES_DEBUG) != 0U) res_dprintf x; \ - errno = save_errno; \ - } while (0) - -/* Public. */ - -/*% - * find enclosing zone for a , and some server addresses - * - * parameters: - *\li res - resolver context to work within (is modified) - *\li dname - domain name whose enclosing zone is desired - *\li class - class of dname (and its enclosing zone) - *\li zname - found zone name - *\li zsize - allocated size of zname - *\li addrs - found server addresses - *\li naddrs - max number of addrs - * - * return values: - *\li < 0 - an error occurred (check errno) - *\li = 0 - zname is now valid, but addrs[] wasn't changed - *\li > 0 - zname is now valid, and return value is number of addrs[] found - * - * notes: - *\li this function calls res_nsend() which means it depends on correctly - * functioning recursive nameservers (usually defined in /etc/resolv.conf - * or its local equivilent). - * - *\li we start by asking for an SOA. if we get one as an - * answer, that just means is a zone top, which is fine. - * more than likely we'll be told to go pound sand, in the form of a - * negative answer. - * - *\li note that we are not prepared to deal with referrals since that would - * only come from authority servers and our correctly functioning local - * recursive server would have followed the referral and got us something - * more definite. - * - *\li if the authority section contains an SOA, this SOA should also be the - * closest enclosing zone, since any intermediary zone cuts would've been - * returned as referrals and dealt with by our correctly functioning local - * recursive name server. but an SOA in the authority section should NOT - * match our dname (since that would have been returned in the answer - * section). an authority section SOA has to be "above" our dname. - * - *\li however, since authority section SOA's were once optional, it's - * possible that we'll have to go hunting for the enclosing SOA by - * ripping labels off the front of our dname -- this is known as "doing - * it the hard way." - * - *\li ultimately we want some server addresses, which are ideally the ones - * pertaining to the SOA.MNAME, but only if there is a matching NS RR. - * so the second phase (after we find an SOA) is to go looking for the - * NS RRset for that SOA's zone. - * - *\li no answer section processed by this code is allowed to contain CNAME - * or DNAME RR's. for the SOA query this means we strip a label and - * keep going. for the NS and A queries this means we just give up. - */ - -int -res_findzonecut(res_state statp, const char *dname, ns_class class, int opts, - char *zname, size_t zsize, struct in_addr *addrs, int naddrs) -{ - int result, i; - union res_sockaddr_union *u; - - - opts |= RES_IPV4ONLY; - opts &= ~RES_IPV6ONLY; - - u = calloc(naddrs, sizeof(*u)); - if (u == NULL) - return(-1); - - result = res_findzonecut2(statp, dname, class, opts, zname, zsize, - u, naddrs); - - for (i = 0; i < result; i++) { - addrs[i] = u[i].sin.sin_addr; - } - free(u); - return (result); -} - -int -res_findzonecut2(res_state statp, const char *dname, ns_class class, int opts, - char *zname, size_t zsize, union res_sockaddr_union *addrs, - int naddrs) -{ - char mname[NS_MAXDNAME]; - u_long save_pfcode; - rrset_ns nsrrs; - int n; - - DPRINTF(("START dname='%s' class=%s, zsize=%ld, naddrs=%d", - dname, p_class(class), (long)zsize, naddrs)); - save_pfcode = statp->pfcode; - statp->pfcode |= RES_PRF_HEAD2 | RES_PRF_HEAD1 | RES_PRF_HEADX | - RES_PRF_QUES | RES_PRF_ANS | - RES_PRF_AUTH | RES_PRF_ADD; - INIT_LIST(nsrrs); - - DPRINTF(("get the soa, and see if it has enough glue")); - if ((n = get_soa(statp, dname, class, opts, zname, zsize, - mname, sizeof mname, &nsrrs)) < 0 || - ((opts & RES_EXHAUSTIVE) == 0 && - (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0)) - goto done; - - DPRINTF(("get the ns rrset and see if it has enough glue")); - if ((n = get_ns(statp, zname, class, opts, &nsrrs)) < 0 || - ((opts & RES_EXHAUSTIVE) == 0 && - (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0)) - goto done; - - DPRINTF(("get the missing glue and see if it's finally enough")); - if ((n = get_glue(statp, class, opts, &nsrrs)) >= 0) - n = satisfy(statp, mname, &nsrrs, addrs, naddrs); - - done: - DPRINTF(("FINISH n=%d (%s)", n, (n < 0) ? strerror(errno) : "OK")); - free_nsrrset(&nsrrs); - statp->pfcode = save_pfcode; - return (n); -} - -/* Private. */ - -static int -satisfy(res_state statp, const char *mname, rrset_ns *nsrrsp, - union res_sockaddr_union *addrs, int naddrs) -{ - rr_ns *nsrr; - int n, x; - - n = 0; - nsrr = find_ns(nsrrsp, mname); - if (nsrr != NULL) { - x = add_addrs(statp, nsrr, addrs, naddrs); - addrs += x; - naddrs -= x; - n += x; - } - for (nsrr = HEAD(*nsrrsp); - nsrr != NULL && naddrs > 0; - nsrr = NEXT(nsrr, link)) - if (ns_samename(nsrr->name, mname) != 1) { - x = add_addrs(statp, nsrr, addrs, naddrs); - addrs += x; - naddrs -= x; - n += x; - } - DPRINTF(("satisfy(%s): %d", mname, n)); - return (n); -} - -static int -add_addrs(res_state statp, rr_ns *nsrr, - union res_sockaddr_union *addrs, int naddrs) -{ - rr_a *arr; - int n = 0; - - for (arr = HEAD(nsrr->addrs); arr != NULL; arr = NEXT(arr, link)) { - if (naddrs <= 0) - return (0); - *addrs++ = arr->addr; - naddrs--; - n++; - } - DPRINTF(("add_addrs: %d", n)); - return (n); -} - -static int -get_soa(res_state statp, const char *dname, ns_class class, int opts, - char *zname, size_t zsize, char *mname, size_t msize, - rrset_ns *nsrrsp) -{ - char tname[NS_MAXDNAME]; - u_char *resp = NULL; - int n, i, ancount, nscount; - ns_sect sect; - ns_msg msg; - u_int rcode; - - /* - * Find closest enclosing SOA, even if it's for the root zone. - */ - - /* First canonicalize dname (exactly one unescaped trailing "."). */ - if (ns_makecanon(dname, tname, sizeof tname) < 0) - goto cleanup; - dname = tname; - - resp = malloc(NS_MAXMSG); - if (resp == NULL) - goto cleanup; - - /* Now grovel the subdomains, hunting for an SOA answer or auth. */ - for (;;) { - /* Leading or inter-label '.' are skipped here. */ - while (*dname == '.') - dname++; - - /* Is there an SOA? */ - n = do_query(statp, dname, class, ns_t_soa, resp, &msg); - if (n < 0) { - DPRINTF(("get_soa: do_query('%s', %s) failed (%d)", - dname, p_class(class), n)); - goto cleanup; - } - if (n > 0) { - DPRINTF(("get_soa: CNAME or DNAME found")); - sect = ns_s_max, n = 0; - } else { - rcode = ns_msg_getflag(msg, ns_f_rcode); - ancount = ns_msg_count(msg, ns_s_an); - nscount = ns_msg_count(msg, ns_s_ns); - if (ancount > 0 && rcode == ns_r_noerror) - sect = ns_s_an, n = ancount; - else if (nscount > 0) - sect = ns_s_ns, n = nscount; - else - sect = ns_s_max, n = 0; - } - for (i = 0; i < n; i++) { - const char *t; - const u_char *rdata; - ns_rr rr; - - if (ns_parserr(&msg, sect, i, &rr) < 0) { - DPRINTF(("get_soa: ns_parserr(%s, %d) failed", - p_section(sect, ns_o_query), i)); - goto cleanup; - } - if (ns_rr_type(rr) == ns_t_cname || - ns_rr_type(rr) == ns_t_dname) - break; - if (ns_rr_type(rr) != ns_t_soa || - ns_rr_class(rr) != class) - continue; - t = ns_rr_name(rr); - switch (sect) { - case ns_s_an: - if (ns_samedomain(dname, t) == 0) { - DPRINTF( - ("get_soa: ns_samedomain('%s', '%s') == 0", - dname, t) - ); - errno = EPROTOTYPE; - goto cleanup; - } - break; - case ns_s_ns: - if (ns_samename(dname, t) == 1 || - ns_samedomain(dname, t) == 0) { - DPRINTF( - ("get_soa: ns_samename() || !ns_samedomain('%s', '%s')", - dname, t) - ); - errno = EPROTOTYPE; - goto cleanup; - } - break; - default: - abort(); - } - if (strlen(t) + 1 > zsize) { - DPRINTF(("get_soa: zname(%lu) too small (%lu)", - (unsigned long)zsize, - (unsigned long)strlen(t) + 1)); - errno = EMSGSIZE; - goto cleanup; - } - strcpy(zname, t); - rdata = ns_rr_rdata(rr); - if (ns_name_uncompress(resp, ns_msg_end(msg), rdata, - mname, msize) < 0) { - DPRINTF(("get_soa: ns_name_uncompress failed") - ); - goto cleanup; - } - if (save_ns(statp, &msg, ns_s_ns, - zname, class, opts, nsrrsp) < 0) { - DPRINTF(("get_soa: save_ns failed")); - goto cleanup; - } - free(resp); - return (0); - } - - /* If we're out of labels, then not even "." has an SOA! */ - if (*dname == '\0') - break; - - /* Find label-terminating "."; top of loop will skip it. */ - while (*dname != '.') { - if (*dname == '\\') - if (*++dname == '\0') { - errno = EMSGSIZE; - goto cleanup; - } - dname++; - } - } - DPRINTF(("get_soa: out of labels")); - errno = EDESTADDRREQ; - cleanup: - if (resp != NULL) - free(resp); - return (-1); -} - -static int -get_ns(res_state statp, const char *zname, ns_class class, int opts, - rrset_ns *nsrrsp) -{ - u_char *resp; - ns_msg msg; - int n; - - resp = malloc(NS_MAXMSG); - if (resp == NULL) - return (-1); - - /* Go and get the NS RRs for this zone. */ - n = do_query(statp, zname, class, ns_t_ns, resp, &msg); - if (n != 0) { - DPRINTF(("get_ns: do_query('%s', %s) failed (%d)", - zname, p_class(class), n)); - free(resp); - return (-1); - } - - /* Remember the NS RRs and associated A RRs that came back. */ - if (save_ns(statp, &msg, ns_s_an, zname, class, opts, nsrrsp) < 0) { - DPRINTF(("get_ns save_ns('%s', %s) failed", - zname, p_class(class))); - free(resp); - return (-1); - } - - free(resp); - return (0); -} - -static int -get_glue(res_state statp, ns_class class, int opts, rrset_ns *nsrrsp) { - rr_ns *nsrr, *nsrr_n; - u_char *resp; - - resp = malloc(NS_MAXMSG); - if (resp == NULL) - return(-1); - - /* Go and get the A RRs for each empty NS RR on our list. */ - for (nsrr = HEAD(*nsrrsp); nsrr != NULL; nsrr = nsrr_n) { - ns_msg msg; - int n; - - nsrr_n = NEXT(nsrr, link); - - if ((nsrr->flags & RR_NS_HAVE_V4) == 0) { - n = do_query(statp, nsrr->name, class, ns_t_a, - resp, &msg); - if (n < 0) { - DPRINTF( - ("get_glue: do_query('%s', %s') failed", - nsrr->name, p_class(class))); - goto cleanup; - } - if (n > 0) { - DPRINTF(( - "get_glue: do_query('%s', %s') CNAME or DNAME found", - nsrr->name, p_class(class))); - } - if (save_a(statp, &msg, ns_s_an, nsrr->name, class, - opts, nsrr) < 0) { - DPRINTF(("get_glue: save_r('%s', %s) failed", - nsrr->name, p_class(class))); - goto cleanup; - } - } - - if ((nsrr->flags & RR_NS_HAVE_V6) == 0) { - n = do_query(statp, nsrr->name, class, ns_t_aaaa, - resp, &msg); - if (n < 0) { - DPRINTF( - ("get_glue: do_query('%s', %s') failed", - nsrr->name, p_class(class))); - goto cleanup; - } - if (n > 0) { - DPRINTF(( - "get_glue: do_query('%s', %s') CNAME or DNAME found", - nsrr->name, p_class(class))); - } - if (save_a(statp, &msg, ns_s_an, nsrr->name, class, - opts, nsrr) < 0) { - DPRINTF(("get_glue: save_r('%s', %s) failed", - nsrr->name, p_class(class))); - goto cleanup; - } - } - - /* If it's still empty, it's just chaff. */ - if (EMPTY(nsrr->addrs)) { - DPRINTF(("get_glue: removing empty '%s' NS", - nsrr->name)); - free_nsrr(nsrrsp, nsrr); - } - } - free(resp); - return (0); - - cleanup: - free(resp); - return (-1); -} - -static int -save_ns(res_state statp, ns_msg *msg, ns_sect sect, - const char *owner, ns_class class, int opts, - rrset_ns *nsrrsp) -{ - int i; - - for (i = 0; i < ns_msg_count(*msg, sect); i++) { - char tname[MAXDNAME]; - const u_char *rdata; - rr_ns *nsrr; - ns_rr rr; - - if (ns_parserr(msg, sect, i, &rr) < 0) { - DPRINTF(("save_ns: ns_parserr(%s, %d) failed", - p_section(sect, ns_o_query), i)); - return (-1); - } - if (ns_rr_type(rr) != ns_t_ns || - ns_rr_class(rr) != class || - ns_samename(ns_rr_name(rr), owner) != 1) - continue; - nsrr = find_ns(nsrrsp, ns_rr_name(rr)); - if (nsrr == NULL) { - nsrr = malloc(sizeof *nsrr); - if (nsrr == NULL) { - DPRINTF(("save_ns: malloc failed")); - return (-1); - } - rdata = ns_rr_rdata(rr); - if (ns_name_uncompress(ns_msg_base(*msg), - ns_msg_end(*msg), rdata, - tname, sizeof tname) < 0) { - DPRINTF(("save_ns: ns_name_uncompress failed") - ); - free(nsrr); - return (-1); - } - nsrr->name = strdup(tname); - if (nsrr->name == NULL) { - DPRINTF(("save_ns: strdup failed")); - free(nsrr); - return (-1); - } - INIT_LINK(nsrr, link); - INIT_LIST(nsrr->addrs); - nsrr->flags = 0; - APPEND(*nsrrsp, nsrr, link); - } - if (save_a(statp, msg, ns_s_ar, - nsrr->name, class, opts, nsrr) < 0) { - DPRINTF(("save_ns: save_r('%s', %s) failed", - nsrr->name, p_class(class))); - return (-1); - } - } - return (0); -} - -static int -save_a(res_state statp, ns_msg *msg, ns_sect sect, - const char *owner, ns_class class, int opts, - rr_ns *nsrr) -{ - int i; - - for (i = 0; i < ns_msg_count(*msg, sect); i++) { - ns_rr rr; - rr_a *arr; - - if (ns_parserr(msg, sect, i, &rr) < 0) { - DPRINTF(("save_a: ns_parserr(%s, %d) failed", - p_section(sect, ns_o_query), i)); - return (-1); - } - if ((ns_rr_type(rr) != ns_t_a && - ns_rr_type(rr) != ns_t_aaaa) || - ns_rr_class(rr) != class || - ns_samename(ns_rr_name(rr), owner) != 1 || - ns_rr_rdlen(rr) != NS_INADDRSZ) - continue; - if ((opts & RES_IPV6ONLY) != 0 && ns_rr_type(rr) != ns_t_aaaa) - continue; - if ((opts & RES_IPV4ONLY) != 0 && ns_rr_type(rr) != ns_t_a) - continue; - arr = malloc(sizeof *arr); - if (arr == NULL) { - DPRINTF(("save_a: malloc failed")); - return (-1); - } - INIT_LINK(arr, link); - memset(&arr->addr, 0, sizeof(arr->addr)); - switch (ns_rr_type(rr)) { - case ns_t_a: - arr->addr.sin.sin_family = AF_INET; -#ifdef HAVE_SA_LEN - arr->addr.sin.sin_len = sizeof(arr->addr.sin); -#endif - memcpy(&arr->addr.sin.sin_addr, ns_rr_rdata(rr), - NS_INADDRSZ); - arr->addr.sin.sin_port = htons(NAMESERVER_PORT); - nsrr->flags |= RR_NS_HAVE_V4; - break; - case ns_t_aaaa: - arr->addr.sin6.sin6_family = AF_INET6; -#ifdef HAVE_SA_LEN - arr->addr.sin6.sin6_len = sizeof(arr->addr.sin6); -#endif - memcpy(&arr->addr.sin6.sin6_addr, ns_rr_rdata(rr), 16); - arr->addr.sin.sin_port = htons(NAMESERVER_PORT); - nsrr->flags |= RR_NS_HAVE_V6; - break; - default: - abort(); - } - APPEND(nsrr->addrs, arr, link); - } - return (0); -} - -static void -free_nsrrset(rrset_ns *nsrrsp) { - rr_ns *nsrr; - - while ((nsrr = HEAD(*nsrrsp)) != NULL) - free_nsrr(nsrrsp, nsrr); -} - -static void -free_nsrr(rrset_ns *nsrrsp, rr_ns *nsrr) { - rr_a *arr; - char *tmp; - - while ((arr = HEAD(nsrr->addrs)) != NULL) { - UNLINK(nsrr->addrs, arr, link); - free(arr); - } - DE_CONST(nsrr->name, tmp); - free(tmp); - UNLINK(*nsrrsp, nsrr, link); - free(nsrr); -} - -static rr_ns * -find_ns(rrset_ns *nsrrsp, const char *dname) { - rr_ns *nsrr; - - for (nsrr = HEAD(*nsrrsp); nsrr != NULL; nsrr = NEXT(nsrr, link)) - if (ns_samename(nsrr->name, dname) == 1) - return (nsrr); - return (NULL); -} - -static int -do_query(res_state statp, const char *dname, ns_class class, ns_type qtype, - u_char *resp, ns_msg *msg) -{ - u_char req[NS_PACKETSZ]; - int i, n; - - n = res_nmkquery(statp, ns_o_query, dname, class, qtype, - NULL, 0, NULL, req, NS_PACKETSZ); - if (n < 0) { - DPRINTF(("do_query: res_nmkquery failed")); - return (-1); - } - n = res_nsend(statp, req, n, resp, NS_MAXMSG); - if (n < 0) { - DPRINTF(("do_query: res_nsend failed")); - return (-1); - } - if (n == 0) { - DPRINTF(("do_query: res_nsend returned 0")); - errno = EMSGSIZE; - return (-1); - } - if (ns_initparse(resp, n, msg) < 0) { - DPRINTF(("do_query: ns_initparse failed")); - return (-1); - } - n = 0; - for (i = 0; i < ns_msg_count(*msg, ns_s_an); i++) { - ns_rr rr; - - if (ns_parserr(msg, ns_s_an, i, &rr) < 0) { - DPRINTF(("do_query: ns_parserr failed")); - return (-1); - } - n += (ns_rr_class(rr) == class && - (ns_rr_type(rr) == ns_t_cname || - ns_rr_type(rr) == ns_t_dname)); - } - return (n); -} - -static void -res_dprintf(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - fputs(";; res_findzonecut: ", stderr); - vfprintf(stderr, fmt, ap); - fputc('\n', stderr); - va_end(ap); -} - -/*! \file */ diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_init.c /usr/src/lib/libc/resolv/res_init.c --- /home/reed/src/isc/libbind/libbind/resolv/res_init.c 2013-04-04 17:43:30.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_init.c 2013-06-05 09:26:14.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: res_init.c,v 1.26 2012/09/09 18:04:26 christos Exp $ */ + /* * Copyright (c) 1985, 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -10,7 +12,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -64,17 +70,25 @@ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #if defined(LIBC_SCCS) && !defined(lint) +#ifdef notdef static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; -static const char rcsid[] = "$Id: res_init.c,v 1.29 2013-01-06 23:14:54 marka Exp $"; +static const char rcsid[] = "Id: res_init.c,v 1.26 2008/12/11 09:59:00 marka Exp"; +#else +__RCSID("$NetBSD: res_init.c,v 1.26 2012/09/09 18:04:26 christos Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ #include "port_before.h" +#include "namespace.h" #include #include #include +#include #include +#include #include #include @@ -85,8 +99,12 @@ static const char rcsid[] = "$Id: res_in #include #include #include +#include #include +#define HAVE_MD5 +#include + #ifndef HAVE_MD5 # include "../dst/md5.h" #else @@ -100,31 +118,50 @@ static const char rcsid[] = "$Id: res_in #include "port_after.h" +#if 0 +#ifdef __weak_alias +__weak_alias(res_ninit,_res_ninit) +__weak_alias(res_randomid,__res_randomid) +__weak_alias(res_nclose,_res_nclose) +__weak_alias(res_ndestroy,_res_ndestroy) +__weak_alias(res_get_nibblesuffix,__res_get_nibblesuffix) +__weak_alias(res_get_nibblesuffix2,__res_get_nibblesuffix2) +__weak_alias(res_getservers,__res_getservers) +__weak_alias(res_setservers,__res_setservers) +#endif +#endif + + /* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */ #include #include "res_private.h" -/*% Options. Should all be left alone. */ #define RESOLVSORT +/*% Options. Should all be left alone. */ +#ifndef DEBUG #define DEBUG +#endif #ifdef SOLARIS2 #include #endif -static void res_setoptions __P((res_state, const char *, const char *)); +static void res_setoptions(res_state, const char *, const char *); #ifdef RESOLVSORT static const char sort_mask[] = "/&"; #define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL) -static u_int32_t net_mask __P((struct in_addr)); +static uint32_t net_mask(struct in_addr); #endif #if !defined(isascii) /*%< XXX - could be a function */ # define isascii(c) (!(c & 0200)) #endif +static struct timespec __res_conf_time; +static const struct timespec ts = { 0, 0 }; + /* * Resolver state default settings. */ @@ -152,8 +189,6 @@ static u_int32_t net_mask __P((struct in */ int res_ninit(res_state statp) { - extern int __res_vinit(res_state, int); - return (__res_vinit(statp, 0)); } @@ -176,16 +211,18 @@ __res_vinit(res_state statp, int preinit int maxns = MAXNS; RES_SET_H_ERRNO(statp, 0); - if (statp->_u._ext.ext != NULL) + + if ((statp->options & RES_INIT) != 0U) res_ndestroy(statp); if (!preinit) { statp->retrans = RES_TIMEOUT; statp->retry = RES_DFLRETRY; statp->options = RES_DEFAULT; - res_rndinit(statp); - statp->id = res_nrandomid(statp); } + statp->_rnd = malloc(16); + res_rndinit(statp); + statp->id = res_nrandomid(statp); memset(u, 0, sizeof(u)); #ifdef USELOOPBACK @@ -262,9 +299,8 @@ __res_vinit(res_state statp, int preinit buf[0] = '.'; cp = strchr(buf, '.'); cp = (cp == NULL) ? buf : (cp + 1); - strncpy(statp->defdname, cp, - sizeof(statp->defdname) - 1); - statp->defdname[sizeof(statp->defdname) - 1] = '\0'; + (void)strlcpy(statp->defdname, cp, + sizeof(statp->defdname)); } } #endif /* SOLARIS2 */ @@ -310,9 +346,12 @@ __res_vinit(res_state statp, int preinit line[sizeof(name) - 1] == '\t')) nserv = 0; - if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { + if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) { + struct stat st; + struct kevent kc; + /* read the config file */ - while (fgets(buf, sizeof(buf), fp) != NULL) { + while (fgets(buf, (int)sizeof(buf), fp) != NULL) { /* skip comments */ if (*buf == ';' || *buf == '#') continue; @@ -458,7 +497,19 @@ __res_vinit(res_state statp, int preinit #ifdef RESOLVSORT statp->nsort = nsort; #endif + statp->_u._ext.ext->resfd = dup(fileno(fp)); (void) fclose(fp); + if (fstat(statp->_u._ext.ext->resfd, &st) != -1) + __res_conf_time = statp->_u._ext.ext->res_conf_time = + st.st_mtimespec; + statp->_u._ext.ext->kq = kqueue1(O_CLOEXEC); + EV_SET(&kc, statp->_u._ext.ext->resfd, EVFILT_VNODE, + EV_ADD|EV_ENABLE|EV_CLEAR, NOTE_DELETE|NOTE_WRITE| NOTE_EXTEND| + NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE, 0, 0); + (void)kevent(statp->_u._ext.ext->kq, &kc, 1, NULL, 0, &ts); + } else { + statp->_u._ext.ext->kq = -1; + statp->_u._ext.ext->resfd = -1; } /* * Last chance to get a nameserver. This should not normally @@ -509,11 +560,45 @@ __res_vinit(res_state statp, int preinit return (statp->res_h_errno); } +int +res_check(res_state statp, struct timespec *mtime) +{ + /* + * If the times are equal, then we check if there + * was a kevent related to resolv.conf and reload. + * If the times are not equal, then we don't bother + * to check the kevent, because another thread already + * did, loaded and changed the time. + */ + if (timespeccmp(&statp->_u._ext.ext->res_conf_time, + &__res_conf_time, ==)) { + struct kevent ke; + if (statp->_u._ext.ext->kq == -1) + goto out; + + switch (kevent(statp->_u._ext.ext->kq, NULL, 0, &ke, 1, &ts)) { + case 0: + case -1: +out: + if (mtime) + *mtime = __res_conf_time; + return 0; + default: + break; + } + } + (void)__res_vinit(statp, 0); + if (mtime) + *mtime = __res_conf_time; + return 1; +} + static void res_setoptions(res_state statp, const char *options, const char *source) { const char *cp = options; int i; + size_t j; struct __res_state_ext *ext = statp->_u._ext.ext; #ifdef DEBUG @@ -590,11 +675,12 @@ res_setoptions(res_state statp, const ch statp->options |= RES_USE_INET6; } else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) { statp->options |= RES_ROTATE; - } else if (!strncmp(cp, "blast", sizeof("blast") - 1)) { - statp->options |= RES_BLAST; } else if (!strncmp(cp, "no-check-names", sizeof("no-check-names") - 1)) { statp->options |= RES_NOCHECKNAME; + } else if (!strncmp(cp, "check-names", + sizeof("check-names") - 1)) { + statp->options &= ~RES_NOCHECKNAME; } #ifdef RES_USE_EDNS0 else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) { @@ -608,17 +694,17 @@ res_setoptions(res_state statp, const ch if (ext == NULL) goto skip; cp += sizeof("nibble:") - 1; - i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1); - strncpy(ext->nsuffix, cp, i); - ext->nsuffix[i] = '\0'; + j = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1); + strncpy(ext->nsuffix, cp, j); + ext->nsuffix[j] = '\0'; } else if (!strncmp(cp, "nibble2:", sizeof("nibble2:") - 1)) { if (ext == NULL) goto skip; cp += sizeof("nibble2:") - 1; - i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix2) - 1); - strncpy(ext->nsuffix2, cp, i); - ext->nsuffix2[i] = '\0'; + j = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix2) - 1); + strncpy(ext->nsuffix2, cp, j); + ext->nsuffix2[j] = '\0'; } else if (!strncmp(cp, "v6revmode:", sizeof("v6revmode:") - 1)) { cp += sizeof("v6revmode:") - 1; @@ -642,11 +728,10 @@ res_setoptions(res_state statp, const ch #ifdef RESOLVSORT /* XXX - should really support CIDR which means explicit masks always. */ -static u_int32_t -net_mask(in) /*!< XXX - should really use system's version of this */ - struct in_addr in; +static uint32_t +net_mask(struct in_addr in) /*!< XXX - should really use system's version of this */ { - register u_int32_t i = ntohl(in.s_addr); + register uint32_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return (htonl(IN_CLASSA_NET)); @@ -656,43 +741,48 @@ net_mask(in) /*!< XXX - should really u } #endif +static u_char srnd[16]; + void res_rndinit(res_state statp) { struct timeval now; - u_int32_t u32; - u_int16_t u16; + uint32_t u32; + uint16_t u16; + u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; gettimeofday(&now, NULL); - u32 = now.tv_sec; - memcpy(statp->_u._ext._rnd, &u32, 4); + u32 = (uint32_t)now.tv_sec; + memcpy(rnd, &u32, 4); u32 = now.tv_usec; - memcpy(statp->_u._ext._rnd + 4, &u32, 4); - u32 += now.tv_sec; - memcpy(statp->_u._ext._rnd + 8, &u32, 4); + memcpy(rnd + 4, &u32, 4); + u32 += (uint32_t)now.tv_sec; + memcpy(rnd + 8, &u32, 4); u16 = getpid(); - memcpy(statp->_u._ext._rnd + 12, &u16, 2); + memcpy(rnd + 12, &u16, 2); } u_int -res_nrandomid(res_state statp) { +res_nrandomid(res_state statp) +{ struct timeval now; - u_int16_t u16; + uint16_t u16; MD5_CTX ctx; + u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; gettimeofday(&now, NULL); - u16 = (u_int16_t) (now.tv_sec ^ now.tv_usec); - memcpy(statp->_u._ext._rnd + 14, &u16, 2); + u16 = (uint16_t) (now.tv_sec ^ now.tv_usec); + memcpy(rnd + 14, &u16, 2); #ifndef HAVE_MD5 MD5_Init(&ctx); - MD5_Update(&ctx, statp->_u._ext._rnd, 16); - MD5_Final(statp->_u._ext._rnd, &ctx); + MD5_Update(&ctx, rnd, 16); + MD5_Final(rnd, &ctx); #else MD5Init(&ctx); - MD5Update(&ctx, statp->_u._ext._rnd, 16); - MD5Final(statp->_u._ext._rnd, &ctx); + MD5Update(&ctx, rnd, 16); + MD5Final(rnd, &ctx); #endif - memcpy(&u16, statp->_u._ext._rnd + 14, 2); + memcpy(&u16, rnd + 14, 2); return ((u_int) u16); } @@ -704,7 +794,8 @@ res_nrandomid(res_state statp) { * This routine is not expected to be user visible. */ void -res_nclose(res_state statp) { +res_nclose(res_state statp) +{ int ns; if (statp->_vcsock >= 0) { @@ -721,30 +812,43 @@ res_nclose(res_state statp) { } void -res_ndestroy(res_state statp) { +res_ndestroy(res_state statp) +{ res_nclose(statp); - if (statp->_u._ext.ext != NULL) + if (statp->_u._ext.ext != NULL) { + if (statp->_u._ext.ext->kq != -1) + (void)close(statp->_u._ext.ext->kq); + if (statp->_u._ext.ext->resfd != -1) + (void)close(statp->_u._ext.ext->resfd); free(statp->_u._ext.ext); + statp->_u._ext.ext = NULL; + } + if (statp->_rnd != NULL) { + free(statp->_rnd); + statp->_rnd = NULL; + } statp->options &= ~RES_INIT; - statp->_u._ext.ext = NULL; } const char * -res_get_nibblesuffix(res_state statp) { +res_get_nibblesuffix(res_state statp) +{ if (statp->_u._ext.ext) return (statp->_u._ext.ext->nsuffix); return ("ip6.arpa"); } const char * -res_get_nibblesuffix2(res_state statp) { +res_get_nibblesuffix2(res_state statp) +{ if (statp->_u._ext.ext) return (statp->_u._ext.ext->nsuffix2); return ("ip6.int"); } void -res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt) { +res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt) +{ int i, nserv; size_t size; @@ -795,10 +899,11 @@ res_setservers(res_state statp, const un } int -res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) { +res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) +{ int i; size_t size; - u_int16_t family; + uint16_t family; for (i = 0; i < statp->nscount && i < cnt; i++) { if (statp->_u._ext.ext) diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_mkquery.c /usr/src/lib/libc/resolv/res_mkquery.c --- /home/reed/src/isc/libbind/libbind/resolv/res_mkquery.c 2013-06-05 09:33:54.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_mkquery.c 2013-06-05 09:26:14.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: res_mkquery.c,v 1.13 2012/03/13 21:13:43 christos Exp $ */ + /* * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996, 1997, 1988, 1999, 2001, 2003 Internet Software Consortium. @@ -27,7 +29,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -64,24 +70,41 @@ * SOFTWARE. */ +#include #if defined(LIBC_SCCS) && !defined(lint) +#ifdef notdef static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_mkquery.c,v 1.11 2013-01-06 23:14:54 marka Exp $"; +static const char rcsid[] = "Id: res_mkquery.c,v 1.10 2008/12/11 09:59:00 marka Exp"; +#else +__RCSID("$NetBSD: res_mkquery.c,v 1.13 2012/03/13 21:13:43 christos Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ #include "port_before.h" + +#include "namespace.h" #include #include #include #include +#include #include #include #include #include #include "port_after.h" +#if 0 +#ifdef __weak_alias +__weak_alias(res_nmkquery,_res_nmkquery) +__weak_alias(res_nopt,_res_nopt) +#endif +#endif + /* Options. Leave them on. */ +#ifndef DEBUG #define DEBUG +#endif extern const char *_res_opcodes[]; @@ -118,7 +141,7 @@ res_nmkquery(res_state statp, if ((buf == NULL) || (buflen < HFIXEDSZ)) return (-1); memset(buf, 0, HFIXEDSZ); - hp = (HEADER *) buf; + hp = (HEADER *)(void *)buf; statp->id = res_nrandomid(statp); hp->id = htons(statp->id); hp->opcode = op; @@ -138,7 +161,7 @@ res_nmkquery(res_state statp, case NS_NOTIFY_OP: if (ep - cp < QFIXEDSZ) return (-1); - if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs, + if ((n = dn_comp(dname, cp, (int)(ep - cp - QFIXEDSZ), dnptrs, lastdnptr)) < 0) return (-1); cp += n; @@ -154,7 +177,7 @@ res_nmkquery(res_state statp, */ if ((ep - cp) < RRFIXEDSZ) return (-1); - n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ, + n = dn_comp((const char *)data, cp, (int)(ep - cp - RRFIXEDSZ), dnptrs, lastdnptr); if (n < 0) return (-1); @@ -186,7 +209,7 @@ res_nmkquery(res_state statp, ns_put16(datalen, cp); cp += INT16SZ; if (datalen) { - memcpy(cp, data, datalen); + memcpy(cp, data, (size_t)datalen); cp += datalen; } hp->ancount = htons(1); @@ -195,7 +218,8 @@ res_nmkquery(res_state statp, default: return (-1); } - return (cp - buf); + _DIAGASSERT(__type_fit(int, cp - buf)); + return (int)(cp - buf); } #ifdef RES_USE_EDNS0 @@ -217,7 +241,7 @@ res_nopt(res_state statp, printf(";; res_nopt()\n"); #endif - hp = (HEADER *) buf; + hp = (HEADER *)(void *)buf; cp = buf + n0; ep = buf + buflen; @@ -247,7 +271,8 @@ res_nopt(res_state statp, hp->arcount = htons(ntohs(hp->arcount) + 1); - return (cp - buf); + _DIAGASSERT(__type_fit(int, cp - buf)); + return (int)(cp - buf); } /* @@ -287,13 +312,15 @@ res_nopt_rdata(res_state statp, ns_put16(len, cp); cp += INT16SZ; - memcpy(cp, data, len); + memcpy(cp, data, (size_t)len); cp += len; - len = cp - rdata; + _DIAGASSERT(__type_fit(u_short, cp - rdata)); + len = (u_short)(cp - rdata); ns_put16(len, rdata - 2); /* Update RDLEN field */ - return (cp - buf); + _DIAGASSERT(__type_fit(int, cp - buf)); + return (int)(cp - buf); } #endif diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_mkupdate.c /usr/src/lib/libc/resolv/res_mkupdate.c --- /home/reed/src/isc/libbind/libbind/resolv/res_mkupdate.c 2009-01-20 19:28:19.000000000 -0600 +++ /usr/src/lib/libc/resolv/res_mkupdate.c 1969-12-31 18:00:00.000000000 -0600 @@ -1,1163 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and 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. - */ - -/*! \file - * \brief - * Based on the Dynamic DNS reference implementation by Viraj Bais - * <viraj_bais@ccm.fm.intel.com> - */ - -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_mkupdate.c,v 1.10 2008/12/11 09:59:00 marka Exp $"; -#endif /* not lint */ - -#include "port_before.h" - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "port_after.h" - -/* Options. Leave them on. */ -#define DEBUG -#define MAXPORT 1024 - -static int getnum_str(u_char **, u_char *); -static int gethexnum_str(u_char **, u_char *); -static int getword_str(char *, int, u_char **, u_char *); -static int getstr_str(char *, int, u_char **, u_char *); - -#define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2); - -/* Forward. */ - -int res_protocolnumber(const char *); -int res_servicenumber(const char *); - -/*% - * Form update packets. - * Returns the size of the resulting packet if no error - * - * On error, - * returns - *\li -1 if error in reading a word/number in rdata - * portion for update packets - *\li -2 if length of buffer passed is insufficient - *\li -3 if zone section is not the first section in - * the linked list, or section order has a problem - *\li -4 on a number overflow - *\li -5 unknown operation or no records - */ -int -res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) { - ns_updrec *rrecp_start = rrecp_in; - HEADER *hp; - u_char *cp, *sp2, *startp, *endp; - int n, i, soanum, multiline; - ns_updrec *rrecp; - struct in_addr ina; - struct in6_addr in6a; - char buf2[MAXDNAME]; - u_char buf3[MAXDNAME]; - int section, numrrs = 0, counts[ns_s_max]; - u_int16_t rtype, rclass; - u_int32_t n1, rttl; - u_char *dnptrs[20], **dpp, **lastdnptr; - int siglen, keylen, certlen; - - /* - * Initialize header fields. - */ - if ((buf == NULL) || (buflen < HFIXEDSZ)) - return (-1); - memset(buf, 0, HFIXEDSZ); - hp = (HEADER *) buf; - statp->id = res_nrandomid(statp); - hp->id = htons(statp->id); - hp->opcode = ns_o_update; - hp->rcode = NOERROR; - cp = buf + HFIXEDSZ; - buflen -= HFIXEDSZ; - dpp = dnptrs; - *dpp++ = buf; - *dpp++ = NULL; - lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; - - if (rrecp_start == NULL) - return (-5); - else if (rrecp_start->r_section != S_ZONE) - return (-3); - - memset(counts, 0, sizeof counts); - for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) { - numrrs++; - section = rrecp->r_section; - if (section < 0 || section >= ns_s_max) - return (-1); - counts[section]++; - for (i = section + 1; i < ns_s_max; i++) - if (counts[i]) - return (-3); - rtype = rrecp->r_type; - rclass = rrecp->r_class; - rttl = rrecp->r_ttl; - /* overload class and type */ - if (section == S_PREREQ) { - rttl = 0; - switch (rrecp->r_opcode) { - case YXDOMAIN: - rclass = C_ANY; - rtype = T_ANY; - rrecp->r_size = 0; - break; - case NXDOMAIN: - rclass = C_NONE; - rtype = T_ANY; - rrecp->r_size = 0; - break; - case NXRRSET: - rclass = C_NONE; - rrecp->r_size = 0; - break; - case YXRRSET: - if (rrecp->r_size == 0) - rclass = C_ANY; - break; - default: - fprintf(stderr, - "res_mkupdate: incorrect opcode: %d\n", - rrecp->r_opcode); - fflush(stderr); - return (-1); - } - } else if (section == S_UPDATE) { - switch (rrecp->r_opcode) { - case DELETE: - rclass = rrecp->r_size == 0 ? C_ANY : C_NONE; - break; - case ADD: - break; - default: - fprintf(stderr, - "res_mkupdate: incorrect opcode: %d\n", - rrecp->r_opcode); - fflush(stderr); - return (-1); - } - } - - /* - * XXX appending default domain to owner name is omitted, - * fqdn must be provided - */ - if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs, - lastdnptr)) < 0) - return (-1); - cp += n; - ShrinkBuffer(n + 2*INT16SZ); - PUTSHORT(rtype, cp); - PUTSHORT(rclass, cp); - if (section == S_ZONE) { - if (numrrs != 1 || rrecp->r_type != T_SOA) - return (-3); - continue; - } - ShrinkBuffer(INT32SZ + INT16SZ); - PUTLONG(rttl, cp); - sp2 = cp; /*%< save pointer to length byte */ - cp += INT16SZ; - if (rrecp->r_size == 0) { - if (section == S_UPDATE && rclass != C_ANY) - return (-1); - else { - PUTSHORT(0, sp2); - continue; - } - } - startp = rrecp->r_data; - endp = startp + rrecp->r_size - 1; - /* XXX this should be done centrally. */ - switch (rrecp->r_type) { - case T_A: - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - if (!inet_aton(buf2, &ina)) - return (-1); - n1 = ntohl(ina.s_addr); - ShrinkBuffer(INT32SZ); - PUTLONG(n1, cp); - break; - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - case ns_t_dname: - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); - if (n < 0) - return (-1); - cp += n; - ShrinkBuffer(n); - break; - case T_MINFO: - case T_SOA: - case T_RP: - for (i = 0; i < 2; i++) { - if (!getword_str(buf2, sizeof buf2, &startp, - endp)) - return (-1); - n = dn_comp(buf2, cp, buflen, - dnptrs, lastdnptr); - if (n < 0) - return (-1); - cp += n; - ShrinkBuffer(n); - } - if (rrecp->r_type == T_SOA) { - ShrinkBuffer(5 * INT32SZ); - while (isspace(*startp) || !*startp) - startp++; - if (*startp == '(') { - multiline = 1; - startp++; - } else - multiline = 0; - /* serial, refresh, retry, expire, minimum */ - for (i = 0; i < 5; i++) { - soanum = getnum_str(&startp, endp); - if (soanum < 0) - return (-1); - PUTLONG(soanum, cp); - } - if (multiline) { - while (isspace(*startp) || !*startp) - startp++; - if (*startp != ')') - return (-1); - } - } - break; - case T_MX: - case T_AFSDB: - case T_RT: - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); - if (n < 0) - return (-1); - cp += n; - ShrinkBuffer(n); - break; - case T_SRV: - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - n = dn_comp(buf2, cp, buflen, NULL, NULL); - if (n < 0) - return (-1); - cp += n; - ShrinkBuffer(n); - break; - case T_PX: - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - PUTSHORT(n, cp); - ShrinkBuffer(INT16SZ); - for (i = 0; i < 2; i++) { - if (!getword_str(buf2, sizeof buf2, &startp, - endp)) - return (-1); - n = dn_comp(buf2, cp, buflen, dnptrs, - lastdnptr); - if (n < 0) - return (-1); - cp += n; - ShrinkBuffer(n); - } - break; - case T_WKS: { - char bm[MAXPORT/8]; - unsigned int maxbm = 0; - - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - if (!inet_aton(buf2, &ina)) - return (-1); - n1 = ntohl(ina.s_addr); - ShrinkBuffer(INT32SZ); - PUTLONG(n1, cp); - - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - if ((i = res_protocolnumber(buf2)) < 0) - return (-1); - ShrinkBuffer(1); - *cp++ = i & 0xff; - - for (i = 0; i < MAXPORT/8 ; i++) - bm[i] = 0; - - while (getword_str(buf2, sizeof buf2, &startp, endp)) { - if ((n = res_servicenumber(buf2)) <= 0) - return (-1); - - if (n < MAXPORT) { - bm[n/8] |= (0x80>>(n%8)); - if ((unsigned)n > maxbm) - maxbm = n; - } else - return (-1); - } - maxbm = maxbm/8 + 1; - ShrinkBuffer(maxbm); - memcpy(cp, bm, maxbm); - cp += maxbm; - break; - } - case T_HINFO: - for (i = 0; i < 2; i++) { - if ((n = getstr_str(buf2, sizeof buf2, - &startp, endp)) < 0) - return (-1); - if (n > 255) - return (-1); - ShrinkBuffer(n+1); - *cp++ = n; - memcpy(cp, buf2, n); - cp += n; - } - break; - case T_TXT: - for (;;) { - if ((n = getstr_str(buf2, sizeof buf2, - &startp, endp)) < 0) { - if (cp != (sp2 + INT16SZ)) - break; - return (-1); - } - if (n > 255) - return (-1); - ShrinkBuffer(n+1); - *cp++ = n; - memcpy(cp, buf2, n); - cp += n; - } - break; - case T_X25: - /* RFC1183 */ - if ((n = getstr_str(buf2, sizeof buf2, &startp, - endp)) < 0) - return (-1); - if (n > 255) - return (-1); - ShrinkBuffer(n+1); - *cp++ = n; - memcpy(cp, buf2, n); - cp += n; - break; - case T_ISDN: - /* RFC1183 */ - if ((n = getstr_str(buf2, sizeof buf2, &startp, - endp)) < 0) - return (-1); - if ((n > 255) || (n == 0)) - return (-1); - ShrinkBuffer(n+1); - *cp++ = n; - memcpy(cp, buf2, n); - cp += n; - if ((n = getstr_str(buf2, sizeof buf2, &startp, - endp)) < 0) - n = 0; - if (n > 255) - return (-1); - ShrinkBuffer(n+1); - *cp++ = n; - memcpy(cp, buf2, n); - cp += n; - break; - case T_NSAP: - if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) { - ShrinkBuffer(n); - memcpy(cp, buf2, n); - cp += n; - } else { - return (-1); - } - break; - case T_LOC: - if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) { - ShrinkBuffer(n); - memcpy(cp, buf2, n); - cp += n; - } else - return (-1); - break; - case ns_t_sig: - { - int sig_type, success, dateerror; - u_int32_t exptime, timesigned; - - /* type */ - if ((n = getword_str(buf2, sizeof buf2, - &startp, endp)) < 0) - return (-1); - sig_type = sym_ston(__p_type_syms, buf2, &success); - if (!success || sig_type == ns_t_any) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(sig_type, cp); - /* alg */ - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(1); - *cp++ = n; - /* labels */ - n = getnum_str(&startp, endp); - if (n <= 0 || n > 255) - return (-1); - ShrinkBuffer(1); - *cp++ = n; - /* ottl & expire */ - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - exptime = ns_datetosecs(buf2, &dateerror); - if (!dateerror) { - ShrinkBuffer(INT32SZ); - PUTLONG(rttl, cp); - } - else { - char *ulendp; - u_int32_t ottl; - - errno = 0; - ottl = strtoul(buf2, &ulendp, 10); - if (errno != 0 || - (ulendp != NULL && *ulendp != '\0')) - return (-1); - ShrinkBuffer(INT32SZ); - PUTLONG(ottl, cp); - if (!getword_str(buf2, sizeof buf2, &startp, - endp)) - return (-1); - exptime = ns_datetosecs(buf2, &dateerror); - if (dateerror) - return (-1); - } - /* expire */ - ShrinkBuffer(INT32SZ); - PUTLONG(exptime, cp); - /* timesigned */ - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - timesigned = ns_datetosecs(buf2, &dateerror); - if (!dateerror) { - ShrinkBuffer(INT32SZ); - PUTLONG(timesigned, cp); - } - else - return (-1); - /* footprint */ - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - /* signer name */ - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); - if (n < 0) - return (-1); - cp += n; - ShrinkBuffer(n); - /* sig */ - if ((n = getword_str(buf2, sizeof buf2, - &startp, endp)) < 0) - return (-1); - siglen = b64_pton(buf2, buf3, sizeof(buf3)); - if (siglen < 0) - return (-1); - ShrinkBuffer(siglen); - memcpy(cp, buf3, siglen); - cp += siglen; - break; - } - case ns_t_key: - /* flags */ - n = gethexnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - /* proto */ - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(1); - *cp++ = n; - /* alg */ - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(1); - *cp++ = n; - /* key */ - if ((n = getword_str(buf2, sizeof buf2, - &startp, endp)) < 0) - return (-1); - keylen = b64_pton(buf2, buf3, sizeof(buf3)); - if (keylen < 0) - return (-1); - ShrinkBuffer(keylen); - memcpy(cp, buf3, keylen); - cp += keylen; - break; - case ns_t_nxt: - { - int success, nxt_type; - u_char data[32]; - int maxtype; - - /* next name */ - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - n = dn_comp(buf2, cp, buflen, NULL, NULL); - if (n < 0) - return (-1); - cp += n; - ShrinkBuffer(n); - maxtype = 0; - memset(data, 0, sizeof data); - for (;;) { - if (!getword_str(buf2, sizeof buf2, &startp, - endp)) - break; - nxt_type = sym_ston(__p_type_syms, buf2, - &success); - if (!success || !ns_t_rr_p(nxt_type)) - return (-1); - NS_NXT_BIT_SET(nxt_type, data); - if (nxt_type > maxtype) - maxtype = nxt_type; - } - n = maxtype/NS_NXT_BITS+1; - ShrinkBuffer(n); - memcpy(cp, data, n); - cp += n; - break; - } - case ns_t_cert: - /* type */ - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - /* key tag */ - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - /* alg */ - n = getnum_str(&startp, endp); - if (n < 0) - return (-1); - ShrinkBuffer(1); - *cp++ = n; - /* cert */ - if ((n = getword_str(buf2, sizeof buf2, - &startp, endp)) < 0) - return (-1); - certlen = b64_pton(buf2, buf3, sizeof(buf3)); - if (certlen < 0) - return (-1); - ShrinkBuffer(certlen); - memcpy(cp, buf3, certlen); - cp += certlen; - break; - case ns_t_aaaa: - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - if (inet_pton(AF_INET6, buf2, &in6a) <= 0) - return (-1); - ShrinkBuffer(NS_IN6ADDRSZ); - memcpy(cp, &in6a, NS_IN6ADDRSZ); - cp += NS_IN6ADDRSZ; - break; - case ns_t_naptr: - /* Order Preference Flags Service Replacement Regexp */ - /* Order */ - n = getnum_str(&startp, endp); - if (n < 0 || n > 65535) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - /* Preference */ - n = getnum_str(&startp, endp); - if (n < 0 || n > 65535) - return (-1); - ShrinkBuffer(INT16SZ); - PUTSHORT(n, cp); - /* Flags */ - if ((n = getstr_str(buf2, sizeof buf2, - &startp, endp)) < 0) { - return (-1); - } - if (n > 255) - return (-1); - ShrinkBuffer(n+1); - *cp++ = n; - memcpy(cp, buf2, n); - cp += n; - /* Service Classes */ - if ((n = getstr_str(buf2, sizeof buf2, - &startp, endp)) < 0) { - return (-1); - } - if (n > 255) - return (-1); - ShrinkBuffer(n+1); - *cp++ = n; - memcpy(cp, buf2, n); - cp += n; - /* Pattern */ - if ((n = getstr_str(buf2, sizeof buf2, - &startp, endp)) < 0) { - return (-1); - } - if (n > 255) - return (-1); - ShrinkBuffer(n+1); - *cp++ = n; - memcpy(cp, buf2, n); - cp += n; - /* Replacement */ - if (!getword_str(buf2, sizeof buf2, &startp, endp)) - return (-1); - n = dn_comp(buf2, cp, buflen, NULL, NULL); - if (n < 0) - return (-1); - cp += n; - ShrinkBuffer(n); - break; - default: - return (-1); - } /*switch*/ - n = (u_int16_t)((cp - sp2) - INT16SZ); - PUTSHORT(n, sp2); - } /*for*/ - - hp->qdcount = htons(counts[0]); - hp->ancount = htons(counts[1]); - hp->nscount = htons(counts[2]); - hp->arcount = htons(counts[3]); - return (cp - buf); -} - -/*% - * Get a whitespace delimited word from a string (not file) - * into buf. modify the start pointer to point after the - * word in the string. - */ -static int -getword_str(char *buf, int size, u_char **startpp, u_char *endp) { - char *cp; - int c; - - for (cp = buf; *startpp <= endp; ) { - c = **startpp; - if (isspace(c) || c == '\0') { - if (cp != buf) /*%< trailing whitespace */ - break; - else { /*%< leading whitespace */ - (*startpp)++; - continue; - } - } - (*startpp)++; - if (cp >= buf+size-1) - break; - *cp++ = (u_char)c; - } - *cp = '\0'; - return (cp != buf); -} - -/*% - * get a white spae delimited string from memory. Process quoted strings - * and \\DDD escapes. Return length or -1 on error. Returned string may - * contain nulls. - */ -static char digits[] = "0123456789"; -static int -getstr_str(char *buf, int size, u_char **startpp, u_char *endp) { - char *cp; - int c, c1 = 0; - int inquote = 0; - int seen_quote = 0; - int escape = 0; - int dig = 0; - - for (cp = buf; *startpp <= endp; ) { - if ((c = **startpp) == '\0') - break; - /* leading white space */ - if ((cp == buf) && !seen_quote && isspace(c)) { - (*startpp)++; - continue; - } - - switch (c) { - case '\\': - if (!escape) { - escape = 1; - dig = 0; - c1 = 0; - (*startpp)++; - continue; - } - goto do_escape; - case '"': - if (!escape) { - inquote = !inquote; - seen_quote = 1; - (*startpp)++; - continue; - } - /* fall through */ - default: - do_escape: - if (escape) { - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - c1 = c1 * 10 + - (strchr(digits, c) - digits); - - if (++dig == 3) { - c = c1 &0xff; - break; - } - (*startpp)++; - continue; - } - escape = 0; - } else if (!inquote && isspace(c)) - goto done; - if (cp >= buf+size-1) - goto done; - *cp++ = (u_char)c; - (*startpp)++; - } - } - done: - *cp = '\0'; - return ((cp == buf)? (seen_quote? 0: -1): (cp - buf)); -} - -/*% - * Get a whitespace delimited base 16 number from a string (not file) into buf - * update the start pointer to point after the number in the string. - */ -static int -gethexnum_str(u_char **startpp, u_char *endp) { - int c, n; - int seendigit = 0; - int m = 0; - - if (*startpp + 2 >= endp || strncasecmp((char *)*startpp, "0x", 2) != 0) - return getnum_str(startpp, endp); - (*startpp)+=2; - for (n = 0; *startpp <= endp; ) { - c = **startpp; - if (isspace(c) || c == '\0') { - if (seendigit) /*%< trailing whitespace */ - break; - else { /*%< leading whitespace */ - (*startpp)++; - continue; - } - } - if (c == ';') { - while ((*startpp <= endp) && - ((c = **startpp) != '\n')) - (*startpp)++; - if (seendigit) - break; - continue; - } - if (!isxdigit(c)) { - if (c == ')' && seendigit) { - (*startpp)--; - break; - } - return (-1); - } - (*startpp)++; - if (isdigit(c)) - n = n * 16 + (c - '0'); - else - n = n * 16 + (tolower(c) - 'a' + 10); - seendigit = 1; - } - return (n + m); -} - -/*% - * Get a whitespace delimited base 10 number from a string (not file) into buf - * update the start pointer to point after the number in the string. - */ -static int -getnum_str(u_char **startpp, u_char *endp) { - int c, n; - int seendigit = 0; - int m = 0; - - for (n = 0; *startpp <= endp; ) { - c = **startpp; - if (isspace(c) || c == '\0') { - if (seendigit) /*%< trailing whitespace */ - break; - else { /*%< leading whitespace */ - (*startpp)++; - continue; - } - } - if (c == ';') { - while ((*startpp <= endp) && - ((c = **startpp) != '\n')) - (*startpp)++; - if (seendigit) - break; - continue; - } - if (!isdigit(c)) { - if (c == ')' && seendigit) { - (*startpp)--; - break; - } - return (-1); - } - (*startpp)++; - n = n * 10 + (c - '0'); - seendigit = 1; - } - return (n + m); -} - -/*% - * Allocate a resource record buffer & save rr info. - */ -ns_updrec * -res_mkupdrec(int section, const char *dname, - u_int class, u_int type, u_long ttl) { - ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec)); - - if (!rrecp || !(rrecp->r_dname = strdup(dname))) { - if (rrecp) - free((char *)rrecp); - return (NULL); - } - INIT_LINK(rrecp, r_link); - INIT_LINK(rrecp, r_glink); - rrecp->r_class = (ns_class)class; - rrecp->r_type = (ns_type)type; - rrecp->r_ttl = ttl; - rrecp->r_section = (ns_sect)section; - return (rrecp); -} - -/*% - * Free a resource record buffer created by res_mkupdrec. - */ -void -res_freeupdrec(ns_updrec *rrecp) { - /* Note: freeing r_dp is the caller's responsibility. */ - if (rrecp->r_dname != NULL) - free(rrecp->r_dname); - free(rrecp); -} - -struct valuelist { - struct valuelist * next; - struct valuelist * prev; - char * name; - char * proto; - int port; -}; -static struct valuelist *servicelist, *protolist; - -static void -res_buildservicelist() { - struct servent *sp; - struct valuelist *slp; - -#ifdef MAYBE_HESIOD - setservent(0); -#else - setservent(1); -#endif - while ((sp = getservent()) != NULL) { - slp = (struct valuelist *)malloc(sizeof(struct valuelist)); - if (!slp) - break; - slp->name = strdup(sp->s_name); - slp->proto = strdup(sp->s_proto); - if ((slp->name == NULL) || (slp->proto == NULL)) { - if (slp->name) free(slp->name); - if (slp->proto) free(slp->proto); - free(slp); - break; - } - slp->port = ntohs((u_int16_t)sp->s_port); /*%< host byt order */ - slp->next = servicelist; - slp->prev = NULL; - if (servicelist) - servicelist->prev = slp; - servicelist = slp; - } - endservent(); -} - -void -res_destroyservicelist() { - struct valuelist *slp, *slp_next; - - for (slp = servicelist; slp != NULL; slp = slp_next) { - slp_next = slp->next; - free(slp->name); - free(slp->proto); - free(slp); - } - servicelist = (struct valuelist *)0; -} - -void -res_buildprotolist(void) { - struct protoent *pp; - struct valuelist *slp; - -#ifdef MAYBE_HESIOD - setprotoent(0); -#else - setprotoent(1); -#endif - while ((pp = getprotoent()) != NULL) { - slp = (struct valuelist *)malloc(sizeof(struct valuelist)); - if (!slp) - break; - slp->name = strdup(pp->p_name); - if (slp->name == NULL) { - free(slp); - break; - } - slp->port = pp->p_proto; /*%< host byte order */ - slp->next = protolist; - slp->prev = NULL; - if (protolist) - protolist->prev = slp; - protolist = slp; - } - endprotoent(); -} - -void -res_destroyprotolist(void) { - struct valuelist *plp, *plp_next; - - for (plp = protolist; plp != NULL; plp = plp_next) { - plp_next = plp->next; - free(plp->name); - free(plp); - } - protolist = (struct valuelist *)0; -} - -static int -findservice(const char *s, struct valuelist **list) { - struct valuelist *lp = *list; - int n; - - for (; lp != NULL; lp = lp->next) - if (strcasecmp(lp->name, s) == 0) { - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - return (lp->port); /*%< host byte order */ - } - if (sscanf(s, "%d", &n) != 1 || n <= 0) - n = -1; - return (n); -} - -/*% - * Convert service name or (ascii) number to int. - */ -int -res_servicenumber(const char *p) { - if (servicelist == (struct valuelist *)0) - res_buildservicelist(); - return (findservice(p, &servicelist)); -} - -/*% - * Convert protocol name or (ascii) number to int. - */ -int -res_protocolnumber(const char *p) { - if (protolist == (struct valuelist *)0) - res_buildprotolist(); - return (findservice(p, &protolist)); -} - -static struct servent * -cgetservbyport(u_int16_t port, const char *proto) { /*%< Host byte order. */ - struct valuelist **list = &servicelist; - struct valuelist *lp = *list; - static struct servent serv; - - port = ntohs(port); - for (; lp != NULL; lp = lp->next) { - if (port != (u_int16_t)lp->port) /*%< Host byte order. */ - continue; - if (strcasecmp(lp->proto, proto) == 0) { - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - serv.s_name = lp->name; - serv.s_port = htons((u_int16_t)lp->port); - serv.s_proto = lp->proto; - return (&serv); - } - } - return (0); -} - -static struct protoent * -cgetprotobynumber(int proto) { /*%< Host byte order. */ - struct valuelist **list = &protolist; - struct valuelist *lp = *list; - static struct protoent prot; - - for (; lp != NULL; lp = lp->next) - if (lp->port == proto) { /*%< Host byte order. */ - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - prot.p_name = lp->name; - prot.p_proto = lp->port; /*%< Host byte order. */ - return (&prot); - } - return (0); -} - -const char * -res_protocolname(int num) { - static char number[8]; - struct protoent *pp; - - if (protolist == (struct valuelist *)0) - res_buildprotolist(); - pp = cgetprotobynumber(num); - if (pp == 0) { - (void) sprintf(number, "%d", num); - return (number); - } - return (pp->p_name); -} - -const char * -res_servicename(u_int16_t port, const char *proto) { /*%< Host byte order. */ - static char number[8]; - struct servent *ss; - - if (servicelist == (struct valuelist *)0) - res_buildservicelist(); - ss = cgetservbyport(htons(port), proto); - if (ss == 0) { - (void) sprintf(number, "%d", port); - return (number); - } - return (ss->s_name); -} diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_mkupdate.h /usr/src/lib/libc/resolv/res_mkupdate.h --- /home/reed/src/isc/libbind/libbind/resolv/res_mkupdate.h 2005-04-26 23:56:42.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_mkupdate.h 1969-12-31 18:00:00.000000000 -0600 @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1998,1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and 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. - */ - -#ifndef _RES_MKUPDATE_H_ -#define _RES_MKUPDATE_H_ - -__BEGIN_DECLS -__END_DECLS - -#endif /* _RES_MKUPDATE_H_ */ -/*! \file */ diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_private.h /usr/src/lib/libc/resolv/res_private.h --- /home/reed/src/isc/libbind/libbind/resolv/res_private.h 2005-04-26 23:56:42.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_private.h 2012-10-24 08:34:38.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: res_private.h,v 1.3 2009/10/24 17:24:01 christos Exp $ */ + #ifndef res_private_h #define res_private_h @@ -12,10 +14,12 @@ struct __res_state_ext { } sort_list[MAXRESOLVSORT]; char nsuffix[64]; char nsuffix2[64]; + struct timespec res_conf_time; + int kq, resfd; }; -extern int -res_ourserver_p(const res_state statp, const struct sockaddr *sa); +extern int res_ourserver_p(const res_state, const struct sockaddr *); +extern int __res_vinit(res_state, int); #endif diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_query.c /usr/src/lib/libc/resolv/res_query.c --- /home/reed/src/isc/libbind/libbind/resolv/res_query.c 2013-06-05 09:33:54.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_query.c 2013-06-05 09:26:14.000000000 -0500 @@ -1,3 +1,5 @@ +/* $NetBSD: res_query.c,v 1.14 2012/03/13 21:13:44 christos Exp $ */ + /* * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2001, 2003 Internet Software Consortium. @@ -27,7 +29,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -64,12 +70,36 @@ * SOFTWARE. */ +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and 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. + */ + +#include #if defined(LIBC_SCCS) && !defined(lint) +#ifdef notdef static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_query.c,v 1.12 2013-01-06 23:14:54 marka Exp $"; +static const char rcsid[] = "Id: res_query.c,v 1.11 2008/11/14 02:36:51 marka Exp"; +#else +__RCSID("$NetBSD: res_query.c,v 1.14 2012/03/13 21:13:44 christos Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ #include "port_before.h" + +#include "namespace.h" #include #include #include @@ -81,11 +111,23 @@ static const char rcsid[] = "$Id: res_qu #include #include #include +#include #include #include "port_after.h" +#if 0 +#ifdef __weak_alias +__weak_alias(res_nquery,_res_nquery) +__weak_alias(res_nsearch,_res_nsearch) +__weak_alias(res_nquerydomain,__res_nquerydomain) +__weak_alias(res_hostalias,__res_hostalias) +#endif +#endif + /* Options. Leave them on. */ +#ifndef DEBUG #define DEBUG +#endif #if PACKETSZ > 1024 #define MAXPACKET PACKETSZ @@ -111,7 +153,7 @@ res_nquery(res_state statp, int anslen) /*%< size of answer buffer */ { u_char buf[MAXPACKET]; - HEADER *hp = (HEADER *) answer; + HEADER *hp = (HEADER *)(void *)answer; u_int oflags; u_char *rdata; int n; @@ -126,15 +168,15 @@ again: #endif n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL, - buf, sizeof(buf)); + buf, (int)sizeof(buf)); #ifdef RES_USE_EDNS0 if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 && - (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC|RES_NSID))) { - n = res_nopt(statp, n, buf, sizeof(buf), anslen); + (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC|RES_NSID)) != 0U) { + n = res_nopt(statp, n, buf, (int)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); + n = res_nopt_rdata(statp, n, buf, (int)sizeof(buf), + rdata, NS_OPT_NSID, 0, NULL); } } #endif @@ -212,7 +254,7 @@ res_nsearch(res_state statp, int anslen) /*%< size of answer */ { const char *cp, * const *domain; - HEADER *hp = (HEADER *) answer; + HEADER *hp = (HEADER *)(void *)answer; char tmp[NS_MAXDNAME]; u_int dots; int trailing_dot, ret, saved_herrno; @@ -360,7 +402,7 @@ res_nquerydomain(res_state statp, { char nbuf[MAXDNAME]; const char *longname = nbuf; - int n, d; + size_t n, d; #ifdef DEBUG if (statp->options & RES_DEBUG) @@ -377,8 +419,7 @@ res_nquerydomain(res_state statp, RES_SET_H_ERRNO(statp, NO_RECOVERY); return (-1); } - n--; - if (n >= 0 && name[n] == '.') { + if (n && name[--n] == '.') { strncpy(nbuf, name, n); nbuf[n] = '\0'; } else @@ -403,12 +444,17 @@ res_hostalias(const res_state statp, con if (statp->options & RES_NOALIASES) return (NULL); + /* + * forbid hostaliases for setuid binary, due to possible security + * breach. + */ + if (issetugid()) + return (NULL); file = getenv("HOSTALIASES"); if (file == NULL || (fp = fopen(file, "r")) == NULL) return (NULL); - setbuf(fp, NULL); buf[sizeof(buf) - 1] = '\0'; - while (fgets(buf, sizeof(buf), fp)) { + while (fgets(buf, (int)sizeof(buf), fp)) { for (cp1 = buf; *cp1 && !isspace((unsigned char)*cp1); ++cp1) ; if (!*cp1) diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_send.c /usr/src/lib/libc/resolv/res_send.c --- /home/reed/src/isc/libbind/libbind/resolv/res_send.c 2013-04-04 17:43:30.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_send.c 2013-06-05 09:26:14.000000000 -0500 @@ -1,5 +1,7 @@ +/* $NetBSD: res_send.c,v 1.29 2013/02/16 13:45:45 para Exp $ */ + /* - * Portions Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -27,7 +29,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -64,9 +70,31 @@ * SOFTWARE. */ +/* + * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and 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. + */ + +#include #if defined(LIBC_SCCS) && !defined(lint) +#ifdef notdef static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_send.c,v 1.25 2013-01-06 23:14:54 marka Exp $"; +static const char rcsid[] = "Id: res_send.c,v 1.22 2009/01/22 23:49:23 tbox Exp"; +#else +__RCSID("$NetBSD: res_send.c,v 1.29 2013/02/16 13:45:45 para Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ /*! \file @@ -74,24 +102,32 @@ static const char rcsid[] = "$Id: res_se * Send query to name server and wait for reply. */ +#include "namespace.h" #include "port_before.h" +#ifndef USE_KQUEUE #include "fd_setsize.h" +#endif /* USE_KQUEUE */ #include #include #include #include #include +#ifdef USE_KQUEUE +#include +#endif /* USE_KQUEUE */ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -100,6 +136,22 @@ static const char rcsid[] = "$Id: res_se #include "port_after.h" +#if 0 +#ifdef __weak_alias +__weak_alias(res_ourserver_p,__res_ourserver_p) +__weak_alias(res_nameinquery,__res_nameinquery) +__weak_alias(res_queriesmatch,__res_queriesmatch) +__weak_alias(res_nsend,__res_nsend) +#endif +#endif + +#ifndef SOCK_NOSIGPIPE +#define SOCK_NOSIGPIPE 0 +#endif +#ifndef SOCK_NOCLOEXEC +#define SOCK_NOCLOEXEC 0 +#endif + #ifdef USE_POLL #ifdef HAVE_STROPTS_H #include @@ -108,32 +160,36 @@ static const char rcsid[] = "$Id: res_se #endif /* USE_POLL */ /* Options. Leave them on. */ +#ifndef DEBUG #define DEBUG +#endif #include "res_debug.h" #include "res_private.h" #define EXT(res) ((res)->_u._ext) -#ifndef USE_POLL +#if !defined(USE_POLL) && !defined(USE_KQUEUE) static const int highestFD = FD_SETSIZE - 1; -#else -static int highestFD = 0; #endif /* Forward. */ -static int get_salen __P((const struct sockaddr *)); -static struct sockaddr * get_nsaddr __P((res_state, size_t)); -static int send_vc(res_state, const u_char *, int, +static socklen_t get_salen(const struct sockaddr *); +static struct sockaddr * get_nsaddr(res_state, size_t); +static int send_vc(res_state, const void *, size_t, u_char *, int, int *, int); -static int send_dg(res_state, const u_char *, int, +static int send_dg(res_state, +#ifdef USE_KQUEUE + int, +#endif + const void *, size_t, u_char *, int, int *, int, int, int *, int *); static void Aerror(const res_state, FILE *, const char *, int, - const struct sockaddr *, int); + const struct sockaddr *, socklen_t); static void Perror(const res_state, FILE *, const char *, int); static int sock_eq(struct sockaddr *, struct sockaddr *); -#if defined(NEED_PSELECT) && !defined(USE_POLL) +#if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE) static int pselect(int, void *, void *, void *, struct timespec *, const sigset_t *); @@ -162,9 +218,9 @@ res_ourserver_p(const res_state statp, c switch (sa->sa_family) { case AF_INET: - inp = (const struct sockaddr_in *)sa; + inp = (const struct sockaddr_in *)(const void *)sa; for (ns = 0; ns < statp->nscount; ns++) { - srv = (struct sockaddr_in *)get_nsaddr(statp, ns); + srv = (struct sockaddr_in *)(void *)get_nsaddr(statp, (size_t)ns); if (srv->sin_family == inp->sin_family && srv->sin_port == inp->sin_port && (srv->sin_addr.s_addr == INADDR_ANY || @@ -175,9 +231,9 @@ res_ourserver_p(const res_state statp, c case AF_INET6: if (EXT(statp).ext == NULL) break; - in6p = (const struct sockaddr_in6 *)sa; + in6p = (const struct sockaddr_in6 *)(const void *)sa; for (ns = 0; ns < statp->nscount; ns++) { - srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns); + srv6 = (struct sockaddr_in6 *)(void *)get_nsaddr(statp, (size_t)ns); if (srv6->sin6_family == in6p->sin6_family && srv6->sin6_port == in6p->sin6_port && #ifdef HAVE_SIN6_SCOPE_ID @@ -214,13 +270,13 @@ res_nameinquery(const char *name, int ty const u_char *buf, const u_char *eom) { const u_char *cp = buf + HFIXEDSZ; - int qdcount = ntohs(((const HEADER*)buf)->qdcount); + int qdcount = ntohs(((const HEADER*)(const void *)buf)->qdcount); while (qdcount-- > 0) { char tname[MAXDNAME+1]; int n, ttype, tclass; - n = dn_expand(buf, eom, cp, tname, sizeof tname); + n = dn_expand(buf, eom, cp, tname, (int)sizeof tname); if (n < 0) return (-1); cp += n; @@ -252,7 +308,7 @@ res_queriesmatch(const u_char *buf1, con const u_char *buf2, const u_char *eom2) { const u_char *cp = buf1 + HFIXEDSZ; - int qdcount = ntohs(((const HEADER*)buf1)->qdcount); + int qdcount = ntohs(((const HEADER*)(const void *)buf1)->qdcount); if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) return (-1); @@ -261,17 +317,17 @@ res_queriesmatch(const u_char *buf1, con * Only header section present in replies to * dynamic update packets. */ - if ((((const HEADER *)buf1)->opcode == ns_o_update) && - (((const HEADER *)buf2)->opcode == ns_o_update)) + if ((((const HEADER *)(const void *)buf1)->opcode == ns_o_update) && + (((const HEADER *)(const void *)buf2)->opcode == ns_o_update)) return (1); - if (qdcount != ntohs(((const HEADER*)buf2)->qdcount)) + if (qdcount != ntohs(((const HEADER*)(const void *)buf2)->qdcount)) return (0); while (qdcount-- > 0) { char tname[MAXDNAME+1]; int n, ttype, tclass; - n = dn_expand(buf1, eom1, cp, tname, sizeof tname); + n = dn_expand(buf1, eom1, cp, tname, (int)sizeof tname); if (n < 0) return (-1); cp += n; @@ -290,11 +346,12 @@ res_nsend(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz) { int gotsomewhere, terrno, tries, v_circuit, resplen, ns, n; +#ifdef USE_KQUEUE + int kq; +#endif char abuf[NI_MAXHOST]; -#ifdef USE_POLL - highestFD = sysconf(_SC_OPEN_MAX) - 1; -#endif + (void)res_check(statp, NULL); /* No name servers or res_init() failure */ if (statp->nscount == 0 || EXT(statp).ext == NULL) { @@ -311,6 +368,12 @@ res_nsend(res_state statp, gotsomewhere = 0; terrno = ETIMEDOUT; +#ifdef USE_KQUEUE + if ((kq = kqueue1(O_CLOEXEC)) == -1) { + return (-1); + } +#endif + /* * If the ns_addr_list in the resolver context has changed, then * invalidate our cached copy and the associated timing data. @@ -325,8 +388,8 @@ res_nsend(res_state statp, else for (ns = 0; ns < statp->nscount; ns++) { if (statp->nsaddr_list[ns].sin_family && - !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns], - (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) { + !sock_eq((struct sockaddr *)(void *)&statp->nsaddr_list[ns], + (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[ns])) { needclose++; break; } @@ -335,12 +398,12 @@ res_nsend(res_state statp, continue; peerlen = sizeof(peer); if (getpeername(EXT(statp).nssocks[ns], - (struct sockaddr *)&peer, &peerlen) < 0) { + (struct sockaddr *)(void *)&peer, &peerlen) < 0) { needclose++; break; } - if (!sock_eq((struct sockaddr *)&peer, - get_nsaddr(statp, ns))) { + if (!sock_eq((struct sockaddr *)(void *)&peer, + get_nsaddr(statp, (size_t)ns))) { needclose++; break; } @@ -404,8 +467,8 @@ res_nsend(res_state statp, for (tries = 0; tries < statp->retry; tries++) { for (ns = 0; ns < statp->nscount; ns++) { struct sockaddr *nsap; - int nsaplen; - nsap = get_nsaddr(statp, ns); + socklen_t nsaplen; + nsap = get_nsaddr(statp, (size_t)ns); nsaplen = get_salen(nsap); statp->_flags &= ~RES_F_LASTMASK; statp->_flags |= (ns << RES_F_LASTSHIFT); @@ -426,6 +489,9 @@ res_nsend(res_state statp, res_nclose(statp); goto next_ns; case res_done: +#ifdef USE_KQUEUE + close(kq); +#endif return (resplen); case res_modified: /* give the hook another try */ @@ -441,8 +507,8 @@ res_nsend(res_state statp, } Dprint(((statp->options & RES_DEBUG) && - getnameinfo(nsap, nsaplen, abuf, sizeof(abuf), - NULL, 0, niflags) == 0), + getnameinfo(nsap, nsaplen, abuf, + (socklen_t)sizeof(abuf), NULL, 0, niflags) == 0), (stdout, ";; Querying server (# %d) address = %s\n", ns + 1, abuf)); @@ -450,7 +516,7 @@ res_nsend(res_state statp, if (v_circuit) { /* Use VC; at most one attempt per server. */ tries = statp->retry; - n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, + n = send_vc(statp, buf, (size_t)buflen, ans, anssiz, &terrno, ns); if (n < 0) goto fail; @@ -459,8 +525,12 @@ res_nsend(res_state statp, resplen = n; } else { /* Use datagrams. */ - n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, - ns, tries, &v_circuit, &gotsomewhere); + n = send_dg(statp, +#ifdef USE_KQUEUE + kq, +#endif + buf, (size_t)buflen, ans, anssiz, &terrno, + ns, tries, &v_circuit, &gotsomewhere); if (n < 0) goto fail; if (n == 0) @@ -518,11 +588,17 @@ res_nsend(res_state statp, } while (!done); } +#ifdef USE_KQUEUE + close(kq); +#endif return (resplen); next_ns: ; } /*foreach ns*/ } /*foreach retry*/ res_nclose(statp); +#ifdef USE_KQUEUE + close(kq); +#endif if (!v_circuit) { if (!gotsomewhere) errno = ECONNREFUSED; /*%< no nameservers found */ @@ -533,37 +609,37 @@ res_nsend(res_state statp, return (-1); fail: res_nclose(statp); +#ifdef USE_KQUEUE + close(kq); +#endif return (-1); } /* Private */ -static int -get_salen(sa) - const struct sockaddr *sa; +static socklen_t +get_salen(const struct sockaddr *sa) { #ifdef HAVE_SA_LEN /* There are people do not set sa_len. Be forgiving to them. */ if (sa->sa_len) - return (sa->sa_len); + return (socklen_t)sa->sa_len; #endif if (sa->sa_family == AF_INET) - return (sizeof(struct sockaddr_in)); + return (socklen_t)sizeof(struct sockaddr_in); else if (sa->sa_family == AF_INET6) - return (sizeof(struct sockaddr_in6)); + return (socklen_t)sizeof(struct sockaddr_in6); else - return (0); /*%< unknown, die on connect */ + return 0; /*%< unknown, die on connect */ } /*% * pick appropriate nsaddr_list for use. see res_init() for initialization. */ static struct sockaddr * -get_nsaddr(statp, n) - res_state statp; - size_t n; +get_nsaddr(res_state statp, size_t n) { if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) { @@ -585,23 +661,24 @@ get_nsaddr(statp, n) static int send_vc(res_state statp, - const u_char *buf, int buflen, u_char *ans, int anssiz, + const void *buf, size_t buflen, u_char *ans, int anssiz, int *terrno, int ns) { - const HEADER *hp = (const HEADER *) buf; - HEADER *anhp = (HEADER *) ans; + const HEADER *hp = (const HEADER *)(const void *)buf; + HEADER *anhp = (HEADER *)(void *)ans; struct sockaddr *nsap; - int nsaplen; - int truncating, connreset, resplen, n; + socklen_t nsaplen; + int truncating, connreset, resplen; + ssize_t n; struct iovec iov[2]; u_short len; u_char *cp; void *tmp; -#ifdef SO_NOSIGPIPE +#if defined(SO_NOSIGPIPE) && SOCK_NOSIGPIPE == 0 int on = 1; #endif - nsap = get_nsaddr(statp, ns); + nsap = get_nsaddr(statp, (size_t)ns); nsaplen = get_salen(nsap); connreset = 0; @@ -614,8 +691,8 @@ send_vc(res_state statp, ISC_SOCKLEN_T size = sizeof peer; if (getpeername(statp->_vcsock, - (struct sockaddr *)&peer, &size) < 0 || - !sock_eq((struct sockaddr *)&peer, nsap)) { + (struct sockaddr *)(void *)&peer, &size) < 0 || + !sock_eq((struct sockaddr *)(void *)&peer, nsap)) { res_nclose(statp); statp->_flags &= ~RES_F_VC; } @@ -625,11 +702,17 @@ send_vc(res_state statp, if (statp->_vcsock >= 0) res_nclose(statp); - statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0); + statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM + | SOCK_NOSIGPIPE | SOCK_CLOEXEC, 0); +#if SOCK_CLOEXEC == 0 + fcntl(statp->_vcsock, F_SETFD, FD_CLOEXEC); +#endif +#if !defined(USE_POLL) && !defined(USE_KQUEUE) if (statp->_vcsock > highestFD) { res_nclose(statp); errno = ENOTSOCK; } +#endif if (statp->_vcsock < 0) { switch (errno) { case EPROTONOSUPPORT: @@ -645,7 +728,7 @@ send_vc(res_state statp, return (-1); } } -#ifdef SO_NOSIGPIPE +#if defined(SO_NOSIGPIPE) && SOCK_NOSIGPIPE == 0 /* * Disable generation of SIGPIPE when writing to a closed * socket. Write should return -1 and set errno to EPIPE @@ -654,7 +737,7 @@ send_vc(res_state statp, * Push on even if setsockopt(SO_NOSIGPIPE) fails. */ (void)setsockopt(statp->_vcsock, SOL_SOCKET, SO_NOSIGPIPE, &on, - sizeof(on)); + (socklen_t)sizeof(on)); #endif errno = 0; if (connect(statp->_vcsock, nsap, nsaplen) < 0) { @@ -670,11 +753,11 @@ send_vc(res_state statp, /* * Send length & message */ - ns_put16((u_short)buflen, (u_char*)&len); + ns_put16((u_short)buflen, (u_char*)(void *)&len); iov[0] = evConsIovec(&len, INT16SZ); DE_CONST(buf, tmp); - iov[1] = evConsIovec(tmp, buflen); - if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { + iov[1] = evConsIovec(tmp, (size_t)buflen); + if (writev(statp->_vcsock, iov, 2) != (ssize_t)(INT16SZ + buflen)) { *terrno = errno; Perror(statp, stderr, "write failed", errno); res_nclose(statp); @@ -686,9 +769,9 @@ send_vc(res_state statp, read_len: cp = ans; len = INT16SZ; - while ((n = read(statp->_vcsock, (char *)cp, (int)len)) > 0) { + while ((n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0) { cp += n; - if ((len -= n) == 0) + if ((len -= (u_short)n) == 0) break; } if (n <= 0) { @@ -732,9 +815,9 @@ send_vc(res_state statp, return (0); } cp = ans; - while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){ + while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0){ cp += n; - len -= n; + len -= (u_short)n; } if (n <= 0) { *terrno = errno; @@ -754,7 +837,7 @@ send_vc(res_state statp, n = read(statp->_vcsock, junk, (len > sizeof junk) ? sizeof junk : len); if (n > 0) - len -= n; + len -= (u_short)n; else break; } @@ -782,33 +865,48 @@ send_vc(res_state statp, } static int -send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans, +send_dg(res_state statp, +#ifdef USE_KQUEUE + int kq, +#endif + const void *buf, size_t buflen, u_char *ans, int anssiz, int *terrno, int ns, int tries, int *v_circuit, int *gotsomewhere) { - const HEADER *hp = (const HEADER *) buf; - HEADER *anhp = (HEADER *) ans; + const HEADER *hp = (const HEADER *)(const void *)buf; + HEADER *anhp = (HEADER *)(void *)ans; const struct sockaddr *nsap; - int nsaplen; + socklen_t nsaplen; struct timespec now, timeout, finish; struct sockaddr_storage from; ISC_SOCKLEN_T fromlen; - int resplen, seconds, n, s; + ssize_t resplen; + int seconds, n, s; +#ifdef USE_KQUEUE + struct kevent kv; +#else #ifdef USE_POLL int polltimeout; struct pollfd pollfd; #else fd_set dsmask; #endif +#endif - nsap = get_nsaddr(statp, ns); + nsap = get_nsaddr(statp, (size_t)ns); nsaplen = get_salen(nsap); if (EXT(statp).nssocks[ns] == -1) { - EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0); + EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM + | SOCK_CLOEXEC, 0); +#if SOCK_CLOEXEC == 0 + fcntl(EXT(statp)nssocks[ns], F_SETFD, FD_CLOEXEC); +#endif +#if !defined(USE_POLL) && !defined(USE_KQUEUE) if (EXT(statp).nssocks[ns] > highestFD) { res_nclose(statp); errno = ENOTSOCK; } +#endif if (EXT(statp).nssocks[ns] < 0) { switch (errno) { case EPROTONOSUPPORT: @@ -835,8 +933,16 @@ send_dg(res_state statp, const u_char *b * socket operation, and select returns if the * error message is received. We can thus detect * the absence of a nameserver without timing out. - */ - if (connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) { + * + * When the option "insecure1" is specified, we'd + * rather expect to see responses from an "unknown" + * address. In order to let the kernel accept such + * responses, do not connect the socket here. + * XXX: or do we need an explicit option to disable + * connecting? + */ + if (!(statp->options & RES_INSECURE1) && + connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) { Aerror(statp, stderr, "connect(dg)", errno, nsap, nsaplen); res_nclose(statp); @@ -848,13 +954,20 @@ send_dg(res_state statp, const u_char *b } s = EXT(statp).nssocks[ns]; #ifndef CANNOT_CONNECT_DGRAM - if (send(s, (const char*)buf, buflen, 0) != buflen) { + if (statp->options & RES_INSECURE1) { + if (sendto(s, buf, buflen, 0, nsap, nsaplen) != + (ssize_t)buflen) { + Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); + res_nclose(statp); + return (0); + } + } else if (send(s, buf, buflen, 0) != (ssize_t)buflen) { Perror(statp, stderr, "send", errno); res_nclose(statp); return (0); } #else /* !CANNOT_CONNECT_DGRAM */ - if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) + if (sendto(s, buf, buflen, 0, nsap, nsaplen) != (ssize_t)buflen) { Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); res_nclose(statp); @@ -871,26 +984,31 @@ send_dg(res_state statp, const u_char *b if (seconds <= 0) seconds = 1; now = evNowTime(); - timeout = evConsTime(seconds, 0); + timeout = evConsTime((time_t)seconds, 0L); finish = evAddTime(now, timeout); goto nonow; wait: now = evNowTime(); nonow: #ifndef USE_POLL - FD_ZERO(&dsmask); - FD_SET(s, &dsmask); if (evCmpTime(finish, now) > 0) timeout = evSubTime(finish, now); else - timeout = evConsTime(0, 0); + timeout = evConsTime(0L, 0L); +#ifdef USE_KQUEUE + EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, 0); + n = kevent(kq, &kv, 1, &kv, 1, &timeout); +#else + FD_ZERO(&dsmask); + FD_SET(s, &dsmask); n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL); +#endif #else timeout = evSubTime(finish, now); if (timeout.tv_sec < 0) - timeout = evConsTime(0, 0); - polltimeout = 1000*timeout.tv_sec + - timeout.tv_nsec/1000000; + timeout = evConsTime((time_t)0, 0L); + polltimeout = 1000*(int)timeout.tv_sec + + (int)timeout.tv_nsec/1000000; pollfd.fd = s; pollfd.events = POLLRDNORM; n = poll(&pollfd, 1, polltimeout); @@ -902,20 +1020,27 @@ send_dg(res_state statp, const u_char *b return (0); } if (n < 0) { +#if defined(USE_POLL) + static const char *fun = "poll"; +#elif defined(USE_SELECT) + static const char *fun = "select"; +#elif defined(USE_KQUEUE) + static const char *fun = "kevent"; +#endif if (errno == EINTR) goto wait; -#ifndef USE_POLL - Perror(statp, stderr, "select", errno); -#else - Perror(statp, stderr, "poll", errno); -#endif /* USE_POLL */ + Perror(statp, stderr, fun, errno); res_nclose(statp); return (0); } +#ifdef USE_KQUEUE + if ((int)kv.ident != s) + goto wait; +#endif errno = 0; fromlen = sizeof(from); - resplen = recvfrom(s, (char*)ans, anssiz,0, - (struct sockaddr *)&from, &fromlen); + resplen = recvfrom(s, (char*)ans, (size_t)anssiz,0, + (struct sockaddr *)(void *)&from, &fromlen); if (resplen <= 0) { Perror(statp, stderr, "recvfrom", errno); res_nclose(statp); @@ -927,7 +1052,7 @@ send_dg(res_state statp, const u_char *b * Undersized message. */ Dprint(statp->options & RES_DEBUG, - (stdout, ";; undersized: %d\n", + (stdout, ";; undersized: %zd\n", resplen)); *terrno = EMSGSIZE; res_nclose(statp); @@ -946,7 +1071,7 @@ send_dg(res_state statp, const u_char *b goto wait; } if (!(statp->options & RES_INSECURE1) && - !res_ourserver_p(statp, (struct sockaddr *)&from)) { + !res_ourserver_p(statp, (struct sockaddr *)(void *)&from)) { /* * response from wrong server? ignore it. * XXX - potential security hazard could @@ -975,7 +1100,7 @@ send_dg(res_state statp, const u_char *b } #endif if (!(statp->options & RES_INSECURE2) && - !res_queriesmatch(buf, buf + buflen, + !res_queriesmatch(buf, (const u_char *)buf + buflen, ans, ans + anssiz)) { /* * response contains wrong query? ignore it. @@ -985,7 +1110,7 @@ send_dg(res_state statp, const u_char *b DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), (stdout, ";; wrong query name:\n"), - ans, (resplen > anssiz) ? anssiz : resplen); + ans, (int)(resplen > anssiz) ? anssiz : resplen); goto wait; } if (anhp->rcode == SERVFAIL || @@ -993,7 +1118,7 @@ send_dg(res_state statp, const u_char *b anhp->rcode == REFUSED) { DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query:\n"), - ans, (resplen > anssiz) ? anssiz : resplen); + ans, (int)(resplen > anssiz) ? anssiz : resplen); res_nclose(statp); /* don't retry if called from dig */ if (!statp->pfcode) @@ -1014,20 +1139,22 @@ send_dg(res_state statp, const u_char *b * All is well, or the error is fatal. Signal that the * next nameserver ought not be tried. */ - return (resplen); + _DIAGASSERT(__type_fit(int, resplen)); + return (int)resplen; } static void Aerror(const res_state statp, FILE *file, const char *string, int error, - const struct sockaddr *address, int alen) + const struct sockaddr *address, socklen_t alen) { int save = errno; char hbuf[NI_MAXHOST]; char sbuf[NI_MAXSERV]; if ((statp->options & RES_DEBUG) != 0U) { - if (getnameinfo(address, alen, hbuf, sizeof(hbuf), - sbuf, sizeof(sbuf), niflags)) { + if (getnameinfo(address, alen, hbuf, + (socklen_t)sizeof(hbuf), sbuf, (socklen_t)sizeof(sbuf), + niflags)) { strncpy(hbuf, "?", sizeof(hbuf) - 1); hbuf[sizeof(hbuf) - 1] = '\0'; strncpy(sbuf, "?", sizeof(sbuf) - 1); @@ -1058,13 +1185,13 @@ sock_eq(struct sockaddr *a, struct socka return 0; switch (a->sa_family) { case AF_INET: - a4 = (struct sockaddr_in *)a; - b4 = (struct sockaddr_in *)b; + a4 = (struct sockaddr_in *)(void *)a; + b4 = (struct sockaddr_in *)(void *)b; return a4->sin_port == b4->sin_port && a4->sin_addr.s_addr == b4->sin_addr.s_addr; case AF_INET6: - a6 = (struct sockaddr_in6 *)a; - b6 = (struct sockaddr_in6 *)b; + a6 = (struct sockaddr_in6 *)(void *)a; + b6 = (struct sockaddr_in6 *)(void *)b; return a6->sin6_port == b6->sin6_port && #ifdef HAVE_SIN6_SCOPE_ID a6->sin6_scope_id == b6->sin6_scope_id && @@ -1075,7 +1202,7 @@ sock_eq(struct sockaddr *a, struct socka } } -#if defined(NEED_PSELECT) && !defined(USE_POLL) +#if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE) /* XXX needs to move to the porting library. */ static int pselect(int nfds, void *rfds, void *wfds, void *efds, diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_sendsigned.c /usr/src/lib/libc/resolv/res_sendsigned.c --- /home/reed/src/isc/libbind/libbind/resolv/res_sendsigned.c 2006-03-09 17:57:56.000000000 -0600 +++ /usr/src/lib/libc/resolv/res_sendsigned.c 1969-12-31 18:00:00.000000000 -0600 @@ -1,170 +0,0 @@ -#include "port_before.h" -#include "fd_setsize.h" - -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "port_after.h" - -#define DEBUG -#include "res_debug.h" - - -/*% res_nsendsigned */ -int -res_nsendsigned(res_state statp, const u_char *msg, int msglen, - ns_tsig_key *key, u_char *answer, int anslen) -{ - res_state nstatp; - DST_KEY *dstkey; - int usingTCP = 0; - u_char *newmsg; - int newmsglen, bufsize, siglen; - u_char sig[64]; - HEADER *hp; - time_t tsig_time; - int ret; - int len; - - dst_init(); - - nstatp = (res_state) malloc(sizeof(*statp)); - if (nstatp == NULL) { - errno = ENOMEM; - return (-1); - } - memcpy(nstatp, statp, sizeof(*statp)); - - bufsize = msglen + 1024; - newmsg = (u_char *) malloc(bufsize); - if (newmsg == NULL) { - free(nstatp); - errno = ENOMEM; - return (-1); - } - memcpy(newmsg, msg, msglen); - newmsglen = msglen; - - if (ns_samename(key->alg, NS_TSIG_ALG_HMAC_MD5) != 1) - dstkey = NULL; - else - dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5, - NS_KEY_TYPE_AUTH_ONLY, - NS_KEY_PROT_ANY, - key->data, key->len); - if (dstkey == NULL) { - errno = EINVAL; - free(nstatp); - free(newmsg); - return (-1); - } - - nstatp->nscount = 1; - siglen = sizeof(sig); - ret = ns_sign(newmsg, &newmsglen, bufsize, NOERROR, dstkey, NULL, 0, - sig, &siglen, 0); - if (ret < 0) { - free (nstatp); - free (newmsg); - dst_free_key(dstkey); - if (ret == NS_TSIG_ERROR_NO_SPACE) - errno = EMSGSIZE; - else if (ret == -1) - errno = EINVAL; - return (ret); - } - - if (newmsglen > PACKETSZ || nstatp->options & RES_USEVC) - usingTCP = 1; - if (usingTCP == 0) - nstatp->options |= RES_IGNTC; - else - nstatp->options |= RES_USEVC; - /* - * Stop res_send printing the answer. - */ - nstatp->options &= ~RES_DEBUG; - nstatp->pfcode &= ~RES_PRF_REPLY; - -retry: - - len = res_nsend(nstatp, newmsg, newmsglen, answer, anslen); - if (len < 0) { - free (nstatp); - free (newmsg); - dst_free_key(dstkey); - return (len); - } - - ret = ns_verify(answer, &len, dstkey, sig, siglen, - NULL, NULL, &tsig_time, nstatp->options & RES_KEEPTSIG); - if (ret != 0) { - Dprint((statp->options & RES_DEBUG) || - ((statp->pfcode & RES_PRF_REPLY) && - (statp->pfcode & RES_PRF_HEAD1)), - (stdout, ";; got answer:\n")); - - DprintQ((statp->options & RES_DEBUG) || - (statp->pfcode & RES_PRF_REPLY), - (stdout, "%s", ""), - answer, (anslen > len) ? len : anslen); - - if (ret > 0) { - Dprint(statp->pfcode & RES_PRF_REPLY, - (stdout, ";; server rejected TSIG (%s)\n", - p_rcode(ret))); - } else { - Dprint(statp->pfcode & RES_PRF_REPLY, - (stdout, ";; TSIG invalid (%s)\n", - p_rcode(-ret))); - } - - free (nstatp); - free (newmsg); - dst_free_key(dstkey); - if (ret == -1) - errno = EINVAL; - else - errno = ENOTTY; - return (-1); - } - - hp = (HEADER *) answer; - if (hp->tc && !usingTCP && (statp->options & RES_IGNTC) == 0U) { - nstatp->options &= ~RES_IGNTC; - usingTCP = 1; - goto retry; - } - Dprint((statp->options & RES_DEBUG) || - ((statp->pfcode & RES_PRF_REPLY) && - (statp->pfcode & RES_PRF_HEAD1)), - (stdout, ";; got answer:\n")); - - DprintQ((statp->options & RES_DEBUG) || - (statp->pfcode & RES_PRF_REPLY), - (stdout, "%s", ""), - answer, (anslen > len) ? len : anslen); - - Dprint(statp->pfcode & RES_PRF_REPLY, (stdout, ";; TSIG ok\n")); - - free (nstatp); - free (newmsg); - dst_free_key(dstkey); - return (len); -} - -/*! \file */ diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_state.c /usr/src/lib/libc/resolv/res_state.c --- /home/reed/src/isc/libbind/libbind/resolv/res_state.c 1969-12-31 18:00:00.000000000 -0600 +++ /usr/src/lib/libc/resolv/res_state.c 2012-10-24 08:34:38.000000000 -0500 @@ -0,0 +1,73 @@ +/* $NetBSD: res_state.c,v 1.8 2009/01/11 02:46:29 christos Exp $ */ + +/*- + * Copyright (c) 2004 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: res_state.c,v 1.8 2009/01/11 02:46:29 christos Exp $"); +#endif + +#include +#include +#include +#include +#include + +struct __res_state _nres +# if defined(__BIND_RES_TEXT) + = { .retrans = RES_TIMEOUT, } /*%< Motorola, et al. */ +# endif + ; + +res_state __res_get_state_nothread(void); +void __res_put_state_nothread(res_state); + +#ifdef __weak_alias +__weak_alias(__res_get_state, __res_get_state_nothread) +__weak_alias(__res_put_state, __res_put_state_nothread) +/* Source compatibility; only for single threaded programs */ +__weak_alias(__res_state, __res_get_state_nothread) +#endif + +res_state +__res_get_state_nothread(void) +{ + if ((_nres.options & RES_INIT) == 0 && res_ninit(&_nres) == -1) { + h_errno = NETDB_INTERNAL; + return NULL; + } + return &_nres; +} + +void +/*ARGSUSED*/ +__res_put_state_nothread(res_state res) +{ +} diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_update.c /usr/src/lib/libc/resolv/res_update.c --- /home/reed/src/isc/libbind/libbind/resolv/res_update.c 2005-04-26 23:56:43.000000000 -0500 +++ /usr/src/lib/libc/resolv/res_update.c 1969-12-31 18:00:00.000000000 -0600 @@ -1,213 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_update.c,v 1.13 2005/04/27 04:56:43 sra Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and 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. - */ - -/*! \file - * \brief - * Based on the Dynamic DNS reference implementation by Viraj Bais - * <viraj_bais@ccm.fm.intel.com> - */ - -#include "port_before.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "port_after.h" -#include "res_private.h" - -/*% - * Separate a linked list of records into groups so that all records - * in a group will belong to a single zone on the nameserver. - * Create a dynamic update packet for each zone and send it to the - * nameservers for that zone, and await answer. - * Abort if error occurs in updating any zone. - * Return the number of zones updated on success, < 0 on error. - * - * On error, caller must deal with the unsynchronized zones - * eg. an A record might have been successfully added to the forward - * zone but the corresponding PTR record would be missing if error - * was encountered while updating the reverse zone. - */ - -struct zonegrp { - char z_origin[MAXDNAME]; - ns_class z_class; - union res_sockaddr_union z_nsaddrs[MAXNS]; - int z_nscount; - int z_flags; - LIST(ns_updrec) z_rrlist; - LINK(struct zonegrp) z_link; -}; - -#define ZG_F_ZONESECTADDED 0x0001 - -/* Forward. */ - -static void res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2); - -/* Macros. */ - -#define DPRINTF(x) do {\ - int save_errno = errno; \ - if ((statp->options & RES_DEBUG) != 0U) res_dprintf x; \ - errno = save_errno; \ - } while (0) - -/* Public. */ - -int -res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { - ns_updrec *rrecp; - u_char answer[PACKETSZ]; - u_char *packet; - struct zonegrp *zptr, tgrp; - LIST(struct zonegrp) zgrps; - int nzones = 0, nscount = 0, n; - union res_sockaddr_union nsaddrs[MAXNS]; - - packet = malloc(NS_MAXMSG); - if (packet == NULL) { - DPRINTF(("malloc failed")); - return (0); - } - /* Thread all of the updates onto a list of groups. */ - INIT_LIST(zgrps); - memset(&tgrp, 0, sizeof (tgrp)); - for (rrecp = rrecp_in; rrecp; - rrecp = LINKED(rrecp, r_link) ? NEXT(rrecp, r_link) : NULL) { - int nscnt; - /* Find the origin for it if there is one. */ - tgrp.z_class = rrecp->r_class; - nscnt = res_findzonecut2(statp, rrecp->r_dname, tgrp.z_class, - RES_EXHAUSTIVE, tgrp.z_origin, - sizeof tgrp.z_origin, - tgrp.z_nsaddrs, MAXNS); - if (nscnt <= 0) { - DPRINTF(("res_findzonecut failed (%d)", nscnt)); - goto done; - } - tgrp.z_nscount = nscnt; - /* Find the group for it if there is one. */ - for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) - if (ns_samename(tgrp.z_origin, zptr->z_origin) == 1 && - tgrp.z_class == zptr->z_class) - break; - /* Make a group for it if there isn't one. */ - if (zptr == NULL) { - zptr = malloc(sizeof *zptr); - if (zptr == NULL) { - DPRINTF(("malloc failed")); - goto done; - } - *zptr = tgrp; - zptr->z_flags = 0; - INIT_LINK(zptr, z_link); - INIT_LIST(zptr->z_rrlist); - APPEND(zgrps, zptr, z_link); - } - /* Thread this rrecp onto the right group. */ - APPEND(zptr->z_rrlist, rrecp, r_glink); - } - - for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) { - /* Construct zone section and prepend it. */ - rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin, - zptr->z_class, ns_t_soa, 0); - if (rrecp == NULL) { - DPRINTF(("res_mkupdrec failed")); - goto done; - } - PREPEND(zptr->z_rrlist, rrecp, r_glink); - zptr->z_flags |= ZG_F_ZONESECTADDED; - - /* Marshall the update message. */ - n = res_nmkupdate(statp, HEAD(zptr->z_rrlist), - packet, NS_MAXMSG); - DPRINTF(("res_mkupdate -> %d", n)); - if (n < 0) - goto done; - - /* Temporarily replace the resolver's nameserver set. */ - nscount = res_getservers(statp, nsaddrs, MAXNS); - res_setservers(statp, zptr->z_nsaddrs, zptr->z_nscount); - - /* Send the update and remember the result. */ - if (key != NULL) - n = res_nsendsigned(statp, packet, n, key, - answer, sizeof answer); - else - n = res_nsend(statp, packet, n, answer, sizeof answer); - if (n < 0) { - DPRINTF(("res_nsend: send error, n=%d (%s)\n", - n, strerror(errno))); - goto done; - } - if (((HEADER *)answer)->rcode == NOERROR) - nzones++; - - /* Restore resolver's nameserver set. */ - res_setservers(statp, nsaddrs, nscount); - nscount = 0; - } - done: - while (!EMPTY(zgrps)) { - zptr = HEAD(zgrps); - if ((zptr->z_flags & ZG_F_ZONESECTADDED) != 0) - res_freeupdrec(HEAD(zptr->z_rrlist)); - UNLINK(zgrps, zptr, z_link); - free(zptr); - } - if (nscount != 0) - res_setservers(statp, nsaddrs, nscount); - - free(packet); - return (nzones); -} - -/* Private. */ - -static void -res_dprintf(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - fputs(";; res_nupdate: ", stderr); - vfprintf(stderr, fmt, ap); - fputc('\n', stderr); - va_end(ap); -}