diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2012-07-22 19:58:41 +0200 |
---|---|---|
committer | Thomas Schwinge <thomas@codesourcery.com> | 2012-07-22 19:58:41 +0200 |
commit | ef724a37cdb3012efb5b7233eb8b450ad91d3d69 (patch) | |
tree | 2334455220f417223cc1a75aebe76302cdffdf5a /resolv | |
parent | 6f276c2517990f6569b961b4d4919cbce570ac45 (diff) | |
parent | 47e5dcdf349a1aea5c8997104ef785412f0d34fa (diff) |
Merge branch 'baseline' into refs/top-bases/tschwinge/Roger_Whittaker
Conflicts:
configure
configure.in
elf/rtld.c
misc/syslog.c
sysdeps/gnu/configure
sysdeps/gnu/configure.in
sysdeps/mach/hurd/accept4.c
sysdeps/mach/hurd/bits/posix_opt.h
sysdeps/mach/hurd/dup3.c
sysdeps/mach/hurd/i386/init-first.c
sysdeps/mach/hurd/kernel-features.h
sysdeps/mach/hurd/readlinkat.c
Diffstat (limited to 'resolv')
-rw-r--r-- | resolv/nss_dns/dns-host.c | 21 | ||||
-rw-r--r-- | resolv/res_send.c | 102 |
2 files changed, 103 insertions, 20 deletions
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index 10aecb8604..a924d40844 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2004, 2007-2009, 2010 Free Software Foundation, Inc. +/* Copyright (C) 1996-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -744,6 +744,10 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { + /* A CNAME could also have a TTL entry. */ + if (ttlp != NULL && ttl < *ttlp) + *ttlp = ttl; + if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1]) continue; n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); @@ -905,7 +909,10 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, { register int nn; - if (ttlp != NULL) + /* We compose a single hostent out of the entire chain of + entries, so the TTL of the hostent is essentially the lowest + TTL in the chain. */ + if (ttlp != NULL && ttl < *ttlp) *ttlp = ttl; if (canonp != NULL) *canonp = bp; @@ -1081,6 +1088,11 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, if (type == T_CNAME) { char tbuf[MAXDNAME]; + + /* 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_hnok (tbuf) == 0, 0)) { @@ -1161,7 +1173,10 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, if (*firstp) { - if (ttlp != NULL) + /* We compose a single hostent out of the entire chain of + entries, so the TTL of the hostent is essentially the lowest + TTL in the chain. */ + if (ttlp != NULL && ttl < *ttlp) *ttlp = ttl; (*pat)->name = canon ?: h_name; diff --git a/resolv/res_send.c b/resolv/res_send.c index a001c1e753..0a28cd784b 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -1013,8 +1013,9 @@ send_dg(res_state statp, seconds /= statp->nscount; if (seconds <= 0) seconds = 1; - bool single_request = (statp->options & RES_SNGLKUP) != 0; bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0; + bool single_request = (((statp->options & RES_SNGLKUP) != 0) + | single_request_reopen); int save_gotsomewhere = *gotsomewhere; int retval; @@ -1100,24 +1101,91 @@ send_dg(res_state statp, } __set_errno (0); if (pfd[0].revents & POLLOUT) { - ssize_t sr; - if (nwritten != 0) - sr = send (pfd[0].fd, buf2, buflen2, MSG_NOSIGNAL); - else - sr = send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL); +#ifndef __ASSUME_SENDMMSG + static int have_sendmmsg; +#else +# define have_sendmmsg 1 +#endif + if (have_sendmmsg >= 0 && nwritten == 0 && buf2 != NULL + && !single_request) + { + struct iovec iov[2]; + struct mmsghdr reqs[2]; + reqs[0].msg_hdr.msg_name = NULL; + reqs[0].msg_hdr.msg_namelen = 0; + reqs[0].msg_hdr.msg_iov = &iov[0]; + reqs[0].msg_hdr.msg_iovlen = 1; + iov[0].iov_base = (void *) buf; + iov[0].iov_len = buflen; + reqs[0].msg_hdr.msg_control = NULL; + reqs[0].msg_hdr.msg_controllen = 0; + + reqs[1].msg_hdr.msg_name = NULL; + reqs[1].msg_hdr.msg_namelen = 0; + reqs[1].msg_hdr.msg_iov = &iov[1]; + reqs[1].msg_hdr.msg_iovlen = 1; + iov[1].iov_base = (void *) buf2; + iov[1].iov_len = buflen2; + reqs[1].msg_hdr.msg_control = NULL; + reqs[1].msg_hdr.msg_controllen = 0; + + int ndg = sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL); + if (__builtin_expect (ndg == 2, 1)) + { + if (reqs[0].msg_len != buflen + || reqs[1].msg_len != buflen2) + goto fail_sendmmsg; - if (sr != buflen) { - if (errno == EINTR || errno == EAGAIN) - goto recompute_resend; - Perror(statp, stderr, "send", errno); + pfd[0].events = POLLIN; + nwritten += 2; + } + else if (ndg == 1 && reqs[0].msg_len == buflen) + goto just_one; + else if (ndg < 0 && (errno == EINTR || errno == EAGAIN)) + goto recompute_resend; + else + { +#ifndef __ASSUME_SENDMMSG + if (__builtin_expect (have_sendmmsg == 0, 0)) + { + if (ndg < 0 && errno == ENOSYS) + { + have_sendmmsg = -1; + goto try_send; + } + have_sendmmsg = 1; + } +#endif + + fail_sendmmsg: + Perror(statp, stderr, "sendmmsg", errno); goto err_out; - } - if (nwritten != 0 || buf2 == NULL - || single_request || single_request_reopen) - pfd[0].events = POLLIN; + } + } else - pfd[0].events = POLLIN | POLLOUT; - ++nwritten; + { + ssize_t sr; +#ifndef __ASSUME_SENDMMSG + try_send: +#endif + if (nwritten != 0) + sr = send (pfd[0].fd, buf2, buflen2, MSG_NOSIGNAL); + else + sr = send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL); + + if (sr != (nwritten != 0 ? buflen2 : buflen)) { + if (errno == EINTR || errno == EAGAIN) + goto recompute_resend; + Perror(statp, stderr, "send", errno); + goto err_out; + } + just_one: + if (nwritten != 0 || buf2 == NULL || single_request) + pfd[0].events = POLLIN; + else + pfd[0].events = POLLIN | POLLOUT; + ++nwritten; + } goto wait; } else if (pfd[0].revents & POLLIN) { int *thisanssizp; @@ -1327,7 +1395,7 @@ send_dg(res_state statp, recvresp2 = 1; /* Repeat waiting if we have a second answer to arrive. */ if ((recvresp1 & recvresp2) == 0) { - if (single_request || single_request_reopen) { + if (single_request) { pfd[0].events = POLLOUT; if (single_request_reopen) { __res_iclose (statp, false); |