summaryrefslogtreecommitdiff
path: root/resolv
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2016-08-20 20:54:39 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-08-20 20:54:39 +0200
commit29af7775cfef6ed3b466b92e44387574122ed61b (patch)
treec968738daba6d87d69dc4e8b4cb1445a7b6420cb /resolv
parent4893e0ed57daaff901442bacc10ae09cd3e1850f (diff)
parentf76453c31593957fec1a99b986bfa5506618b79c (diff)
Merge branch 'baseline' into refs/top-bases/tschwinge/Roger_Whittaker
Diffstat (limited to 'resolv')
-rw-r--r--resolv/Depend1
-rw-r--r--resolv/Makefile50
-rw-r--r--resolv/Versions4
-rw-r--r--resolv/gai_cancel.c2
-rw-r--r--resolv/gai_error.c2
-rw-r--r--resolv/gai_misc.c2
-rw-r--r--resolv/gai_misc.h4
-rw-r--r--resolv/gai_notify.c2
-rw-r--r--resolv/gai_sigqueue.c2
-rw-r--r--resolv/gai_suspend.c4
-rw-r--r--resolv/getaddrinfo_a.c6
-rw-r--r--resolv/gethnamaddr.c42
-rw-r--r--resolv/inet_addr.c3
-rw-r--r--resolv/inet_pton.c6
-rw-r--r--resolv/netdb.h12
-rw-r--r--resolv/nss_dns/dns-canon.c4
-rw-r--r--resolv/nss_dns/dns-host.c132
-rw-r--r--resolv/nss_dns/dns-network.c12
-rw-r--r--resolv/res-state.c2
-rw-r--r--resolv/res_hconf.c28
-rw-r--r--resolv/res_hconf.h2
-rw-r--r--resolv/res_init.c56
-rw-r--r--resolv/res_mkquery.c4
-rw-r--r--resolv/res_query.c89
-rw-r--r--resolv/res_send.c249
-rw-r--r--resolv/rpc/netdb.h3
-rw-r--r--resolv/tst-inet_ntop.c7
-rw-r--r--resolv/tst-leaks.c2
-rw-r--r--resolv/tst-leaks2.c2
-rw-r--r--resolv/tst-res_hconf_reorder.c112
30 files changed, 487 insertions, 359 deletions
diff --git a/resolv/Depend b/resolv/Depend
index 5c6ec03451..c29ffb5e96 100644
--- a/resolv/Depend
+++ b/resolv/Depend
@@ -1,3 +1,2 @@
-linuxthreads
nptl
libpthread
diff --git a/resolv/Makefile b/resolv/Makefile
index b96b8ed927..1dcb75f7c7 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2015 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
@@ -20,6 +20,8 @@
#
subdir := resolv
+include ../Makeconfig
+
headers := resolv.h \
netdb.h bits/netdb.h \
arpa/nameser.h arpa/nameser_compat.h \
@@ -31,14 +33,13 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
tests = tst-aton tst-leaks tst-inet_ntop
xtests = tst-leaks2
-generate := mtrace-tst-leaks tst-leaks.mtrace tst-leaks2.mtrace
-
-include ../Makeconfig
+generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
extra-libs := libresolv libnss_dns
ifeq ($(have-thread-library),yes)
extra-libs += libanl
routines += gai_sigqueue
+tests += tst-res_hconf_reorder
endif
extra-libs-others = $(extra-libs)
libresolv-routines := gethnamaddr res_comp res_debug \
@@ -64,8 +65,22 @@ ifeq (yesyes,$(build-shared)$(have-thread-library))
tests: $(objpfx)ga_test
endif
-generated := mtrace-tst-leaks tst-leaks.mtrace \
- mtrace-tst-leaks2 tst-leaks2.mtrace
+ifeq ($(run-built-tests),yes)
+ifneq (no,$(PERL))
+tests-special += $(objpfx)mtrace-tst-leaks.out
+xtests-special += $(objpfx)mtrace-tst-leaks2.out
+endif
+endif
+
+ifeq (,$(filter sunrpc,$(subdirs)))
+# The netdb.h we install does '#include <rpc/netdb.h>', so one must exist.
+# If sunrpc/ is built in this configuration, it installs a real <rpc/netdb.h>.
+# If that's not going to happen, install our dummy file.
+headers += rpc/netdb.h
+endif
+
+generated += mtrace-tst-leaks.out tst-leaks.mtrace \
+ mtrace-tst-leaks2.out tst-leaks2.mtrace
include ../Rules
@@ -91,21 +106,16 @@ $(objpfx)libanl.so: $(shared-thread-library)
$(objpfx)ga_test: $(objpfx)libanl.so $(shared-thread-library)
+$(objpfx)tst-res_hconf_reorder: $(libdl) $(shared-thread-library)
+tst-res_hconf_reorder-ENV = RESOLV_REORDER=on
+
$(objpfx)tst-leaks: $(objpfx)libresolv.so
tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
-$(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out
- $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@
-ifeq ($(run-built-tests),yes)
-ifneq (no,$(PERL))
-tests: $(objpfx)mtrace-tst-leaks
-endif
-endif
+$(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@; \
+ $(evaluate-test)
tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace
-$(objpfx)mtrace-tst-leaks2: $(objpfx)tst-leaks2.out
- $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@
-ifeq ($(run-built-tests),yes)
-ifneq (no,$(PERL))
-xtests: $(objpfx)mtrace-tst-leaks2
-endif
-endif
+$(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@; \
+ $(evaluate-test)
diff --git a/resolv/Versions b/resolv/Versions
index 6f02597372..e561bce1a4 100644
--- a/resolv/Versions
+++ b/resolv/Versions
@@ -1,5 +1,3 @@
-%include <tls.h>
-
libc {
GLIBC_2.0 {
_res;
@@ -26,7 +24,7 @@ libc {
GLIBC_PRIVATE {
__gai_sigqueue;
- h_errno; __resp;
+ __h_errno; __resp;
__res_maybe_init; __res_iclose;
}
diff --git a/resolv/gai_cancel.c b/resolv/gai_cancel.c
index caf31455a2..6be2e5b16d 100644
--- a/resolv/gai_cancel.c
+++ b/resolv/gai_cancel.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
diff --git a/resolv/gai_error.c b/resolv/gai_error.c
index e8d1baa1b5..085c82e1b9 100644
--- a/resolv/gai_error.c
+++ b/resolv/gai_error.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
index 9c53876bf9..0244b20c69 100644
--- a/resolv/gai_misc.c
+++ b/resolv/gai_misc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
diff --git a/resolv/gai_misc.h b/resolv/gai_misc.h
index b87b9e3d32..92f968830c 100644
--- a/resolv/gai_misc.h
+++ b/resolv/gai_misc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -31,7 +31,7 @@ struct waitlist
#ifndef DONT_NEED_GAI_MISC_COND
pthread_cond_t *cond;
#endif
- volatile int *counterp;
+ volatile unsigned int *counterp;
/* The next field is used in asynchronous `lio_listio' operations. */
struct sigevent *sigevp;
/* XXX See requestlist, it's used to work around the broken signal
diff --git a/resolv/gai_notify.c b/resolv/gai_notify.c
index 7bee10211b..ab048620da 100644
--- a/resolv/gai_notify.c
+++ b/resolv/gai_notify.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
diff --git a/resolv/gai_sigqueue.c b/resolv/gai_sigqueue.c
index f6e391c729..e2c78785eb 100644
--- a/resolv/gai_sigqueue.c
+++ b/resolv/gai_sigqueue.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2015 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
diff --git a/resolv/gai_suspend.c b/resolv/gai_suspend.c
index b795cdecb8..c3a1288360 100644
--- a/resolv/gai_suspend.c
+++ b/resolv/gai_suspend.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -35,7 +35,7 @@ gai_suspend (const struct gaicb *const list[], int ent,
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
#endif
int cnt;
- int cntr = 1;
+ unsigned int cntr = 1;
int none = 1;
int result;
diff --git a/resolv/getaddrinfo_a.c b/resolv/getaddrinfo_a.c
index 38b48c627e..e6372228c9 100644
--- a/resolv/getaddrinfo_a.c
+++ b/resolv/getaddrinfo_a.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -28,7 +28,7 @@
/* We need this special structure to handle asynchronous I/O. */
struct async_waitlist
{
- int counter;
+ unsigned int counter;
struct sigevent sigev;
struct waitlist list[0];
};
@@ -40,7 +40,7 @@ getaddrinfo_a (int mode, struct gaicb *list[], int ent, struct sigevent *sig)
struct sigevent defsigev;
struct requestlist *requests[ent];
int cnt;
- volatile int total = 0;
+ volatile unsigned int total = 0;
int result = 0;
/* Check arguments. */
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index 1fd8f92680..7fd0e497b1 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -49,6 +49,11 @@
* --Copyright--
*/
+/* XXX This file is not used by any of the resolver functions implemented by
+ glibc (i.e. get*info and gethostby*). It cannot be removed however because
+ it exports symbols in the libresolv ABI. The file is not maintained any
+ more, nor are these functions. */
+
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
@@ -326,23 +331,18 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype)
buflen -= n;
continue;
}
- if ((type == T_SIG) || (type == T_KEY) || (type == T_NXT)) {
- /* We don't support DNSSEC yet. For now, ignore
- * the record and send a low priority message
- * to syslog.
- */
- syslog(LOG_DEBUG|LOG_AUTH,
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class(C_IN), p_type(qtype),
- p_type(type));
- cp += n;
- continue;
- }
if (type != qtype) {
- syslog(LOG_NOTICE|LOG_AUTH,
+ /* Log a low priority message if we get an unexpected
+ * record, but skip it if we are using DNSSEC since it
+ * uses many different types in responses that do not
+ * match QTYPE.
+ */
+ if ((_res.options & RES_USE_DNSSEC) == 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
"gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class(C_IN), p_type(qtype),
- p_type(type));
+ qname, p_class(C_IN), p_type(qtype),
+ p_type(type));
+ }
cp += n;
continue; /* XXX - had_error++ ? */
}
@@ -621,7 +621,7 @@ gethostbyname2(name, af)
buf.buf = origbuf = (querybuf *) alloca (1024);
if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
- &buf.ptr, NULL, NULL, NULL)) < 0) {
+ &buf.ptr, NULL, NULL, NULL, NULL)) < 0) {
if (buf.buf != origbuf)
free (buf.buf);
Dprintf("res_nsearch failed (%d)\n", n);
@@ -667,8 +667,8 @@ gethostbyaddr(addr, len, af)
return (NULL);
}
if (af == AF_INET6 && len == IN6ADDRSZ &&
- (!bcmp(uaddr, mapped, sizeof mapped) ||
- !bcmp(uaddr, tunnelled, sizeof tunnelled))) {
+ (!memcmp(uaddr, mapped, sizeof mapped) ||
+ !memcmp(uaddr, tunnelled, sizeof tunnelled))) {
/* Unmap. */
addr += sizeof mapped;
uaddr += sizeof mapped;
@@ -716,12 +716,12 @@ gethostbyaddr(addr, len, af)
buf.buf = orig_buf = (querybuf *) alloca (1024);
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
- &buf.ptr, NULL, NULL, NULL);
+ &buf.ptr, NULL, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
strcpy(qp, "ip6.int");
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
buf.buf != orig_buf ? MAXPACKET : 1024,
- &buf.ptr, NULL, NULL, NULL);
+ &buf.ptr, NULL, NULL, NULL, NULL);
}
if (n < 0) {
if (buf.buf != orig_buf)
@@ -917,7 +917,7 @@ _gethtbyaddr(addr, len, af)
_sethtent(0);
while ((p = _gethtent()))
- if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
+ if (p->h_addrtype == af && !memcmp(p->h_addr, addr, len))
break;
_endhtent();
return (p);
diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
index 144b87a74c..ee42093754 100644
--- a/resolv/inet_addr.c
+++ b/resolv/inet_addr.c
@@ -90,13 +90,14 @@ static const char rcsid[] = "$BINDId: inet_addr.c,v 8.11 1999/10/13 16:39:25 vix
* The value returned is in network order.
*/
in_addr_t
-inet_addr(const char *cp) {
+__inet_addr(const char *cp) {
struct in_addr val;
if (__inet_aton(cp, &val))
return (val.s_addr);
return (INADDR_NONE);
}
+weak_alias (__inet_addr, inet_addr)
/*
* Check whether "cp" is a valid ascii representation
diff --git a/resolv/inet_pton.c b/resolv/inet_pton.c
index c507013e4e..3d8819512e 100644
--- a/resolv/inet_pton.c
+++ b/resolv/inet_pton.c
@@ -49,7 +49,7 @@ static int inet_pton6 (const char *src, u_char *dst) internal_function;
* Paul Vixie, 1996.
*/
int
-inet_pton(af, src, dst)
+__inet_pton(af, src, dst)
int af;
const char *src;
void *dst;
@@ -65,7 +65,9 @@ inet_pton(af, src, dst)
}
/* NOTREACHED */
}
-libc_hidden_def (inet_pton)
+libc_hidden_def (__inet_pton)
+weak_alias (__inet_pton, inet_pton)
+libc_hidden_weak (inet_pton)
/* int
* inet_pton4(src, dst)
diff --git a/resolv/netdb.h b/resolv/netdb.h
index f9e2bf00cb..44cf6923b2 100644
--- a/resolv/netdb.h
+++ b/resolv/netdb.h
@@ -1,4 +1,4 @@
- /* Copyright (C) 1996-2014 Free Software Foundation, Inc.
+ /* Copyright (C) 1996-2015 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
@@ -70,7 +70,7 @@ extern int *__h_errno_location (void) __THROW __attribute__ ((__const__));
# define NO_DATA 4 /* Valid name, no data record of requested
type. */
#endif
-#if defined __USE_MISC || defined __USE_GNU
+#ifdef __USE_MISC
# define NETDB_INTERNAL -1 /* See errno. */
# define NETDB_SUCCESS 0 /* No problem. */
# define NO_ADDRESS NO_DATA /* No address, look for MX record. */
@@ -104,7 +104,7 @@ struct hostent
int h_addrtype; /* Host address type. */
int h_length; /* Length of address. */
char **h_addr_list; /* List of addresses from name server. */
-#if defined __USE_MISC || defined __USE_GNU
+#ifdef __USE_MISC
# define h_addr h_addr_list[0] /* Address, for backward compatibility.*/
#endif
};
@@ -436,7 +436,7 @@ extern int getnetgrent_r (char **__restrict __hostp,
#endif /* misc */
-#ifdef __USE_BSD
+#ifdef __USE_MISC
/* Call `rshd' at port RPORT on remote machine *AHOST to execute CMD.
The local user is LOCUSER, on the remote machine the command is
executed as REMUSER. In *FD2P the descriptor to the socket for the
@@ -561,8 +561,8 @@ extern int rresvport_af (int *__alport, sa_family_t __af);
#endif
-/* Extension from POSIX.1g. */
-#ifdef __USE_POSIX
+/* Extension from POSIX.1:2001. */
+#ifdef __USE_XOPEN2K
/* Structure to contain information about address of a service provider. */
struct addrinfo
{
diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c
index a9db232c7b..14ddd6cca0 100644
--- a/resolv/nss_dns/dns-canon.c
+++ b/resolv/nss_dns/dns-canon.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -62,7 +62,7 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen,
{
int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
buf, sizeof (buf), &ansp.ptr, NULL, NULL,
- NULL);
+ NULL, NULL);
if (r > 0)
{
/* We need to decode the response. Just one question record.
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index f8f192e5af..357ac04693 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -190,7 +190,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
if (n < 0)
{
switch (errno)
@@ -225,7 +225,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (n < 0)
{
@@ -308,13 +308,20 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
u_char *ans2p = NULL;
int nans2p = 0;
int resplen2 = 0;
+ int ans2p_malloced = 0;
int olderr = errno;
enum nss_status status;
int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
host_buffer.buf->buf, 2048, &host_buffer.ptr,
- &ans2p, &nans2p, &resplen2);
- if (n < 0)
+ &ans2p, &nans2p, &resplen2, &ans2p_malloced);
+ if (n >= 0)
+ {
+ status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
+ resplen2, name, pat, buffer, buflen,
+ errnop, herrnop, ttlp);
+ }
+ else
{
switch (errno)
{
@@ -341,16 +348,11 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
*errnop = EAGAIN;
else
__set_errno (olderr);
-
- if (host_buffer.buf != orig_host_buffer)
- free (host_buffer.buf);
-
- return status;
}
- status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
- resplen2, name, pat, buffer, buflen,
- errnop, herrnop, ttlp);
+ /* Check whether ans2p was separately allocated. */
+ if (ans2p_malloced)
+ free (ans2p);
if (host_buffer.buf != orig_host_buffer)
free (host_buffer.buf);
@@ -398,7 +400,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
buffer += pad;
buflen = buflen > pad ? buflen - pad : 0;
- if (__builtin_expect (buflen < sizeof (struct host_data), 0))
+ if (__glibc_unlikely (buflen < sizeof (struct host_data)))
{
*errnop = ERANGE;
*h_errnop = NETDB_INTERNAL;
@@ -452,7 +454,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
break;
case AF_INET6:
/* Only lookup with the byte string format if the user wants it. */
- if (__builtin_expect (_res.options & RES_USEBSTRING, 0))
+ if (__glibc_unlikely (_res.options & RES_USEBSTRING))
{
qp = stpcpy (qbuf, "\\[x");
for (n = 0; n < IN6ADDRSZ; ++n)
@@ -460,7 +462,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
strcpy (qp, "].ip6.arpa");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
host_buffer.buf->buf, 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (n >= 0)
goto got_it_already;
}
@@ -481,14 +483,14 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
}
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
{
strcpy (qp, "ip6.int");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
}
if (n < 0)
{
@@ -613,7 +615,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
int have_to_map = 0;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
buffer += pad;
- if (__builtin_expect (buflen < sizeof (struct host_data) + pad, 0))
+ buflen = buflen > pad ? buflen - pad : 0;
+ if (__glibc_unlikely (buflen < sizeof (struct host_data)))
{
/* The buffer is too small. */
too_small:
@@ -727,14 +730,14 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
n = -1;
}
- if (__builtin_expect (n < 0 || (*name_ok) (bp) == 0, 0))
+ if (__glibc_unlikely (n < 0 || (*name_ok) (bp) == 0))
{
++had_error;
continue;
}
cp += n; /* name */
- if (__builtin_expect (cp + 10 > end_of_message, 0))
+ if (__glibc_unlikely (cp + 10 > end_of_message))
{
++had_error;
continue;
@@ -748,7 +751,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
cp += INT32SZ; /* TTL */
n = __ns_get16 (cp);
cp += INT16SZ; /* len */
- if (__builtin_expect (class != C_IN, 0))
+ if (__glibc_unlikely (class != C_IN))
{
/* XXX - debug? syslog? */
cp += n;
@@ -764,7 +767,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])
continue;
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
- if (__builtin_expect (n < 0 || (*name_ok) (tbuf) == 0, 0))
+ if (__glibc_unlikely (n < 0 || (*name_ok) (tbuf) == 0))
{
++had_error;
continue;
@@ -782,7 +785,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
linebuflen -= n;
/* Get canonical name. */
n = strlen (tbuf) + 1; /* For the \0. */
- if (__builtin_expect (n > linebuflen, 0))
+ if (__glibc_unlikely (n > linebuflen))
goto too_small;
if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN)
{
@@ -797,8 +800,12 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
if (qtype == T_PTR && type == T_CNAME)
{
+ /* A CNAME could also have a TTL entry. */
+ if (ttlp != NULL && ttl < *ttlp)
+ *ttlp = ttl;
+
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
- if (__builtin_expect (n < 0 || res_dnok (tbuf) == 0, 0))
+ if (__glibc_unlikely (n < 0 || res_dnok (tbuf) == 0))
{
++had_error;
continue;
@@ -806,7 +813,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
cp += n;
/* Get canonical name. */
n = strlen (tbuf) + 1; /* For the \0. */
- if (__builtin_expect (n > linebuflen, 0))
+ if (__glibc_unlikely (n > linebuflen))
goto too_small;
if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN)
{
@@ -818,26 +825,19 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
linebuflen -= n;
continue;
}
- if (__builtin_expect (type == T_SIG, 0)
- || __builtin_expect (type == T_KEY, 0)
- || __builtin_expect (type == T_NXT, 0))
- {
- /* We don't support DNSSEC yet. For now, ignore the record
- and send a low priority message to syslog. */
- syslog (LOG_DEBUG | LOG_AUTH,
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class (C_IN), p_type(qtype), p_type (type));
- cp += n;
- continue;
- }
if (type == T_A && qtype == T_AAAA && map)
have_to_map = 1;
- else if (__builtin_expect (type != qtype, 0))
+ else if (__glibc_unlikely (type != qtype))
{
- syslog (LOG_NOTICE | LOG_AUTH,
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class (C_IN), p_type (qtype), p_type (type));
+ /* Log a low priority message if we get an unexpected record, but
+ skip it if we are using DNSSEC since it uses many different types
+ in responses that do not match QTYPE. */
+ if ((_res.options & RES_USE_DNSSEC) == 0)
+ syslog (LOG_NOTICE | LOG_AUTH,
+ "gethostby*.getanswer: asked for \"%s %s %s\", "
+ "got type \"%s\"",
+ qname, p_class (C_IN), p_type (qtype), p_type (type));
cp += n;
continue; /* XXX - had_error++ ? */
}
@@ -845,7 +845,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
switch (type)
{
case T_PTR:
- if (__builtin_expect (strcasecmp (tname, bp) != 0, 0))
+ if (__glibc_unlikely (strcasecmp (tname, bp) != 0))
{
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);
cp += n;
@@ -862,37 +862,20 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
n = -1;
}
- if (__builtin_expect (n < 0 || res_hnok (bp) == 0, 0))
+ if (__glibc_unlikely (n < 0 || res_hnok (bp) == 0))
{
++had_error;
break;
}
-#if MULTI_PTRS_ARE_ALIASES
- cp += n;
- if (haveanswer == 0)
- result->h_name = bp;
- else if (ap < &host_data->aliases[MAXALIASES-1])
- *ap++ = bp;
- else
- n = -1;
- if (n != -1)
- {
- n = strlen (bp) + 1; /* for the \0 */
- if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN)
- {
- ++had_error;
- break;
- }
- bp += n;
- linebuflen -= n;
- }
- break;
-#else
+ if (ttlp != NULL && ttl < *ttlp)
+ *ttlp = ttl;
+ /* bind would put multiple PTR records as aliases, but we don't do
+ that. */
result->h_name = bp;
if (have_to_map)
{
n = strlen (bp) + 1; /* for the \0 */
- if (__builtin_expect (n >= MAXHOSTNAMELEN, 0))
+ if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
{
++had_error;
break;
@@ -904,7 +887,6 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
}
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
-#endif
case T_A:
case T_AAAA:
if (__builtin_expect (strcasecmp (result->h_name, bp), 0) != 0)
@@ -938,7 +920,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
linebuflen -= sizeof (align) - ((u_long) bp % sizeof (align));
bp += sizeof (align) - ((u_long) bp % sizeof (align));
- if (__builtin_expect (n > linebuflen, 0))
+ if (__glibc_unlikely (n > linebuflen))
goto too_small;
bp = __mempcpy (*hap++ = bp, cp, n);
cp += n;
@@ -1009,7 +991,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
int qdcount = ntohs (hp->qdcount);
const u_char *cp = answer->buf + HFIXEDSZ;
const u_char *end_of_message = answer->buf + anslen;
- if (__builtin_expect (qdcount != 1, 0))
+ if (__glibc_unlikely (qdcount != 1))
{
*h_errnop = NO_RECOVERY;
return NSS_STATUS_UNAVAIL;
@@ -1063,7 +1045,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
n = -1;
}
- if (__builtin_expect (n < 0 || res_hnok (buffer) == 0, 0))
+ if (__glibc_unlikely (n < 0 || res_hnok (buffer) == 0))
{
++had_error;
continue;
@@ -1077,7 +1059,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
cp += n; /* name */
- if (__builtin_expect (cp + 10 > end_of_message, 0))
+ if (__glibc_unlikely (cp + 10 > end_of_message))
{
++had_error;
continue;
@@ -1107,7 +1089,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
*ttlp = ttl;
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
- if (__builtin_expect (n < 0 || res_hnok (tbuf) == 0, 0))
+ if (__glibc_unlikely (n < 0 || res_hnok (tbuf) == 0))
{
++had_error;
continue;
@@ -1124,9 +1106,9 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
}
n = strlen (tbuf) + 1;
- if (__builtin_expect (n > buflen, 0))
+ if (__glibc_unlikely (n > buflen))
goto too_small;
- if (__builtin_expect (n >= MAXHOSTNAMELEN, 0))
+ if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
{
++had_error;
continue;
@@ -1143,7 +1125,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
// We should not see any types other than those explicitly listed
// below. Some types sent by server seem missing, though. Just
// collect the data for now.
- if (__builtin_expect (type != T_A && type != T_AAAA, 0))
+ if (__glibc_unlikely (type != T_A && type != T_AAAA))
#else
if (__builtin_expect (type == T_SIG, 0)
|| __builtin_expect (type == T_KEY, 0)
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
index 8e80a6010e..00f4490c5d 100644
--- a/resolv/nss_dns/dns-network.c
+++ b/resolv/nss_dns/dns-network.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -129,7 +129,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
/* Nothing found. */
@@ -205,7 +205,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result,
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
/* Nothing found. */
@@ -268,7 +268,7 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct net_data);
buffer += pad;
- if (__builtin_expect (buflen < sizeof (*net_data) + pad, 0))
+ if (__glibc_unlikely (buflen < sizeof (*net_data) + pad))
{
/* The buffer is too small. */
too_small:
@@ -398,8 +398,8 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
case BYNAME:
{
- char **ap = result->n_aliases++;
- while (*ap != NULL)
+ char **ap;
+ for (ap = result->n_aliases; *ap != NULL; ++ap)
{
/* Check each alias name for being of the forms:
4.3.2.1.in-addr.arpa = net 1.2.3.4
diff --git a/resolv/res-state.c b/resolv/res-state.c
index 440940312e..d6775532b7 100644
--- a/resolv/res-state.c
+++ b/resolv/res-state.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2015 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
diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c
index b4c86227f8..0d4f3f45bc 100644
--- a/resolv/res_hconf.c
+++ b/resolv/res_hconf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by David Mosberger (davidm@azstarnet.com).
@@ -46,6 +46,10 @@
#include "res_hconf.h"
#include <wchar.h>
+#if IS_IN (libc)
+# define fgets_unlocked __fgets_unlocked
+#endif
+
#define _PATH_HOSTCONF "/etc/host.conf"
/* Environment vars that all user to override default behavior: */
@@ -358,7 +362,7 @@ _res_hconf_init (void)
}
-#ifndef NOT_IN_libc
+#if IS_IN (libc)
# if defined SIOCGIFCONF && defined SIOCGIFNETMASK
/* List of known interfaces. */
libc_freeres_ptr (
@@ -417,7 +421,7 @@ _res_hconf_reorder_addrs (struct hostent *hp)
/* Get lock. */
__libc_lock_lock (lock);
- /* Recheck, somebody else might have done the work by done. */
+ /* Recheck, somebody else might have done the work by now. */
if (num_ifs <= 0)
{
int new_num_ifs = 0;
@@ -435,18 +439,24 @@ _res_hconf_reorder_addrs (struct hostent *hp)
for (cur_ifr = ifr, i = 0; i < num;
cur_ifr = __if_nextreq (cur_ifr), ++i)
{
+ union
+ {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ } ss;
+
if (cur_ifr->ifr_addr.sa_family != AF_INET)
continue;
ifaddrs[new_num_ifs].addrtype = AF_INET;
- ifaddrs[new_num_ifs].u.ipv4.addr =
- ((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr;
+ ss.sa = cur_ifr->ifr_addr;
+ ifaddrs[new_num_ifs].u.ipv4.addr = ss.sin.sin_addr.s_addr;
if (__ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0)
continue;
- ifaddrs[new_num_ifs].u.ipv4.mask =
- ((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr;
+ ss.sa = cur_ifr->ifr_netmask;
+ ifaddrs[new_num_ifs].u.ipv4.mask = ss.sin.sin_addr.s_addr;
/* Now we're committed to this entry. */
++new_num_ifs;
@@ -463,10 +473,10 @@ _res_hconf_reorder_addrs (struct hostent *hp)
errno = save;
num_ifs = new_num_ifs;
-
- __libc_lock_unlock (lock);
}
+ __libc_lock_unlock (lock);
+
__close (sd);
}
diff --git a/resolv/res_hconf.h b/resolv/res_hconf.h
index 1e0c2d9a22..42cef79965 100644
--- a/resolv/res_hconf.h
+++ b/resolv/res_hconf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by David Mosberger (davidm@azstarnet.com).
diff --git a/resolv/res_init.c b/resolv/res_init.c
index 5e1a747a4a..66561ffac2 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -153,10 +153,8 @@ __res_vinit(res_state statp, int preinit) {
char *cp, **pp;
int n;
char buf[BUFSIZ];
- int nserv = 0; /* number of nameserver records read from file */
-#ifdef _LIBC
- int nservall = 0; /* number of NS records read, nserv IPv4 only */
-#endif
+ int nserv = 0; /* number of nameservers read from file */
+ int have_serv6 = 0;
int haveenv = 0;
int havesearch = 0;
#ifdef RESOLVSORT
@@ -184,15 +182,9 @@ __res_vinit(res_state statp, int preinit) {
statp->_flags = 0;
statp->qhook = NULL;
statp->rhook = NULL;
- statp->_u._ext.nsinit = 0;
statp->_u._ext.nscount = 0;
-#ifdef _LIBC
- statp->_u._ext.nscount6 = 0;
- for (n = 0; n < MAXNS; n++) {
- statp->_u._ext.nsaddrs[n] = NULL;
- statp->_u._ext.nsmap[n] = MAXNS;
- }
-#endif
+ for (n = 0; n < MAXNS; n++)
+ statp->_u._ext.nsaddrs[n] = NULL;
/* Allow user to override the local domain definition */
if ((cp = getenv("LOCALDOMAIN")) != NULL) {
@@ -238,7 +230,7 @@ __res_vinit(res_state statp, int preinit) {
/* No threads use this stream. */
__fsetlocking (fp, FSETLOCKING_BYCALLER);
/* read the config file */
- while (fgets_unlocked(buf, sizeof(buf), fp) != NULL) {
+ while (__fgets_unlocked(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
if (*buf == ';' || *buf == '#')
continue;
@@ -296,11 +288,7 @@ __res_vinit(res_state statp, int preinit) {
continue;
}
/* read nameservers to query */
-#ifdef _LIBC
- if (MATCH(buf, "nameserver") && nservall < MAXNS) {
-#else
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
-#endif
struct in_addr a;
cp = buf + sizeof("nameserver") - 1;
@@ -308,13 +296,12 @@ __res_vinit(res_state statp, int preinit) {
cp++;
if ((*cp != '\0') && (*cp != '\n')
&& __inet_aton(cp, &a)) {
- statp->nsaddr_list[nservall].sin_addr = a;
- statp->nsaddr_list[nservall].sin_family = AF_INET;
- statp->nsaddr_list[nservall].sin_port =
+ statp->nsaddr_list[nserv].sin_addr = a;
+ statp->nsaddr_list[nserv].sin_family = AF_INET;
+ statp->nsaddr_list[nserv].sin_port =
htons(NAMESERVER_PORT);
nserv++;
#ifdef _LIBC
- nservall++;
} else {
struct in6_addr a6;
char *el;
@@ -324,7 +311,7 @@ __res_vinit(res_state statp, int preinit) {
if ((el = strchr(cp, SCOPE_DELIMITER)) != NULL)
*el = '\0';
if ((*cp != '\0') &&
- (inet_pton(AF_INET6, cp, &a6) > 0)) {
+ (__inet_pton(AF_INET6, cp, &a6) > 0)) {
struct sockaddr_in6 *sa6;
sa6 = malloc(sizeof(*sa6));
@@ -334,14 +321,14 @@ __res_vinit(res_state statp, int preinit) {
sa6->sin6_flowinfo = 0;
sa6->sin6_addr = a6;
- if (__builtin_expect (el == NULL, 1))
+ if (__glibc_likely (el == NULL))
sa6->sin6_scope_id = 0;
else {
int try_numericscope = 1;
if (IN6_IS_ADDR_LINKLOCAL (&a6)
|| IN6_IS_ADDR_MC_LINKLOCAL (&a6)) {
sa6->sin6_scope_id
- = if_nametoindex (el + 1);
+ = __if_nametoindex (el + 1);
if (sa6->sin6_scope_id != 0)
try_numericscope = 0;
}
@@ -356,10 +343,11 @@ __res_vinit(res_state statp, int preinit) {
}
}
- statp->_u._ext.nsaddrs[nservall] = sa6;
- statp->_u._ext.nssocks[nservall] = -1;
- statp->_u._ext.nsmap[nservall] = MAXNS + 1;
- nservall++;
+ statp->nsaddr_list[nserv].sin_family = 0;
+ statp->_u._ext.nsaddrs[nserv] = sa6;
+ statp->_u._ext.nssocks[nserv] = -1;
+ have_serv6 = 1;
+ nserv++;
}
}
#endif
@@ -414,10 +402,9 @@ __res_vinit(res_state statp, int preinit) {
continue;
}
}
- statp->nscount = nservall;
+ statp->nscount = nserv;
#ifdef _LIBC
- if (nservall - nserv > 0) {
- statp->_u._ext.nscount6 = nservall - nserv;
+ if (have_serv6) {
/* We try IPv6 servers again. */
statp->ipv6_unavail = false;
}
@@ -428,7 +415,7 @@ __res_vinit(res_state statp, int preinit) {
(void) fclose(fp);
}
if (__builtin_expect(statp->nscount == 0, 0)) {
- statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
+ statp->nsaddr.sin_addr = __inet_makeaddr(IN_LOOPBACKNET, 1);
statp->nsaddr.sin_family = AF_INET;
statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
statp->nscount = 1;
@@ -606,11 +593,7 @@ __res_iclose(res_state statp, bool free_addr) {
statp->_vcsock = -1;
statp->_flags &= ~(RES_F_VC | RES_F_CONN);
}
-#ifdef _LIBC
- for (ns = 0; ns < MAXNS; ns++)
-#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]);
@@ -621,7 +604,6 @@ __res_iclose(res_state statp, bool free_addr) {
statp->_u._ext.nsaddrs[ns] = NULL;
}
}
- statp->_u._ext.nsinit = 0;
}
libc_hidden_def (__res_iclose)
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 6170763fa3..1635e6a035 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -180,7 +180,7 @@ res_nmkquery(res_state statp,
n = ns_name_compress((char *)data, cp, buflen,
(const u_char **) dnptrs,
(const u_char **) lastdnptr);
- if (__builtin_expect (n < 0, 0))
+ if (__glibc_unlikely (n < 0))
return (-1);
cp += n;
buflen -= n;
@@ -195,7 +195,7 @@ res_nmkquery(res_state statp,
/*
* Initialize answer section
*/
- if (__builtin_expect (buflen < 1 + RRFIXEDSZ + datalen, 0))
+ if (__glibc_unlikely (buflen < 1 + RRFIXEDSZ + datalen))
return (-1);
*cp++ = '\0'; /* no domain name */
NS_PUT16 (type, cp);
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 1325f9772d..4a9b3b3f27 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -98,7 +98,7 @@ static int
__libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
int class, int type, u_char *answer, int anslen,
u_char **answerp, u_char **answerp2, int *nanswerp2,
- int *resplen2);
+ int *resplen2, int *answerp2_malloced);
/*
* Formulate a normal query, send, and await answer.
@@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp,
u_char **answerp, /* if buffer needs to be enlarged */
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
HEADER *hp = (HEADER *) answer;
HEADER *hp2;
@@ -202,7 +203,7 @@ __libc_res_nquery(res_state statp,
goto again;
}
}
- if (__builtin_expect (n <= 0, 0)) {
+ if (__glibc_unlikely (n <= 0)) {
/* If the query choked with EDNS0, retry without EDNS0. */
if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0
&& ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
@@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp,
}
assert (answerp == NULL || (void *) *answerp == (void *) answer);
n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
- anslen, answerp, answerp2, nanswerp2, resplen2);
+ anslen, answerp, answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
if (use_malloc)
free (buf);
if (n < 0) {
@@ -316,7 +318,7 @@ res_nquery(res_state statp,
int anslen) /* size of answer buffer */
{
return __libc_res_nquery(statp, name, class, type, answer, anslen,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nquery)
@@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp,
u_char **answerp,
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
const char *cp, * const *domain;
HEADER *hp = (HEADER *) answer;
@@ -360,7 +363,7 @@ __libc_res_nsearch(res_state statp,
if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
return (__libc_res_nquery(statp, cp, class, type, answer,
anslen, answerp, answerp2,
- nanswerp2, resplen2));
+ nanswerp2, resplen2, answerp2_malloced));
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -377,8 +380,11 @@ __libc_res_nsearch(res_state statp,
if (dots >= statp->ndots || trailing_dot) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
- answerp2, nanswerp2, resplen2);
- if (ret > 0 || trailing_dot)
+ answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
+ if (ret > 0 || trailing_dot
+ /* If the second response is valid then we use that. */
+ || (ret == 0 && resplen2 != NULL && *resplen2 > 0))
return (ret);
saved_herrno = h_errno;
tried_as_is++;
@@ -386,11 +392,11 @@ __libc_res_nsearch(res_state statp,
answer = *answerp;
anslen = MAXPACKET;
}
- if (answerp2
- && (*answerp2 < answer || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
}
@@ -407,30 +413,41 @@ __libc_res_nsearch(res_state statp,
for (domain = (const char * const *)statp->dnsrch;
*domain && !done;
domain++) {
+ const char *dname = domain[0];
searched = 1;
- if (domain[0][0] == '\0' ||
- (domain[0][0] == '.' && domain[0][1] == '\0'))
+ /* __libc_res_nquerydoman concatenates name
+ with dname with a "." in between. If we
+ pass it in dname the "." we got from the
+ configured default search path, we'll end
+ up with "name..", which won't resolve.
+ OTOH, passing it "" will result in "name.",
+ which has the intended effect for both
+ possible representations of the root
+ domain. */
+ if (dname[0] == '.')
+ dname++;
+ if (dname[0] == '\0')
root_on_list++;
- ret = __libc_res_nquerydomain(statp, name, *domain,
+ ret = __libc_res_nquerydomain(statp, name, dname,
class, type,
answer, anslen, answerp,
answerp2, nanswerp2,
- resplen2);
- if (ret > 0)
+ resplen2, answerp2_malloced);
+ if (ret > 0 || (ret == 0 && resplen2 != NULL
+ && *resplen2 > 0))
return (ret);
if (answerp && *answerp != answer) {
answer = *answerp;
anslen = MAXPACKET;
}
- if (answerp2
- && (*answerp2 < answer
- || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
/*
@@ -479,15 +496,17 @@ __libc_res_nsearch(res_state statp,
}
/*
- * f the query has not already been tried as is then try it
+ * If the query has not already been tried as is then try it
* unless RES_NOTLDQUERY is set and there were no dots.
*/
if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0)
&& !(tried_as_is || root_on_list)) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
- answerp2, nanswerp2, resplen2);
- if (ret > 0)
+ answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
+ if (ret > 0 || (ret == 0 && resplen2 != NULL
+ && *resplen2 > 0))
return (ret);
}
@@ -498,10 +517,11 @@ __libc_res_nsearch(res_state statp,
* else send back meaningless H_ERRNO, that being the one from
* the last DNSRCH we did.
*/
- if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
if (saved_herrno != -1)
RES_SET_H_ERRNO(statp, saved_herrno);
@@ -521,13 +541,12 @@ res_nsearch(res_state statp,
int anslen) /* size of answer */
{
return __libc_res_nsearch(statp, name, class, type, answer,
- anslen, NULL, NULL, NULL, NULL);
+ anslen, NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nsearch)
/*
- * Perform a call on res_query on the concatenation of name and domain,
- * removing a trailing dot from name if domain is NULL.
+ * Perform a call on res_query on the concatenation of name and domain.
*/
static int
__libc_res_nquerydomain(res_state statp,
@@ -539,7 +558,8 @@ __libc_res_nquerydomain(res_state statp,
u_char **answerp,
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
char nbuf[MAXDNAME];
const char *longname = nbuf;
@@ -551,10 +571,6 @@ __libc_res_nquerydomain(res_state statp,
name, domain?domain:"<Nil>", class, type);
#endif
if (domain == NULL) {
- /*
- * Check for trailing '.';
- * copy without '.' if present.
- */
n = strlen(name);
/* Decrement N prior to checking it against MAXDNAME
@@ -565,11 +581,7 @@ __libc_res_nquerydomain(res_state statp,
RES_SET_H_ERRNO(statp, NO_RECOVERY);
return (-1);
}
- if (name[n] == '.') {
- strncpy(nbuf, name, n);
- nbuf[n] = '\0';
- } else
- longname = name;
+ longname = name;
} else {
n = strlen(name);
d = strlen(domain);
@@ -581,7 +593,7 @@ __libc_res_nquerydomain(res_state statp,
}
return (__libc_res_nquery(statp, longname, class, type, answer,
anslen, answerp, answerp2, nanswerp2,
- resplen2));
+ resplen2, answerp2_malloced));
}
int
@@ -593,7 +605,8 @@ res_nquerydomain(res_state statp,
int anslen) /* size of answer */
{
return __libc_res_nquerydomain(statp, name, domain, class, type,
- answer, anslen, NULL, NULL, NULL, NULL);
+ answer, anslen, NULL, NULL, NULL, NULL,
+ NULL);
}
libresolv_hidden_def (res_nquerydomain)
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 7f2e85f324..5e53cc2df6 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -96,6 +96,7 @@ static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixi
#include <string.h>
#include <unistd.h>
#include <kernel-features.h>
+#include <libc-internal.h>
#if PACKETSZ > 65536
#define MAXPACKET PACKETSZ
@@ -183,15 +184,16 @@ evNowTime(struct timespec *res) {
/* Forward. */
+static struct sockaddr *get_nsaddr (res_state, int);
static int send_vc(res_state, const u_char *, int,
const u_char *, int,
u_char **, int *, int *, int, u_char **,
- u_char **, int *, int *);
+ u_char **, int *, int *, int *);
static int send_dg(res_state, const u_char *, int,
const u_char *, int,
u_char **, int *, int *, int,
int *, int *, u_char **,
- u_char **, int *, int *);
+ u_char **, int *, int *, int *);
#ifdef DEBUG
static void Aerror(const res_state, FILE *, const char *, int,
const struct sockaddr *);
@@ -220,20 +222,21 @@ res_ourserver_p(const res_state statp, const struct sockaddr_in6 *inp)
in_port_t port = in4p->sin_port;
in_addr_t addr = in4p->sin_addr.s_addr;
- for (ns = 0; ns < MAXNS; ns++) {
+ for (ns = 0; ns < statp->nscount; ns++) {
const struct sockaddr_in *srv =
- (struct sockaddr_in *)EXT(statp).nsaddrs[ns];
+ (struct sockaddr_in *) get_nsaddr (statp, ns);
- if ((srv != NULL) && (srv->sin_family == AF_INET) &&
+ if ((srv->sin_family == AF_INET) &&
(srv->sin_port == port) &&
(srv->sin_addr.s_addr == INADDR_ANY ||
srv->sin_addr.s_addr == addr))
return (1);
}
} else if (inp->sin6_family == AF_INET6) {
- for (ns = 0; ns < MAXNS; ns++) {
- const struct sockaddr_in6 *srv = EXT(statp).nsaddrs[ns];
- if ((srv != NULL) && (srv->sin6_family == AF_INET6) &&
+ for (ns = 0; ns < statp->nscount; ns++) {
+ const struct sockaddr_in6 *srv
+ = (struct sockaddr_in6 *) get_nsaddr (statp, ns);
+ if ((srv->sin6_family == AF_INET6) &&
(srv->sin6_port == inp->sin6_port) &&
!(memcmp(&srv->sin6_addr, &in6addr_any,
sizeof (struct in6_addr)) &&
@@ -343,7 +346,7 @@ int
__libc_res_nsend(res_state statp, const u_char *buf, int buflen,
const u_char *buf2, int buflen2,
u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
- int *nansp2, int *resplen2)
+ int *nansp2, int *resplen2, int *ansp2_malloced)
{
int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
@@ -358,7 +361,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
}
#ifdef USE_HOOKS
- if (__builtin_expect (statp->qhook || statp->rhook, 0)) {
+ if (__glibc_unlikely (statp->qhook || statp->rhook)) {
if (anssiz < MAXPACKET && ansp) {
u_char *buf = malloc (MAXPACKET);
if (buf == NULL)
@@ -383,74 +386,48 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
* If the ns_addr_list in the resolver context has changed, then
* invalidate our cached copy and the associated timing data.
*/
- if (EXT(statp).nsinit) {
+ if (EXT(statp).nscount != 0) {
int needclose = 0;
if (EXT(statp).nscount != statp->nscount)
needclose++;
else
- for (ns = 0; ns < MAXNS; ns++) {
- unsigned int map = EXT(statp).nsmap[ns];
- if (map < MAXNS
+ for (ns = 0; ns < statp->nscount; ns++) {
+ if (statp->nsaddr_list[ns].sin_family != 0
&& !sock_eq((struct sockaddr_in6 *)
- &statp->nsaddr_list[map],
+ &statp->nsaddr_list[ns],
EXT(statp).nsaddrs[ns]))
{
needclose++;
break;
}
}
- if (needclose)
+ if (needclose) {
__res_iclose(statp, false);
+ EXT(statp).nscount = 0;
+ }
}
/*
* Maybe initialize our private copy of the ns_addr_list.
*/
- if (EXT(statp).nsinit == 0) {
- unsigned char map[MAXNS];
-
- memset (map, MAXNS, sizeof (map));
- for (n = 0; n < MAXNS; n++) {
- ns = EXT(statp).nsmap[n];
- if (ns < statp->nscount)
- map[ns] = n;
- else if (ns < MAXNS) {
- free(EXT(statp).nsaddrs[n]);
- EXT(statp).nsaddrs[n] = NULL;
- EXT(statp).nsmap[n] = MAXNS;
- }
- }
- n = statp->nscount;
- if (statp->nscount > EXT(statp).nscount)
- for (n = EXT(statp).nscount, ns = 0;
- n < statp->nscount; n++) {
- while (ns < MAXNS
- && EXT(statp).nsmap[ns] != MAXNS)
- ns++;
- if (ns == MAXNS)
- break;
- EXT(statp).nsmap[ns] = n;
- map[n] = ns++;
- }
- EXT(statp).nscount = n;
- for (ns = 0; ns < EXT(statp).nscount; ns++) {
- n = map[ns];
- if (EXT(statp).nsaddrs[n] == NULL)
- EXT(statp).nsaddrs[n] =
+ if (EXT(statp).nscount == 0) {
+ for (ns = 0; ns < statp->nscount; ns++) {
+ EXT(statp).nssocks[ns] = -1;
+ if (statp->nsaddr_list[ns].sin_family == 0)
+ continue;
+ if (EXT(statp).nsaddrs[ns] == NULL)
+ EXT(statp).nsaddrs[ns] =
malloc(sizeof (struct sockaddr_in6));
- if (EXT(statp).nsaddrs[n] != NULL) {
- memset (mempcpy(EXT(statp).nsaddrs[n],
+ if (EXT(statp).nsaddrs[ns] != NULL)
+ memset (mempcpy(EXT(statp).nsaddrs[ns],
&statp->nsaddr_list[ns],
sizeof (struct sockaddr_in)),
'\0',
sizeof (struct sockaddr_in6)
- sizeof (struct sockaddr_in));
- EXT(statp).nssocks[n] = -1;
- n++;
- }
}
- EXT(statp).nsinit = 1;
+ EXT(statp).nscount = statp->nscount;
}
/*
@@ -459,47 +436,40 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
*/
if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0) &&
(statp->options & RES_BLAST) == 0) {
- struct sockaddr_in6 *ina;
- unsigned int map;
-
- n = 0;
- while (n < MAXNS && EXT(statp).nsmap[n] == MAXNS)
- n++;
- if (n < MAXNS) {
- ina = EXT(statp).nsaddrs[n];
- map = EXT(statp).nsmap[n];
- for (;;) {
- ns = n + 1;
- while (ns < MAXNS
- && EXT(statp).nsmap[ns] == MAXNS)
- ns++;
- if (ns == MAXNS)
- break;
- EXT(statp).nsaddrs[n] = EXT(statp).nsaddrs[ns];
- EXT(statp).nsmap[n] = EXT(statp).nsmap[ns];
- n = ns;
- }
- EXT(statp).nsaddrs[n] = ina;
- EXT(statp).nsmap[n] = map;
+ struct sockaddr_in ina;
+ struct sockaddr_in6 *inp;
+ int lastns = statp->nscount - 1;
+ int fd;
+
+ inp = EXT(statp).nsaddrs[0];
+ ina = statp->nsaddr_list[0];
+ fd = EXT(statp).nssocks[0];
+ for (ns = 0; ns < lastns; ns++) {
+ EXT(statp).nsaddrs[ns] = EXT(statp).nsaddrs[ns + 1];
+ statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
+ EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
}
+ EXT(statp).nsaddrs[lastns] = inp;
+ statp->nsaddr_list[lastns] = ina;
+ EXT(statp).nssocks[lastns] = fd;
}
/*
* Send request, RETRY times, or until successful.
*/
for (try = 0; try < statp->retry; try++) {
- for (ns = 0; ns < MAXNS; ns++)
+ for (ns = 0; ns < statp->nscount; ns++)
{
#ifdef DEBUG
char tmpbuf[40];
#endif
- struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
+#if defined USE_HOOKS || defined DEBUG
+ struct sockaddr *nsap = get_nsaddr (statp, ns);
+#endif
- if (nsap == NULL)
- goto next_ns;
same_ns:
#ifdef USE_HOOKS
- if (__builtin_expect (statp->qhook != NULL, 0)) {
+ if (__glibc_unlikely (statp->qhook != NULL)) {
int done = 0, loops = 0;
do {
@@ -535,18 +505,19 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
Dprint(statp->options & RES_DEBUG,
(stdout, ";; Querying server (# %d) address = %s\n",
- ns + 1, inet_ntop(nsap->sin6_family,
- (nsap->sin6_family == AF_INET6
- ? &nsap->sin6_addr
+ ns + 1, inet_ntop(nsap->sa_family,
+ (nsap->sa_family == AF_INET6
+ ? &((struct sockaddr_in6 *) nsap)->sin6_addr
: &((struct sockaddr_in *) nsap)->sin_addr),
tmpbuf, sizeof (tmpbuf))));
- if (__builtin_expect (v_circuit, 0)) {
+ if (__glibc_unlikely (v_circuit)) {
/* Use VC; at most one attempt per server. */
try = statp->retry;
n = send_vc(statp, buf, buflen, buf2, buflen2,
&ans, &anssiz, &terrno,
- ns, ansp, ansp2, nansp2, resplen2);
+ ns, ansp, ansp2, nansp2, resplen2,
+ ansp2_malloced);
if (n < 0)
return (-1);
if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -556,7 +527,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
n = send_dg(statp, buf, buflen, buf2, buflen2,
&ans, &anssiz, &terrno,
ns, &v_circuit, &gotsomewhere, ansp,
- ansp2, nansp2, resplen2);
+ ansp2, nansp2, resplen2, ansp2_malloced);
if (n < 0)
return (-1);
if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -595,7 +566,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
__res_iclose(statp, false);
}
#ifdef USE_HOOKS
- if (__builtin_expect (statp->rhook, 0)) {
+ if (__glibc_unlikely (statp->rhook)) {
int done = 0, loops = 0;
do {
@@ -646,18 +617,33 @@ res_nsend(res_state statp,
const u_char *buf, int buflen, u_char *ans, int anssiz)
{
return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nsend)
/* Private */
+static struct sockaddr *
+get_nsaddr (res_state statp, int n)
+{
+
+ if (statp->nsaddr_list[n].sin_family == 0 && EXT(statp).nsaddrs[n] != NULL)
+ /* EXT(statp).nsaddrs[n] holds an address that is larger than
+ struct sockaddr, and user code did not update
+ statp->nsaddr_list[n]. */
+ return (struct sockaddr *) EXT(statp).nsaddrs[n];
+ else
+ /* User code updated statp->nsaddr_list[n], or statp->nsaddr_list[n]
+ has the same content as EXT(statp).nsaddrs[n]. */
+ return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
+}
+
static int
send_vc(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
u_char **ansp, int *anssizp,
int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
- int *resplen2)
+ int *resplen2, int *ansp2_malloced)
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
@@ -666,8 +652,25 @@ send_vc(res_state statp,
// XXX REMOVE
// int anssiz = *anssizp;
HEADER *anhp = (HEADER *) ans;
- struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
- int truncating, connreset, resplen, n;
+ struct sockaddr *nsap = get_nsaddr (statp, ns);
+ int truncating, connreset, n;
+ /* On some architectures compiler might emit a warning indicating
+ 'resplen' may be used uninitialized. However if buf2 == NULL
+ then this code won't be executed; if buf2 != NULL, then first
+ time round the loop recvresp1 and recvresp2 will be 0 so this
+ code won't be executed but "thisresplenp = &resplen;" followed
+ by "*thisresplenp = rlen;" will be executed so that subsequent
+ times round the loop resplen has been initialized. So this is
+ a false-positive.
+ */
+#if __GNUC_PREREQ (4, 7)
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+#endif
+ int resplen;
+#if __GNUC_PREREQ (4, 7)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
struct iovec iov[4];
u_short len;
u_short len2;
@@ -686,8 +689,8 @@ send_vc(res_state statp,
if (getpeername(statp->_vcsock,
(struct sockaddr *)&peer, &size) < 0 ||
- !sock_eq(&peer, nsap)) {
- __res_iclose(statp, false);
+ !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) {
+ __res_iclose(statp, false);
statp->_flags &= ~RES_F_VC;
}
}
@@ -696,20 +699,19 @@ send_vc(res_state statp,
if (statp->_vcsock >= 0)
__res_iclose(statp, false);
- statp->_vcsock = socket(nsap->sin6_family, SOCK_STREAM, 0);
+ statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
if (statp->_vcsock < 0) {
*terrno = errno;
Perror(statp, stderr, "socket(vc)", errno);
return (-1);
}
__set_errno (0);
- if (connect(statp->_vcsock, (struct sockaddr *)nsap,
- nsap->sin6_family == AF_INET
+ if (connect(statp->_vcsock, nsap,
+ nsap->sa_family == AF_INET
? sizeof (struct sockaddr_in)
: sizeof (struct sockaddr_in6)) < 0) {
*terrno = errno;
- Aerror(statp, stderr, "connect/vc", errno,
- (struct sockaddr *) nsap);
+ Aerror(statp, stderr, "connect/vc", errno, nsap);
__res_iclose(statp, false);
return (0);
}
@@ -786,7 +788,11 @@ send_vc(res_state statp,
/* No buffer allocated for the first
reply. We can try to use the rest
of the user-provided buffer. */
-#ifdef _STRING_ARCH_unaligned
+#if __GNUC_PREREQ (4, 7)
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+#endif
+#if _STRING_ARCH_unaligned
*anssizp2 = orig_anssizp - resplen;
*ansp2 = *ansp + resplen;
#else
@@ -796,6 +802,9 @@ send_vc(res_state statp,
*anssizp2 = orig_anssizp - aligned_resplen;
*ansp2 = *ansp + aligned_resplen;
#endif
+#if __GNUC_PREREQ (4, 7)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
} else {
/* The first reply did not fit into the
user-provided buffer. Maybe the second
@@ -814,7 +823,7 @@ send_vc(res_state statp,
if (rlen > *thisanssizp) {
/* Yes, we test ANSCP here. If we have two buffers
both will be allocatable. */
- if (__builtin_expect (anscp != NULL, 1)) {
+ if (__glibc_likely (anscp != NULL)) {
u_char *newp = malloc (MAXPACKET);
if (newp == NULL) {
*terrno = ENOMEM;
@@ -823,6 +832,8 @@ send_vc(res_state statp,
}
*thisanssizp = MAXPACKET;
*thisansp = newp;
+ if (thisansp == ansp2)
+ *ansp2_malloced = 1;
anhp = (HEADER *) newp;
len = rlen;
} else {
@@ -835,7 +846,7 @@ send_vc(res_state statp,
} else
len = rlen;
- if (__builtin_expect (len < HFIXEDSZ, 0)) {
+ if (__glibc_unlikely (len < HFIXEDSZ)) {
/*
* Undersized message.
*/
@@ -851,13 +862,13 @@ send_vc(res_state statp,
cp += n;
len -= n;
}
- if (__builtin_expect (n <= 0, 0)) {
+ if (__glibc_unlikely (n <= 0)) {
*terrno = errno;
Perror(statp, stderr, "read(vc)", errno);
__res_iclose(statp, false);
return (0);
}
- if (__builtin_expect (truncating, 0)) {
+ if (__glibc_unlikely (truncating)) {
/*
* Flush rest of answer so connection stays in synch.
*/
@@ -911,13 +922,12 @@ static int
reopen (res_state statp, int *terrno, int ns)
{
if (EXT(statp).nssocks[ns] == -1) {
- struct sockaddr *nsap
- = (struct sockaddr *) EXT(statp).nsaddrs[ns];
+ struct sockaddr *nsap = get_nsaddr (statp, ns);
socklen_t slen;
/* only try IPv6 if IPv6 NS and if not failed before */
if (nsap->sa_family == AF_INET6 && !statp->ipv6_unavail) {
- if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
+ if (__glibc_likely (__have_o_nonblock >= 0)) {
EXT(statp).nssocks[ns] =
socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK,
0);
@@ -928,14 +938,14 @@ reopen (res_state statp, int *terrno, int ns)
&& errno == EINVAL ? -1 : 1);
#endif
}
- if (__builtin_expect (__have_o_nonblock < 0, 0))
+ if (__glibc_unlikely (__have_o_nonblock < 0))
EXT(statp).nssocks[ns] =
socket(PF_INET6, SOCK_DGRAM, 0);
if (EXT(statp).nssocks[ns] < 0)
statp->ipv6_unavail = errno == EAFNOSUPPORT;
slen = sizeof (struct sockaddr_in6);
} else if (nsap->sa_family == AF_INET) {
- if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
+ if (__glibc_likely (__have_o_nonblock >= 0)) {
EXT(statp).nssocks[ns]
= socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK,
0);
@@ -946,7 +956,7 @@ reopen (res_state statp, int *terrno, int ns)
&& errno == EINVAL ? -1 : 1);
#endif
}
- if (__builtin_expect (__have_o_nonblock < 0, 0))
+ if (__glibc_unlikely (__have_o_nonblock < 0))
EXT(statp).nssocks[ns]
= socket(PF_INET, SOCK_DGRAM, 0);
slen = sizeof (struct sockaddr_in);
@@ -973,7 +983,7 @@ reopen (res_state statp, int *terrno, int ns)
__res_iclose(statp, false);
return (0);
}
- if (__builtin_expect (__have_o_nonblock < 0, 0)) {
+ if (__glibc_unlikely (__have_o_nonblock < 0)) {
/* Make socket non-blocking. */
int fl = __fcntl (EXT(statp).nssocks[ns], F_GETFL);
if (fl != -1)
@@ -992,7 +1002,7 @@ send_dg(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
u_char **ansp, int *anssizp,
int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
- u_char **ansp2, int *anssizp2, int *resplen2)
+ u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
@@ -1055,7 +1065,7 @@ send_dg(res_state statp,
n = 0;
if (nwritten == 0)
n = __poll (pfd, 1, 0);
- if (__builtin_expect (n == 0, 0)) {
+ if (__glibc_unlikely (n == 0)) {
n = __poll (pfd, 1, ptimeout);
need_recompute = 1;
}
@@ -1130,7 +1140,7 @@ send_dg(res_state statp,
reqs[1].msg_hdr.msg_controllen = 0;
int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL);
- if (__builtin_expect (ndg == 2, 1))
+ if (__glibc_likely (ndg == 2))
{
if (reqs[0].msg_len != buflen
|| reqs[1].msg_len != buflen2)
@@ -1146,7 +1156,7 @@ send_dg(res_state statp,
else
{
#ifndef __ASSUME_SENDMMSG
- if (__builtin_expect (have_sendmmsg == 0, 0))
+ if (__glibc_unlikely (have_sendmmsg == 0))
{
if (ndg < 0 && errno == ENOSYS)
{
@@ -1202,7 +1212,7 @@ send_dg(res_state statp,
/* No buffer allocated for the first
reply. We can try to use the rest
of the user-provided buffer. */
-#ifdef _STRING_ARCH_unaligned
+#if _STRING_ARCH_unaligned
*anssizp2 = orig_anssizp - resplen;
*ansp2 = *ansp + resplen;
#else
@@ -1238,6 +1248,8 @@ send_dg(res_state statp,
if (newp != NULL) {
*anssizp = MAXPACKET;
*thisansp = ans = newp;
+ if (thisansp == ansp2)
+ *ansp2_malloced = 1;
}
}
HEADER *anhp = (HEADER *) *thisansp;
@@ -1246,7 +1258,7 @@ send_dg(res_state statp,
*thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp,
*thisanssizp, 0,
(struct sockaddr *)&from, &fromlen);
- if (__builtin_expect (*thisresplenp <= 0, 0)) {
+ if (__glibc_unlikely (*thisresplenp <= 0)) {
if (errno == EINTR || errno == EAGAIN) {
need_recompute = 1;
goto wait;
@@ -1255,7 +1267,7 @@ send_dg(res_state statp,
goto err_out;
}
*gotsomewhere = 1;
- if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) {
+ if (__glibc_unlikely (*thisresplenp < HFIXEDSZ)) {
/*
* Undersized message.
*/
@@ -1346,6 +1358,7 @@ send_dg(res_state statp,
(*thisresplenp > *thisanssizp)
? *thisanssizp : *thisresplenp);
+ next_ns:
if (recvresp1 || (buf2 != NULL && recvresp2)) {
*resplen2 = 0;
return resplen;
@@ -1363,7 +1376,6 @@ send_dg(res_state statp,
goto wait;
}
- next_ns:
__res_iclose(statp, false);
/* don't retry if called from dig */
if (!statp->pfcode)
@@ -1405,6 +1417,7 @@ send_dg(res_state statp,
retval = reopen (statp, terrno, ns);
if (retval <= 0)
return retval;
+ pfd[0].fd = EXT(statp).nssocks[ns];
}
}
goto wait;
diff --git a/resolv/rpc/netdb.h b/resolv/rpc/netdb.h
new file mode 100644
index 0000000000..eecea3cb06
--- /dev/null
+++ b/resolv/rpc/netdb.h
@@ -0,0 +1,3 @@
+/* This is a dummy file for <rpc/netdb.h>, which is included by <netdb.h>.
+ This file is installed when the C library does not support the SunRPC
+ interfaces (including 'struct rpcent' et al) at all. */
diff --git a/resolv/tst-inet_ntop.c b/resolv/tst-inet_ntop.c
index f968ec4dcb..f0de06306c 100644
--- a/resolv/tst-inet_ntop.c
+++ b/resolv/tst-inet_ntop.c
@@ -4,8 +4,8 @@
#include <stdio.h>
#include <string.h>
-int
-main (void)
+static int
+do_test (void)
{
struct in_addr addr4;
struct in6_addr addr6;
@@ -109,3 +109,6 @@ main (void)
return result;
}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/resolv/tst-leaks.c b/resolv/tst-leaks.c
index e1f42f1264..290d936cd4 100644
--- a/resolv/tst-leaks.c
+++ b/resolv/tst-leaks.c
@@ -1,5 +1,5 @@
/* Tests for res_query in libresolv
- Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Copyright (C) 2003-2015 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
diff --git a/resolv/tst-leaks2.c b/resolv/tst-leaks2.c
index b964ae7435..dfb7ca26b0 100644
--- a/resolv/tst-leaks2.c
+++ b/resolv/tst-leaks2.c
@@ -1,5 +1,5 @@
/* Tests for res_init in libresolv
- Copyright (C) 2004-2014 Free Software Foundation, Inc.
+ Copyright (C) 2004-2015 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
diff --git a/resolv/tst-res_hconf_reorder.c b/resolv/tst-res_hconf_reorder.c
new file mode 100644
index 0000000000..1e7e0e2fa5
--- /dev/null
+++ b/resolv/tst-res_hconf_reorder.c
@@ -0,0 +1,112 @@
+/* BZ #17977 _res_hconf_reorder_addrs test.
+
+ Copyright (C) 2015 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+static struct timespec ts;
+
+/* The first thread that gets a lock in _res_hconf_reorder_addrs()
+ should hold the lock long enough to make two other threads blocked.
+ This is achieved by slowing down realloc(3) that is called several times
+ by _res_hconf_reorder_addrs(). */
+
+void *
+realloc (void *ptr, size_t len)
+{
+ static void *(*fun) (void *, size_t);
+
+ if (!fun)
+ fun = dlsym (RTLD_NEXT, "realloc");
+
+ if (ts.tv_nsec)
+ nanosleep (&ts, NULL);
+
+ return (*fun) (ptr, len);
+}
+
+static void *
+resolve (void *arg)
+{
+ struct in_addr addr;
+ struct hostent ent;
+ struct hostent *result;
+ int err;
+ char buf[1024];
+
+ addr.s_addr = htonl (INADDR_LOOPBACK);
+ (void) gethostbyaddr_r ((void *) &addr, sizeof (addr), AF_INET,
+ &ent, buf, sizeof (buf), &result, &err);
+ return arg;
+}
+
+static int
+do_test (void)
+{
+ #define N 3
+ pthread_t thr[N];
+ unsigned int i;
+ int result = 0;
+
+ /* turn on realloc slowdown */
+ ts.tv_nsec = 100000000;
+
+ for (i = 0; i < N; ++i)
+ {
+ int rc = pthread_create (&thr[i], NULL, resolve, NULL);
+
+ if (rc)
+ {
+ printf ("pthread_create: %s\n", strerror(rc));
+ exit (1);
+ }
+ }
+
+ for (i = 0; i < N; ++i)
+ {
+ void *retval;
+ int rc = pthread_join (thr[i], &retval);
+
+ if (rc)
+ {
+ printf ("pthread_join: %s\n", strerror(rc));
+ exit (1);
+ }
+ if (retval)
+ {
+ printf ("thread %u exit status %p\n", i, retval);
+ result = 1;
+ }
+ }
+
+ /* turn off realloc slowdown, no longer needed */
+ ts.tv_nsec = 0;
+
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"