diff options
Diffstat (limited to 'resolv')
-rw-r--r-- | resolv/Depend | 1 | ||||
-rw-r--r-- | resolv/Makefile | 4 | ||||
-rw-r--r-- | resolv/Versions | 2 | ||||
-rw-r--r-- | resolv/gai_cancel.c | 4 | ||||
-rw-r--r-- | resolv/gai_error.c | 4 | ||||
-rw-r--r-- | resolv/gai_misc.c | 32 | ||||
-rw-r--r-- | resolv/gai_misc.h | 4 | ||||
-rw-r--r-- | resolv/gai_notify.c | 53 | ||||
-rw-r--r-- | resolv/gai_sigqueue.c | 36 | ||||
-rw-r--r-- | resolv/gai_suspend.c | 19 | ||||
-rw-r--r-- | resolv/getaddrinfo_a.c | 21 | ||||
-rw-r--r-- | resolv/gethnamaddr.c | 10 | ||||
-rw-r--r-- | resolv/herror.c | 5 | ||||
-rw-r--r-- | resolv/inet_ntop.c | 2 | ||||
-rw-r--r-- | resolv/nss_dns/dns-canon.c | 16 | ||||
-rw-r--r-- | resolv/nss_dns/dns-host.c | 15 | ||||
-rw-r--r-- | resolv/nss_dns/dns-network.c | 47 | ||||
-rw-r--r-- | resolv/res-state.c | 45 | ||||
-rw-r--r-- | resolv/res_data.c | 4 | ||||
-rw-r--r-- | resolv/res_debug.c | 24 | ||||
-rw-r--r-- | resolv/res_hconf.c | 221 | ||||
-rw-r--r-- | resolv/res_hconf.h | 13 | ||||
-rw-r--r-- | resolv/res_init.c | 36 | ||||
-rw-r--r-- | resolv/res_libc.c | 16 | ||||
-rw-r--r-- | resolv/res_mkquery.c | 48 | ||||
-rw-r--r-- | resolv/res_query.c | 6 | ||||
-rw-r--r-- | resolv/res_send.c | 123 | ||||
-rw-r--r-- | resolv/tst-inet_ntop.c | 111 |
28 files changed, 391 insertions, 531 deletions
diff --git a/resolv/Depend b/resolv/Depend index 8d2587bbc1..fe673ba5ec 100644 --- a/resolv/Depend +++ b/resolv/Depend @@ -1,2 +1 @@ linuxthreads -nptl diff --git a/resolv/Makefile b/resolv/Makefile index 6ac226735a..f6230da8fb 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2003,2004,2007 +# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2003,2004 # Free Software Foundation, Inc. # This file is part of the GNU C Library. @@ -32,7 +32,7 @@ distribute := ../conf/portability.h mapv4v6addr.h mapv4v6hostent.h \ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ res_hconf res_libc res-state -tests = tst-aton tst-leaks tst-inet_ntop +tests = tst-aton tst-leaks xtests = tst-leaks2 generate := mtrace-tst-leaks tst-leaks.mtrace tst-leaks2.mtrace diff --git a/resolv/Versions b/resolv/Versions index 7016365be5..2a67677d8e 100644 --- a/resolv/Versions +++ b/resolv/Versions @@ -39,7 +39,7 @@ libc { h_errno; __resp; %endif - __res_maybe_init; __res_iclose; + __res_maybe_init; } } diff --git a/resolv/gai_cancel.c b/resolv/gai_cancel.c index 19a0a9bb87..45432065c4 100644 --- a/resolv/gai_cancel.c +++ b/resolv/gai_cancel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -20,7 +20,7 @@ #include <netdb.h> #include <pthread.h> -#include <gai_misc.h> +#include "gai_misc.h" int diff --git a/resolv/gai_error.c b/resolv/gai_error.c index 4c91628a62..0620b04b9d 100644 --- a/resolv/gai_error.c +++ b/resolv/gai_error.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -19,7 +19,7 @@ #include <netdb.h> -#include <gai_misc.h> +#include "gai_misc.h" int gai_error (struct gaicb *req) diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c index 2eec0f529d..b3334f38ef 100644 --- a/resolv/gai_misc.c +++ b/resolv/gai_misc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -23,31 +23,10 @@ #include <stdlib.h> #include <sys/time.h> -#include <gai_misc.h> +#include "gai_misc.h" -#ifndef gai_create_helper_thread -# define gai_create_helper_thread __gai_create_helper_thread - -extern inline int -__gai_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), - void *arg) -{ - pthread_attr_t attr; - - /* Make sure the thread is created detached. */ - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - - int ret = pthread_create (threadp, &attr, tf, arg); - - (void) pthread_attr_destroy (&attr); - return ret; -} -#endif - - /* Pool of request list entries. */ static struct requestlist **pool; @@ -250,11 +229,16 @@ __gai_enqueue_request (struct gaicb *gaicbp) if (nthreads < optim.gai_threads && idle_thread_count == 0) { pthread_t thid; + pthread_attr_t attr; newp->running = 1; + /* Make sure the thread is created detached. */ + pthread_attr_init (&attr); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + /* Now try to start a thread. */ - if (gai_create_helper_thread (&thid, handle_requests, newp) == 0) + if (pthread_create (&thid, &attr, handle_requests, newp) == 0) /* We managed to enqueue the request. All errors which can happen now can be recognized by calls to `gai_error'. */ ++nthreads; diff --git a/resolv/gai_misc.h b/resolv/gai_misc.h index 94005de02c..48a93977ae 100644 --- a/resolv/gai_misc.h +++ b/resolv/gai_misc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -29,9 +29,7 @@ struct waitlist { struct waitlist *next; -#ifndef DONT_NEED_GAI_MISC_COND pthread_cond_t *cond; -#endif volatile int *counterp; /* The next field is used in asynchronous `lio_listio' operations. */ struct sigevent *sigevp; diff --git a/resolv/gai_notify.c b/resolv/gai_notify.c index c3ce0afb45..987a64c0e2 100644 --- a/resolv/gai_notify.c +++ b/resolv/gai_notify.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -20,24 +20,15 @@ #include <netdb.h> #include <pthread.h> #include <stdlib.h> -#include <gai_misc.h> +#include "gai_misc.h" -struct notify_func - { - void (*func) (sigval_t); - sigval_t value; - }; static void * notify_func_wrapper (void *arg) { - gai_start_notify_thread (); - struct notify_func *const n = arg; - void (*func) (sigval_t) = n->func; - sigval_t value = n->value; - free (n); - (*func) (value); + struct sigevent *sigev = arg; + sigev->sigev_notify_function (sigev->sigev_value); return NULL; } @@ -63,26 +54,8 @@ __gai_notify_only (struct sigevent *sigev, pid_t caller_pid) pattr = &attr; } - /* SIGEV may be freed as soon as we return, so we cannot let the - notification thread use that pointer. Even though a sigval_t is - only one word and the same size as a void *, we cannot just pass - the value through pthread_create as the argument and have the new - thread run the user's function directly, because on some machines - the calling convention for a union like sigval_t is different from - that for a pointer type like void *. */ - struct notify_func *nf = malloc (sizeof *nf); - if (nf == NULL) + if (pthread_create (&tid, pattr, notify_func_wrapper, sigev) < 0) result = -1; - else - { - nf->func = sigev->sigev_notify_function; - nf->value = sigev->sigev_value; - if (pthread_create (&tid, pattr, notify_func_wrapper, nf) < 0) - { - free (nf); - result = -1; - } - } } else if (sigev->sigev_notify == SIGEV_SIGNAL) /* We have to send a signal. */ @@ -106,21 +79,15 @@ __gai_notify (struct requestlist *req) { struct waitlist *next = waitlist->next; + /* Decrement the counter. This is used in both cases. */ + --*waitlist->counterp; + if (waitlist->sigevp == NULL) - { -#ifdef DONT_NEED_GAI_MISC_COND - GAI_MISC_NOTIFY (waitlist); -#else - /* Decrement the counter. */ - --*waitlist->counterp; - - pthread_cond_signal (waitlist->cond); -#endif - } + pthread_cond_signal (waitlist->cond); else /* This is part of a asynchronous `getaddrinfo_a' operation. If this request is the last one, send the signal. */ - if (--*waitlist->counterp == 0) + if (*waitlist->counterp == 0) { __gai_notify_only (waitlist->sigevp, waitlist->caller_pid); /* This is tricky. See getaddrinfo_a.c for the reason why diff --git a/resolv/gai_sigqueue.c b/resolv/gai_sigqueue.c deleted file mode 100644 index 278a1d8026..0000000000 --- a/resolv/gai_sigqueue.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <aio.h> -#include <errno.h> -#include <signal.h> - -#include <gai_misc.h> - -int -__gai_sigqueue (sig, val, caller_pid) - int sig; - const union sigval val; - pid_t caller_pid; -{ - __set_errno (ENOSYS); - return -1; -} - -stub_warning (__gai_sigqueue) -#include <stub-tag.h> diff --git a/resolv/gai_suspend.c b/resolv/gai_suspend.c index 4d85ac2c10..bb3c9c3402 100644 --- a/resolv/gai_suspend.c +++ b/resolv/gai_suspend.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -23,7 +23,7 @@ #include <stdlib.h> #include <sys/time.h> -#include <gai_misc.h> +#include "gai_misc.h" int @@ -32,11 +32,9 @@ gai_suspend (const struct gaicb *const list[], int ent, { struct waitlist waitlist[ent]; struct requestlist *requestlist[ent]; -#ifndef DONT_NEED_GAI_MISC_COND pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -#endif int cnt; - int cntr = 1; + int dummy; int none = 1; int result; @@ -52,11 +50,9 @@ gai_suspend (const struct gaicb *const list[], int ent, if (requestlist[cnt] != NULL) { -#ifndef DONT_NEED_GAI_MISC_COND waitlist[cnt].cond = &cond; -#endif waitlist[cnt].next = requestlist[cnt]->waiting; - waitlist[cnt].counterp = &cntr; + waitlist[cnt].counterp = &dummy; waitlist[cnt].sigevp = NULL; waitlist[cnt].caller_pid = 0; /* Not needed. */ requestlist[cnt]->waiting = &waitlist[cnt]; @@ -82,10 +78,6 @@ gai_suspend (const struct gaicb *const list[], int ent, which we must remove. So defer cancelation for now. */ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate); -#ifdef DONT_NEED_GAI_MISC_COND - result = 0; - GAI_MISC_WAIT (result, cntr, timeout, 1); -#else if (timeout == NULL) result = pthread_cond_wait (&cond, &__gai_requests_mutex); else @@ -107,7 +99,6 @@ gai_suspend (const struct gaicb *const list[], int ent, result = pthread_cond_timedwait (&cond, &__gai_requests_mutex, &abstime); } -#endif /* Now remove the entry in the waiting list for all requests which didn't terminate. */ @@ -130,12 +121,10 @@ gai_suspend (const struct gaicb *const list[], int ent, /* Now it's time to restore the cancelation state. */ pthread_setcancelstate (oldstate, NULL); -#ifndef DONT_NEED_GAI_MISC_COND /* Release the conditional variable. */ if (pthread_cond_destroy (&cond) != 0) /* This must never happen. */ abort (); -#endif if (result != 0) { diff --git a/resolv/getaddrinfo_a.c b/resolv/getaddrinfo_a.c index f6af3aa45a..abac27d361 100644 --- a/resolv/getaddrinfo_a.c +++ b/resolv/getaddrinfo_a.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -23,7 +23,7 @@ #include <stdlib.h> #include <unistd.h> -#include <gai_misc.h> +#include "gai_misc.h" /* We need this special structure to handle asynchronous I/O. */ @@ -96,9 +96,7 @@ getaddrinfo_a (int mode, struct gaicb *list[], int ent, struct sigevent *sig) } else if (mode == GAI_WAIT) { -#ifndef DONT_NEED_GAI_MISC_COND pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -#endif struct waitlist waitlist[ent]; int oldstate; @@ -106,9 +104,7 @@ getaddrinfo_a (int mode, struct gaicb *list[], int ent, struct sigevent *sig) for (cnt = 0; cnt < ent; ++cnt) if (requests[cnt] != NULL) { -#ifndef DONT_NEED_GAI_MISC_COND waitlist[cnt].cond = &cond; -#endif waitlist[cnt].next = requests[cnt]->waiting; waitlist[cnt].counterp = &total; waitlist[cnt].sigevp = NULL; @@ -123,24 +119,15 @@ getaddrinfo_a (int mode, struct gaicb *list[], int ent, struct sigevent *sig) pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate); while (total > 0) - { -#ifdef DONT_NEED_GAI_MISC_COND - int result; - GAI_MISC_WAIT (result, total, NULL, 1); -#else - pthread_cond_wait (&cond, &__gai_requests_mutex); -#endif - } + pthread_cond_wait (&cond, &__gai_requests_mutex); /* Now it's time to restore the cancelation state. */ pthread_setcancelstate (oldstate, NULL); -#ifndef DONT_NEED_GAI_MISC_COND /* Release the conditional variable. */ if (pthread_cond_destroy (&cond) != 0) /* This must never happen. */ abort (); -#endif } else { @@ -160,9 +147,7 @@ getaddrinfo_a (int mode, struct gaicb *list[], int ent, struct sigevent *sig) for (cnt = 0; cnt < ent; ++cnt) if (requests[cnt] != NULL) { -#ifndef DONT_NEED_GAI_MISC_COND waitlist->list[cnt].cond = NULL; -#endif waitlist->list[cnt].next = requests[cnt]->waiting; waitlist->list[cnt].counterp = &waitlist->counter; waitlist->list[cnt].sigevp = &waitlist->sigev; diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c index 7be23158d0..3698e4b841 100644 --- a/resolv/gethnamaddr.c +++ b/resolv/gethnamaddr.c @@ -51,6 +51,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -176,7 +177,11 @@ Dprintf(msg, num) static struct hostent * -getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) +getanswer(answer, anslen, qname, qtype) + const querybuf *answer; + int anslen; + const char *qname; + int qtype; { register const HEADER *hp; register const u_char *cp; @@ -518,6 +523,7 @@ gethostbyname2(name, af) char *bp; int n, size, type, len; struct hostent *ret; + extern struct hostent *_gethtbyname2(); if (__res_maybe_init (&_res, 0) == -1) { __set_h_errno (NETDB_INTERNAL); @@ -661,6 +667,7 @@ gethostbyaddr(addr, len, af) u_long old_options; char hname2[MAXDNAME+1]; #endif /*SUNSECURITY*/ + extern struct hostent *_gethtbyaddr(); if (__res_maybe_init (&_res, 0) == -1) { __set_h_errno (NETDB_INTERNAL); @@ -873,6 +880,7 @@ struct hostent * _gethtbyname(name) const char *name; { + extern struct hostent *_gethtbyname2(); struct hostent *hp; if (_res.options & RES_USE_INET6) { diff --git a/resolv/herror.c b/resolv/herror.c index 0aaf29f9db..a61a3a9a4d 100644 --- a/resolv/herror.c +++ b/resolv/herror.c @@ -64,14 +64,14 @@ static const char rcsid[] = "$BINDId: herror.c,v 8.11 1999/10/13 16:39:39 vixie #include <libintl.h> #include <not-cancel.h> -const char *const h_errlist[] = { +const char *h_errlist[] = { N_("Resolver Error 0 (no error)"), N_("Unknown host"), /* 1 HOST_NOT_FOUND */ N_("Host name lookup failure"), /* 2 TRY_AGAIN */ N_("Unknown server error"), /* 3 NO_RECOVERY */ N_("No address associated with name"), /* 4 NO_ADDRESS */ }; -const int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; +int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; /* * herror -- @@ -80,6 +80,7 @@ const int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; void herror(const char *s) { struct iovec iov[4], *v = iov; + extern int * __h_errno(); if (s != NULL && *s != '\0') { v->iov_base = (/*noconst*/ char *)s; diff --git a/resolv/inet_ntop.c b/resolv/inet_ntop.c index 1222d08bda..e5553a1d3b 100644 --- a/resolv/inet_ntop.c +++ b/resolv/inet_ntop.c @@ -96,7 +96,7 @@ inet_ntop4(src, dst, size) static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; - if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) >= size) { + if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) { __set_errno (ENOSPC); return (NULL); } diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c index fca6cd8997..91708df51f 100644 --- a/resolv/nss_dns/dns-canon.c +++ b/resolv/nss_dns/dns-canon.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. @@ -40,10 +40,6 @@ typedef union querybuf } querybuf; -static const short int qtypes[] = { ns_t_a, ns_t_aaaa }; -#define nqtypes (sizeof (qtypes) / sizeof (qtypes[0])) - - enum nss_status _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, char **result,int *errnop, int *h_errnop) @@ -57,6 +53,8 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, unsigned char *ptr; } ansp = { .ptr = buf }; enum nss_status status = NSS_STATUS_UNAVAIL; + int qtypes[] = { ns_t_a, ns_t_aaaa }; +#define nqtypes (sizeof (qtypes) / sizeof (qtypes[0])) for (int i = 0; i < nqtypes; ++i) { @@ -103,8 +101,7 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, ptr += s; /* Check whether type and class match. */ - uint_fast16_t type; - NS_GET16 (type, ptr); + unsigned int type = ntohs (*(uint16_t *) ptr); if (type == qtypes[i]) { /* We found the record. */ @@ -133,14 +130,15 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, if (type != ns_t_cname) goto unavail; - if (ns_get16 (ptr) != ns_c_in) + ptr += sizeof (uint16_t); + if (*(uint16_t *) ptr != htons (ns_c_in)) goto unavail; /* Also skip over the TTL. */ ptr += sizeof (uint16_t) + sizeof (uint32_t); /* Skip over the data length and data. */ - ptr += sizeof (uint16_t) + ns_get16 (ptr); + ptr += sizeof (uint16_t) + ntohs (*(uint16_t *) ptr); } } } diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index cf060be8ef..7045c5915b 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2003, 2004, 2007 Free Software Foundation, Inc. +/* Copyright (C) 1996-2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -465,8 +465,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, char *aliases[MAX_NR_ALIASES]; unsigned char host_addr[16]; /* IPv4 or IPv6 */ char *h_addr_ptrs[0]; - } *host_data; - int linebuflen; + } *host_data = (struct host_data *) buffer; + int linebuflen = buflen - sizeof (struct host_data); register const HEADER *hp; const u_char *end_of_message, *cp; int n, ancount, qdcount; @@ -478,9 +478,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, u_char packtmp[NS_MAXCDNAME]; int have_to_map = 0; int32_t ttl = 0; - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); - buffer += pad; - if (__builtin_expect (buflen < sizeof (struct host_data) + pad, 0)) + + if (__builtin_expect (linebuflen, 0) < 0) { /* The buffer is too small. */ too_small: @@ -488,10 +487,6 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, *h_errnop = NETDB_INTERNAL; return NSS_STATUS_TRYAGAIN; } - host_data = (struct host_data *) buffer; - linebuflen = buflen - sizeof (struct host_data); - if (buflen - sizeof (struct host_data) != linebuflen) - linebuflen = INT_MAX; tname = qname; result->h_name = NULL; diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c index 4552b5b678..6ff60f3119 100644 --- a/resolv/nss_dns/dns-network.c +++ b/resolv/nss_dns/dns-network.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2007 +/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -102,8 +102,7 @@ extern int __ns_name_unpack (const u_char *, const u_char *, /* Prototypes for local functions. */ static enum nss_status getanswer_r (const querybuf *answer, int anslen, struct netent *result, char *buffer, - size_t buflen, int *errnop, int *h_errnop, - lookup_method net_i); + size_t buflen, lookup_method net_i); enum nss_status @@ -143,8 +142,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result, ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } - status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen, - errnop, herrnop, BYNAME); + status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen, BYNAME); if (net_buffer.buf != orig_net_buffer) free (net_buffer.buf); return status; @@ -220,8 +218,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } - status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen, - errnop, herrnop, BYADDR); + status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen, BYADDR); if (net_buffer.buf != orig_net_buffer) free (net_buffer.buf); if (status == NSS_STATUS_SUCCESS) @@ -243,8 +240,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, static enum nss_status getanswer_r (const querybuf *answer, int anslen, struct netent *result, - char *buffer, size_t buflen, int *errnop, int *h_errnop, - lookup_method net_i) + char *buffer, size_t buflen, lookup_method net_i) { /* * Find first satisfactory answer @@ -264,33 +260,16 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, { char *aliases[MAX_NR_ALIASES]; char linebuffer[0]; - } *net_data; - - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct net_data); - buffer += pad; - - if (__builtin_expect (buflen < sizeof (*net_data) + pad, 0)) - { - /* The buffer is too small. */ - too_small: - *errnop = ERANGE; - *h_errnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - buflen -= pad; - - net_data = (struct net_data *) buffer; + } *net_data = (struct net_data *) buffer; int linebuflen = buflen - offsetof (struct net_data, linebuffer); - if (buflen - offsetof (struct net_data, linebuffer) != linebuflen) - linebuflen = INT_MAX; - const unsigned char *end_of_message = &answer->buf[anslen]; + const char *end_of_message = &answer->buf[anslen]; const HEADER *header_pointer = &answer->hdr; /* #/records in the answer section. */ int answer_count = ntohs (header_pointer->ancount); /* #/entries in the question section. */ int question_count = ntohs (header_pointer->qdcount); char *bp = net_data->linebuffer; - const unsigned char *cp = &answer->buf[HFIXEDSZ]; + const char *cp = &answer->buf[HFIXEDSZ]; char **alias_pointer; int have_answer; char *ans; @@ -340,7 +319,10 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) { if (errno == EMSGSIZE) - goto too_small; + { + errno = ERANGE; + return NSS_STATUS_TRYAGAIN; + } n = -1; } @@ -364,7 +346,10 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) { if (errno == EMSGSIZE) - goto too_small; + { + errno = ERANGE; + return NSS_STATUS_TRYAGAIN; + } n = -1; } diff --git a/resolv/res-state.c b/resolv/res-state.c deleted file mode 100644 index e327e34f59..0000000000 --- a/resolv/res-state.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 1996, 97, 98, 2002, 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <resolv.h> -#include <tls.h> - -#if ! USE___THREAD - -# undef _res -extern struct __res_state _res; - -/* When threaded, _res may be a per-thread variable. */ -struct __res_state * -weak_const_function -__res_state (void) -{ - return &_res; -} - -#else - -struct __res_state * -__res_state (void) -{ - return __resp; -} - -#endif - -libc_hidden_def (__res_state) diff --git a/resolv/res_data.c b/resolv/res_data.c index 1beea1dc4f..adadcdcd7a 100644 --- a/resolv/res_data.c +++ b/resolv/res_data.c @@ -246,9 +246,7 @@ res_close(void) { if ((_res.options & RES_INIT) == 0) return; #endif - /* We don't free the name server addresses because we never - did it and it would be done implicitly on shutdown. */ - __res_iclose(&_res, false); + res_nclose(&_res); } #ifdef BIND_UPDATE diff --git a/resolv/res_debug.c b/resolv/res_debug.c index d9f1607df6..839069de3d 100644 --- a/resolv/res_debug.c +++ b/resolv/res_debug.c @@ -626,7 +626,8 @@ static const unsigned int poweroften[10]= /* takes an XeY precision/size value, returns a string representation. */ static const char * -precsize_ntoa (u_int8_t prec) +precsize_ntoa(prec) + u_int8_t prec; { static char retbuf[sizeof "90000000.00"]; /* XXX nonreentrant */ unsigned long val; @@ -643,7 +644,8 @@ precsize_ntoa (u_int8_t prec) /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */ static u_int8_t -precsize_aton (const char **strptr) +precsize_aton(strptr) + const char **strptr; { unsigned int mval = 0, cmval = 0; u_int8_t retval = 0; @@ -684,7 +686,9 @@ precsize_aton (const char **strptr) /* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */ static u_int32_t -latlon2ul (const char **latlonstrptr, int *which) +latlon2ul(latlonstrptr,which) + const char **latlonstrptr; + int *which; { const char *cp; u_int32_t retval; @@ -896,7 +900,7 @@ loc_ntoa(binary, ascii) const u_char *binary; char *ascii; { - static const char error[] = "?"; + static char *error = "?"; static char tmpbuf[sizeof "1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"]; const u_char *cp = binary; @@ -976,11 +980,11 @@ loc_ntoa(binary, ascii) altmeters = (altval / 100) * altsign; if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL) - sizestr = (char *) error; + sizestr = error; if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL) - hpstr = (char *) error; + hpstr = error; if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL) - vpstr = (char *) error; + vpstr = error; sprintf(ascii, "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm", @@ -988,11 +992,11 @@ loc_ntoa(binary, ascii) longdeg, longmin, longsec, longsecfrac, eastwest, altmeters, altfrac, sizestr, hpstr, vpstr); - if (sizestr != (char *) error) + if (sizestr != error) free(sizestr); - if (hpstr != (char *) error) + if (hpstr != error) free(hpstr); - if (vpstr != (char *) error) + if (vpstr != error) free(vpstr); return (ascii); diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c index f45888933f..91cd300482 100644 --- a/resolv/res_hconf.c +++ b/resolv/res_hconf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995-2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995-2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by David Mosberger (davidm@azstarnet.com). @@ -53,34 +53,35 @@ /* Environment vars that all user to override default behavior: */ #define ENV_HOSTCONF "RESOLV_HOST_CONF" +#define ENV_SERVORDER "RESOLV_SERV_ORDER" #define ENV_SPOOF "RESOLV_SPOOF_CHECK" #define ENV_TRIM_OVERR "RESOLV_OVERRIDE_TRIM_DOMAINS" #define ENV_TRIM_ADD "RESOLV_ADD_TRIM_DOMAINS" #define ENV_MULTI "RESOLV_MULTI" #define ENV_REORDER "RESOLV_REORDER" -enum parse_cbs - { - CB_none, - CB_arg_trimdomain_list, - CB_arg_spoof, - CB_arg_bool - }; +static const char *arg_service_list (const char *, int, const char *, + unsigned int); +static const char *arg_trimdomain_list (const char *, int, const char *, + unsigned int); +static const char *arg_spoof (const char *, int, const char *, unsigned int); +static const char *arg_bool (const char *, int, const char *, unsigned int); -static const struct cmd +static struct cmd { - const char name[11]; - uint8_t cb; + const char *name; + const char *(*parse_args) (const char * filename, int line_num, + const char * args, unsigned int arg); unsigned int arg; } cmd[] = { - {"order", CB_none, 0}, - {"trim", CB_arg_trimdomain_list, 0}, - {"spoof", CB_arg_spoof, 0}, - {"multi", CB_arg_bool, HCONF_FLAG_MULTI}, - {"nospoof", CB_arg_bool, HCONF_FLAG_SPOOF}, - {"spoofalert", CB_arg_bool, HCONF_FLAG_SPOOFALERT}, - {"reorder", CB_arg_bool, HCONF_FLAG_REORDER} + {"order", arg_service_list, 0}, + {"trim", arg_trimdomain_list, 0}, + {"spoof", arg_spoof, 0}, + {"multi", arg_bool, HCONF_FLAG_MULTI}, + {"nospoof", arg_bool, HCONF_FLAG_SPOOF}, + {"spoofalert", arg_bool, HCONF_FLAG_SPOOFALERT}, + {"reorder", arg_bool, HCONF_FLAG_REORDER} }; /* Structure containing the state. */ @@ -106,7 +107,118 @@ skip_string (const char *str) static const char * -arg_trimdomain_list (const char *fname, int line_num, const char *args) +arg_service_list (const char *fname, int line_num, const char *args, + unsigned int arg) +{ + enum Name_Service service; + const char *start; + size_t len; + size_t i; + static struct + { + const char * name; + enum Name_Service service; + } svcs[] = + { + {"bind", SERVICE_BIND}, + {"hosts", SERVICE_HOSTS}, + {"nis", SERVICE_NIS}, + }; + + do + { + start = args; + args = skip_string (args); + len = args - start; + + service = SERVICE_NONE; + for (i = 0; i < sizeof (svcs) / sizeof (svcs[0]); ++i) + { + if (__strncasecmp (start, svcs[i].name, len) == 0 + && len == strlen (svcs[i].name)) + { + service = svcs[i].service; + break; + } + } + if (service == SERVICE_NONE) + { + char *buf; + + if (__asprintf (&buf, + _("%s: line %d: expected service, found `%s'\n"), + fname, line_num, start) < 0) + return 0; + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); + + free (buf); + return 0; + } + if (_res_hconf.num_services >= SERVICE_MAX) + { + char *buf; + + if (__asprintf (&buf, _("\ +%s: line %d: cannot specify more than %d services"), + fname, line_num, SERVICE_MAX) < 0) + return 0; + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); + + free (buf); + return 0; + } + _res_hconf.service[_res_hconf.num_services++] = service; + + args = skip_ws (args); + switch (*args) + { + case ',': + case ';': + case ':': + args = skip_ws (++args); + if (!*args || *args == '#') + { + char *buf; + + if (__asprintf (&buf, _("\ +%s: line %d: list delimiter not followed by keyword"), + fname, line_num) < 0) + return 0; + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); + + free (buf); + return 0; + } + default: + break; + } + } + while (*args && *args != '#'); + return args; +} + + +static const char * +arg_trimdomain_list (const char *fname, int line_num, const char *args, + unsigned int flag) { const char * start; size_t len; @@ -126,9 +238,14 @@ arg_trimdomain_list (const char *fname, int line_num, const char *args) fname, line_num, TRIMDOMAINS_MAX) < 0) return 0; - __fxprintf (NULL, "%s", buf); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); - free (buf); + free (buf); return 0; } _res_hconf.trimdomain[_res_hconf.num_trimdomains++] = @@ -147,7 +264,12 @@ arg_trimdomain_list (const char *fname, int line_num, const char *args) fname, line_num) < 0) return 0; - __fxprintf (NULL, "%s", buf); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); free (buf); return 0; @@ -162,7 +284,7 @@ arg_trimdomain_list (const char *fname, int line_num, const char *args) static const char * -arg_spoof (const char *fname, int line_num, const char *args) +arg_spoof (const char *fname, int line_num, const char *args, unsigned flag) { const char *start = args; size_t len; @@ -205,7 +327,12 @@ arg_bool (const char *fname, int line_num, const char *args, unsigned flag) fname, line_num, args) < 0) return 0; - __fxprintf (NULL, "%s", buf); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); free (buf); return 0; @@ -218,7 +345,7 @@ static void parse_line (const char *fname, int line_num, const char *str) { const char *start; - const struct cmd *c = 0; + struct cmd *c = 0; size_t len; size_t i; @@ -248,7 +375,12 @@ parse_line (const char *fname, int line_num, const char *str) fname, line_num, start) < 0) return; - __fxprintf (NULL, "%s", buf); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); free (buf); return; @@ -256,17 +388,7 @@ parse_line (const char *fname, int line_num, const char *str) /* process args: */ str = skip_ws (str); - - if (c->cb == CB_arg_trimdomain_list) - str = arg_trimdomain_list (fname, line_num, str); - else if (c->cb == CB_arg_spoof) - str = arg_spoof (fname, line_num, str); - else if (c->cb == CB_arg_bool) - str = arg_bool (fname, line_num, str, c->arg); - else - /* Ignore the line. */ - return; - + str = (*c->parse_args) (fname, line_num, str, c->arg); if (!str) return; @@ -283,7 +405,12 @@ parse_line (const char *fname, int line_num, const char *str) fname, line_num, str) < 0) break; - __fxprintf (NULL, "%s", buf); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); free (buf); } @@ -309,7 +436,10 @@ do_init (void) hconf_name = _PATH_HOSTCONF; fp = fopen (hconf_name, "rc"); - if (fp) + if (!fp) + /* make up something reasonable: */ + _res_hconf.service[_res_hconf.num_services++] = SERVICE_BIND; + else { /* No threads using this stream. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); @@ -323,9 +453,16 @@ do_init (void) fclose (fp); } + envval = getenv (ENV_SERVORDER); + if (envval) + { + _res_hconf.num_services = 0; + arg_service_list (ENV_SERVORDER, 1, envval, 0); + } + envval = getenv (ENV_SPOOF); if (envval) - arg_spoof (ENV_SPOOF, 1, envval); + arg_spoof (ENV_SPOOF, 1, envval, 0); envval = getenv (ENV_MULTI); if (envval) @@ -337,13 +474,13 @@ do_init (void) envval = getenv (ENV_TRIM_ADD); if (envval) - arg_trimdomain_list (ENV_TRIM_ADD, 1, envval); + arg_trimdomain_list (ENV_TRIM_ADD, 1, envval, 0); envval = getenv (ENV_TRIM_OVERR); if (envval) { _res_hconf.num_trimdomains = 0; - arg_trimdomain_list (ENV_TRIM_OVERR, 1, envval); + arg_trimdomain_list (ENV_TRIM_OVERR, 1, envval, 0); } _res_hconf.initialized = 1; diff --git a/resolv/res_hconf.h b/resolv/res_hconf.h index b40da0df74..77eeca4dea 100644 --- a/resolv/res_hconf.h +++ b/resolv/res_hconf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995-1998, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by David Mosberger (davidm@azstarnet.com). @@ -24,11 +24,18 @@ #define TRIMDOMAINS_MAX 4 +enum Name_Service +{ + SERVICE_NONE = 0, + SERVICE_BIND, SERVICE_HOSTS, SERVICE_NIS, + SERVICE_MAX +}; + struct hconf { int initialized; - int unused1; - int unused2[4]; + int num_services; + enum Name_Service service[SERVICE_MAX]; int num_trimdomains; const char *trimdomain[TRIMDOMAINS_MAX]; unsigned int flags; diff --git a/resolv/res_init.c b/resolv/res_init.c index b5a03d1883..731c784e17 100644 --- a/resolv/res_init.c +++ b/resolv/res_init.c @@ -537,7 +537,10 @@ net_mask(in) /* XXX - should really use system's version of this */ u_int res_randomid(void) { - return 0xffff & __getpid(); + struct timeval now; + + __gettimeofday(&now, NULL); + return (0xffff & (now.tv_sec ^ now.tv_usec ^ __getpid())); } #ifdef _LIBC libc_hidden_def (__res_randomid) @@ -552,7 +555,7 @@ libc_hidden_def (__res_randomid) * This routine is not expected to be user visible. */ void -__res_iclose(res_state statp, bool free_addr) { +res_nclose(res_state statp) { int ns; if (statp->_vcsock >= 0) { @@ -565,25 +568,13 @@ __res_iclose(res_state statp, bool free_addr) { #else for (ns = 0; ns < statp->_u._ext.nscount; ns++) #endif - if (statp->_u._ext.nsaddrs[ns]) { - if (statp->_u._ext.nssocks[ns] != -1) { - close_not_cancel_no_status(statp->_u._ext.nssocks[ns]); - statp->_u._ext.nssocks[ns] = -1; - } - if (free_addr) { - free (statp->_u._ext.nsaddrs[ns]); - statp->_u._ext.nsaddrs[ns] = NULL; - } + if (statp->_u._ext.nsaddrs[ns] + && statp->_u._ext.nssocks[ns] != -1) { + close_not_cancel_no_status(statp->_u._ext.nssocks[ns]); + statp->_u._ext.nssocks[ns] = -1; } statp->_u._ext.nsinit = 0; } -libc_hidden_def (__res_iclose) - -void -res_nclose(res_state statp) -{ - __res_iclose (statp, true); -} #ifdef _LIBC libc_hidden_def (__res_nclose) #endif @@ -598,7 +589,14 @@ res_thread_freeres (void) /* Never called res_ninit. */ return; - __res_iclose (&_res, true); /* Close any VC sockets. */ + __res_nclose (&_res); /* Close any VC sockets. */ + + for (int ns = 0; ns < MAXNS; ns++) + if (_res._u._ext.nsaddrs[ns] != NULL) + { + free (_res._u._ext.nsaddrs[ns]); + _res._u._ext.nsaddrs[ns] = NULL; + } /* Make sure we do a full re-initialization the next time. */ _res.options = 0; diff --git a/resolv/res_libc.c b/resolv/res_libc.c index 834773c32f..76abca8442 100644 --- a/resolv/res_libc.c +++ b/resolv/res_libc.c @@ -70,8 +70,14 @@ res_init(void) { _res.retry = 4; if (!(_res.options & RES_INIT)) _res.options = RES_DEFAULT; - else if (_res.nscount > 0) - __res_iclose (&_res, true); /* Close any VC sockets. */ + else if (_res.nscount > 0) { + __res_nclose (&_res); /* Close any VC sockets. */ + + for (int ns = 0; ns < MAXNS; ns++) { + free (_res._u._ext.nsaddrs[ns]); + _res._u._ext.nsaddrs[ns] = NULL; + } + } /* * This one used to initialize implicitly to zero, so unless the app @@ -97,7 +103,11 @@ __res_maybe_init (res_state resp, int preinit) if (resp->options & RES_INIT) { if (__res_initstamp != resp->_u._ext.initstamp) { if (resp->nscount > 0) { - __res_iclose (resp, true); + __res_nclose (resp); + for (int ns = 0; ns < MAXNS; ns++) { + free (resp->_u._ext.nsaddrs[ns]); + resp->_u._ext.nsaddrs[ns] = NULL; + } return __res_vinit (resp, 1); } } diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c index fd80569fe2..815fcf8ab3 100644 --- a/resolv/res_mkquery.c +++ b/resolv/res_mkquery.c @@ -124,6 +124,10 @@ res_nmkquery(res_state statp, incremented by one after the initial randomization which still predictable if the application does multiple requests. */ +#if 0 + hp->id = htons(++statp->id); +#else + hp->id = htons(statp->id); int randombits; do { @@ -137,7 +141,7 @@ res_nmkquery(res_state statp, } while ((randombits & 0xffff) == 0); statp->id = (statp->id + randombits) & 0xffff; - hp->id = statp->id; +#endif hp->opcode = op; hp->rd = (statp->options & RES_RECURSE) != 0; hp->rcode = NOERROR; @@ -151,36 +155,38 @@ res_nmkquery(res_state statp, * perform opcode specific processing */ switch (op) { + case QUERY: /*FALLTHROUGH*/ case NS_NOTIFY_OP: - if ((buflen -= QFIXEDSZ + (data == NULL ? 0 : RRFIXEDSZ)) < 0) - return (-1); - goto compose; - - case QUERY: if ((buflen -= QFIXEDSZ) < 0) return (-1); - compose: if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) return (-1); cp += n; buflen -= n; - NS_PUT16 (type, cp); - NS_PUT16 (class, cp); + __putshort(type, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; hp->qdcount = htons(1); if (op == QUERY || data == NULL) break; /* * Make an additional record for completion domain. */ + buflen -= RRFIXEDSZ; n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); - if (__builtin_expect (n < 0, 0)) + if (n < 0) return (-1); cp += n; buflen -= n; - NS_PUT16 (T_NULL, cp); - NS_PUT16 (class, cp); - NS_PUT32 (0, cp); - NS_PUT16 (0, cp); + __putshort(T_NULL, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(0, cp); + cp += INT16SZ; hp->arcount = htons(1); break; @@ -188,13 +194,17 @@ res_nmkquery(res_state statp, /* * Initialize answer section */ - if (__builtin_expect (buflen < 1 + RRFIXEDSZ + datalen, 0)) + if (buflen < 1 + RRFIXEDSZ + datalen) return (-1); *cp++ = '\0'; /* no domain name */ - NS_PUT16 (type, cp); - NS_PUT16 (class, cp); - NS_PUT32 (0, cp); - NS_PUT16 (datalen, cp); + __putshort(type, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(datalen, cp); + cp += INT16SZ; if (datalen) { memcpy(cp, data, datalen); cp += datalen; diff --git a/resolv/res_query.c b/resolv/res_query.c index 85bad97d2d..0feba6687a 100644 --- a/resolv/res_query.c +++ b/resolv/res_query.c @@ -69,7 +69,6 @@ static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ -#include <assert.h> #include <sys/types.h> #include <sys/param.h> #include <netinet/in.h> @@ -152,7 +151,6 @@ __libc_res_nquery(res_state statp, free (buf); return (n); } - assert (answerp == NULL || (void *) *answerp == (void *) answer); n = __libc_res_nsend(statp, buf, n, answer, anslen, answerp); if (use_malloc) free (buf); @@ -165,10 +163,6 @@ __libc_res_nquery(res_state statp, return (n); } - if (answerp != NULL) - /* __libc_res_nsend might have reallocated the buffer. */ - hp = (HEADER *) *answerp; - if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { #ifdef DEBUG if (statp->options & RES_DEBUG) diff --git a/resolv/res_send.c b/resolv/res_send.c index 887d048e19..8fb21a9446 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -267,8 +267,8 @@ res_nameinquery(const char *name, int type, int class, cp += n; if (cp + 2 * INT16SZ > eom) return (-1); - NS_GET16(ttype, cp); - NS_GET16(tclass, cp); + ttype = ns_get16(cp); cp += INT16SZ; + tclass = ns_get16(cp); cp += INT16SZ; if (ttype == type && tclass == class && ns_samename(tname, name) == 1) return (1); @@ -292,6 +292,9 @@ int res_queriesmatch(const u_char *buf1, const u_char *eom1, const u_char *buf2, const u_char *eom2) { + const u_char *cp = buf1 + HFIXEDSZ; + int qdcount = ntohs(((HEADER*)buf1)->qdcount); + if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) return (-1); @@ -303,16 +306,8 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, (((HEADER *)buf2)->opcode == ns_o_update)) return (1); - /* Note that we initially do not convert QDCOUNT to the host byte - order. We can compare it with the second buffer's QDCOUNT - value without doing this. */ - int qdcount = ((HEADER*)buf1)->qdcount; - if (qdcount != ((HEADER*)buf2)->qdcount) + if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) return (0); - - qdcount = htons (qdcount); - const u_char *cp = buf1 + HFIXEDSZ; - while (qdcount-- > 0) { char tname[MAXDNAME+1]; int n, ttype, tclass; @@ -323,8 +318,8 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, cp += n; if (cp + 2 * INT16SZ > eom1) return (-1); - NS_GET16(ttype, cp); - NS_GET16(tclass, cp); + ttype = ns_get16(cp); cp += INT16SZ; + tclass = ns_get16(cp); cp += INT16SZ; if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) return (0); } @@ -386,7 +381,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, } } if (needclose) - __res_iclose(statp, false); + res_nclose(statp); } /* @@ -493,7 +488,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, done = 1; break; case res_nextns: - __res_iclose(statp, false); + res_nclose(statp); goto next_ns; case res_done: return (resplen); @@ -558,7 +553,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, */ if ((v_circuit && (statp->options & RES_USEVC) == 0) || (statp->options & RES_STAYOPEN) == 0) { - __res_iclose(statp, false); + res_nclose(statp); } if (statp->rhook) { int done = 0, loops = 0; @@ -575,7 +570,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, done = 1; break; case res_nextns: - __res_iclose(statp, false); + res_nclose(statp); goto next_ns; case res_modified: /* give the hook another try */ @@ -594,7 +589,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, next_ns: ; } /*foreach ns*/ } /*foreach retry*/ - __res_iclose(statp, false); + res_nclose(statp); if (!v_circuit) { if (!gotsomewhere) __set_errno (ECONNREFUSED); /* no nameservers found */ @@ -637,19 +632,19 @@ send_vc(res_state statp, /* Are we still talking to whom we want to talk to? */ if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { struct sockaddr_in6 peer; - socklen_t size = sizeof peer; + int size = sizeof peer; if (getpeername(statp->_vcsock, (struct sockaddr *)&peer, &size) < 0 || !sock_eq(&peer, nsap)) { - __res_iclose(statp, false); + res_nclose(statp); statp->_flags &= ~RES_F_VC; } } if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { if (statp->_vcsock >= 0) - __res_iclose(statp, false); + res_nclose(statp); statp->_vcsock = socket(nsap->sin6_family, SOCK_STREAM, 0); if (statp->_vcsock < 0) { @@ -659,13 +654,11 @@ send_vc(res_state statp, } __set_errno (0); if (connect(statp->_vcsock, (struct sockaddr *)nsap, - nsap->sin6_family == AF_INET - ? sizeof (struct sockaddr_in) - : sizeof (struct sockaddr_in6)) < 0) { + sizeof *nsap) < 0) { *terrno = errno; Aerror(statp, stderr, "connect/vc", errno, (struct sockaddr *) nsap); - __res_iclose(statp, false); + res_nclose(statp); return (0); } statp->_flags |= RES_F_VC; @@ -674,14 +667,14 @@ send_vc(res_state statp, /* * Send length & message */ - ns_put16((u_short)buflen, (u_char*)&len); + putshort((u_short)buflen, (u_char*)&len); evConsIovec(&len, INT16SZ, &iov[0]); evConsIovec((void*)buf, buflen, &iov[1]); if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, 2)) != (INT16SZ + buflen)) { *terrno = errno; Perror(statp, stderr, "write failed", errno); - __res_iclose(statp, false); + res_nclose(statp); return (0); } /* @@ -699,7 +692,7 @@ send_vc(res_state statp, if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read failed", errno); - __res_iclose(statp, false); + res_nclose(statp); /* * A long running process might get its TCP * connection reset if the remote server was @@ -711,8 +704,10 @@ send_vc(res_state statp, */ if (*terrno == ECONNRESET && !connreset) { connreset = 1; + res_nclose(statp); goto same_ns; } + res_nclose(statp); return (0); } resplen = ns_get16(ans); @@ -721,7 +716,7 @@ send_vc(res_state statp, ans = malloc (MAXPACKET); if (ans == NULL) { *terrno = ENOMEM; - __res_iclose(statp, false); + res_nclose(statp); return (0); } anssiz = MAXPACKET; @@ -746,7 +741,7 @@ send_vc(res_state statp, Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", len)); *terrno = EMSGSIZE; - __res_iclose(statp, false); + res_nclose(statp); return (0); } cp = ans; @@ -757,7 +752,7 @@ send_vc(res_state statp, if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read(vc)", errno); - __res_iclose(statp, false); + res_nclose(statp); return (0); } if (truncating) { @@ -814,8 +809,7 @@ send_dg(res_state statp, int ptimeout; struct sockaddr_in6 from; static int socket_pf = 0; - socklen_t fromlen; - int resplen, seconds, n; + int fromlen, resplen, seconds, n; if (EXT(statp).nssocks[ns] == -1) { /* only try IPv6 if IPv6 NS and if not failed before */ @@ -850,7 +844,7 @@ send_dg(res_state statp, sizeof *nsap) < 0) { Aerror(statp, stderr, "connect(dg)", errno, (struct sockaddr *) nsap); - __res_iclose(statp, false); + res_nclose(statp); return (0); } /* Make socket non-blocking. */ @@ -879,13 +873,10 @@ send_dg(res_state statp, pfd[0].events = POLLOUT; wait: if (need_recompute) { - recompute_resend: evNowTime(&now); if (evCmpTime(finish, now) <= 0) { - poll_err_out: - Perror(statp, stderr, "poll", errno); - err_out: - __res_iclose(statp, false); + Perror(statp, stderr, "select", errno); + res_nclose(statp); return (0); } evSubTime(&timeout, &finish, &now); @@ -907,18 +898,26 @@ send_dg(res_state statp, return (0); } if (n < 0) { - if (errno == EINTR) - goto recompute_resend; - - goto poll_err_out; + if (errno == EINTR) { + recompute_resend: + evNowTime(&now); + if (evCmpTime(finish, now) > 0) { + evSubTime(&timeout, &finish, &now); + goto wait; + } + } + Perror(statp, stderr, "poll", errno); + res_nclose(statp); + return (0); } __set_errno (0); if (pfd[0].revents & POLLOUT) { - if (send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL) != buflen) { + if (send(pfd[0].fd, (char*)buf, buflen, 0) != buflen) { if (errno == EINTR || errno == EAGAIN) goto recompute_resend; Perror(statp, stderr, "send", errno); - goto err_out; + res_nclose(statp); + return (0); } pfd[0].events = POLLIN; ++nwritten; @@ -948,7 +947,8 @@ send_dg(res_state statp, goto wait; } Perror(statp, stderr, "recvfrom", errno); - goto err_out; + res_nclose(statp); + return (0); } *gotsomewhere = 1; if (resplen < HFIXEDSZ) { @@ -959,7 +959,8 @@ send_dg(res_state statp, (stdout, ";; undersized: %d\n", resplen)); *terrno = EMSGSIZE; - goto err_out; + res_nclose(statp); + return (0); } if (hp->id != anhp->id) { /* @@ -1006,19 +1007,11 @@ send_dg(res_state statp, DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query:\n"), ans, (resplen > anssiz) ? anssiz : resplen); - next_ns: - __res_iclose(statp, false); + res_nclose(statp); /* don't retry if called from dig */ if (!statp->pfcode) return (0); } - if (anhp->rcode == NOERROR && anhp->ancount == 0 - && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) { - DprintQ(statp->options & RES_DEBUG, - (stdout, "referred query:\n"), - ans, (resplen > anssiz) ? anssiz : resplen); - goto next_ns; - } if (!(statp->options & RES_IGNTC) && anhp->tc) { /* * To get the rest of answer, @@ -1027,7 +1020,7 @@ send_dg(res_state statp, Dprint(statp->options & RES_DEBUG, (stdout, ";; truncated answer\n")); *v_circuit = 1; - __res_iclose(statp, false); + res_nclose(statp); return (1); } /* @@ -1037,11 +1030,8 @@ send_dg(res_state statp, return (resplen); } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { /* Something went wrong. We can stop trying. */ - goto err_out; - } - else { - /* poll should not have returned > 0 in this case. */ - abort (); + res_nclose(statp); + return (0); } } @@ -1057,13 +1047,8 @@ Aerror(const res_state statp, FILE *file, const char *string, int error, fprintf(file, "res_send: %s ([%s].%u): %s\n", string, - (address->sa_family == AF_INET - ? inet_ntop(address->sa_family, - &((const struct sockaddr_in *) address)->sin_addr, - tmp, sizeof tmp) - : inet_ntop(address->sa_family, - &((const struct sockaddr_in6 *) address)->sin6_addr, - tmp, sizeof tmp)), + inet_ntop(address->sa_family, address->sa_data, + tmp, sizeof tmp), (address->sa_family == AF_INET ? ntohs(((struct sockaddr_in *) address)->sin_port) : address->sa_family == AF_INET6 diff --git a/resolv/tst-inet_ntop.c b/resolv/tst-inet_ntop.c deleted file mode 100644 index a042c74c91..0000000000 --- a/resolv/tst-inet_ntop.c +++ /dev/null @@ -1,111 +0,0 @@ -#include <arpa/inet.h> -#include <errno.h> -#include <netinet/in.h> -#include <stdio.h> -#include <string.h> - -int -main (void) -{ - struct in_addr addr4; - struct in6_addr addr6; - char buf[64]; - int result = 0; - - addr4.s_addr = 0xe0e0e0e0; - addr6.s6_addr16[0] = 0; - addr6.s6_addr16[1] = 0; - addr6.s6_addr16[2] = 0; - addr6.s6_addr16[3] = 0; - addr6.s6_addr16[4] = 0; - addr6.s6_addr16[5] = 0xffff; - addr6.s6_addr32[3] = 0xe0e0e0e0; - memset (buf, 'x', sizeof buf); - - if (inet_ntop (AF_INET, &addr4, buf, 15) != NULL) - { - puts ("1st inet_ntop returned non-NULL"); - result++; - } - else if (errno != ENOSPC) - { - puts ("1st inet_ntop didn't fail with ENOSPC"); - result++; - } - if (buf[15] != 'x') - { - puts ("1st inet_ntop wrote past the end of buffer"); - result++; - } - - if (inet_ntop (AF_INET, &addr4, buf, 16) != buf) - { - puts ("2nd inet_ntop did not return buf"); - result++; - } - if (memcmp (buf, "224.224.224.224\0" "xxxxxxxx", 24) != 0) - { - puts ("2nd inet_ntop wrote past the end of buffer"); - result++; - } - - if (inet_ntop (AF_INET6, &addr6, buf, 22) != NULL) - { - puts ("3rd inet_ntop returned non-NULL"); - result++; - } - else if (errno != ENOSPC) - { - puts ("3rd inet_ntop didn't fail with ENOSPC"); - result++; - } - if (buf[22] != 'x') - { - puts ("3rd inet_ntop wrote past the end of buffer"); - result++; - } - - if (inet_ntop (AF_INET6, &addr6, buf, 23) != buf) - { - puts ("4th inet_ntop did not return buf"); - result++; - } - if (memcmp (buf, "::ffff:224.224.224.224\0" "xxxxxxxx", 31) != 0) - { - puts ("4th inet_ntop wrote past the end of buffer"); - result++; - } - - memset (&addr6.s6_addr, 0xe0, sizeof (addr6.s6_addr)); - - if (inet_ntop (AF_INET6, &addr6, buf, 39) != NULL) - { - puts ("5th inet_ntop returned non-NULL"); - result++; - } - else if (errno != ENOSPC) - { - puts ("5th inet_ntop didn't fail with ENOSPC"); - result++; - } - if (buf[39] != 'x') - { - puts ("5th inet_ntop wrote past the end of buffer"); - result++; - } - - if (inet_ntop (AF_INET6, &addr6, buf, 40) != buf) - { - puts ("6th inet_ntop did not return buf"); - result++; - } - if (memcmp (buf, "e0e0:e0e0:e0e0:e0e0:e0e0:e0e0:e0e0:e0e0\0" - "xxxxxxxx", 48) != 0) - { - puts ("6th inet_ntop wrote past the end of buffer"); - result++; - } - - - return result; -} |