With big DNS answers like the one you get for goodtimesdot.com you can
get a truncated address list if IPv6 mapping is enabled. Instead tell
the caller to resize the buffer.
In EDNS0 records the maximum result size is transmitted in a 16
bit value. Large buffer sizes were handled incorrectly by using
only the low 16 bits. Fix this by limiting the size to 0xffff.
There is some more shardware/software out there which has problems
if two DNS requests are sent using the same tuple
(source addr, source port, dest addr, dest port)
This can range from firewalls to load balancers. Some of the vendors
already fixed it in response to this problem. Still, we need a way
to make glibc work with broken environments. The single-request-reopen
flag can be used or we fall back automatically to this mode.
2009-05-05 Aurelien Jarno <aurelien@aurel32.net>
[BZ #10128]
* resolv/res_query.c (__libc_res_nquery): If one query returns NOTIMP
or FORMERR and the other NOERROR, don't raise an error.
* resolv/res_init.c (res_setoptions): Recognize single-request option.
* resolv/res_send.c (send_dg): If we sent two requests at once and
only get one reply before timeout switch to mode where we send the
second request only after the first answer has been received.
ESRCH return value.
(_nss_dns_gethostbyname4_r): Likewise.
* resolv/res_init.c (__res_vinit): Initialize nscount to zero.
* sysdeps/posix/getaddrinfo.c (gaih_inet): In case we use
gethostbyname4_r, we don't have a separate IPv6 status, so copy
the no_data variable.
* include/resolv.h: Remove hidden proto declarations for __ns_*
functions. Add them for __dn_count_labels and __p_secstodate.
* include/arpa/nameser.h: Add a number of hidden proto declarations.
Define ns_msg_getflags macro here.
* resolv/res_debug.c: Add hidden definition for __dn_count_labels
and __p_secstodate.
* resolv/Versions: Export functions from <arpa/nameser.h> from
libresolv in version GLIBC_2.9.
* resolv/ns_name.c: Integrate changes from bind 9.5.0. Add necessary
hidden definitions.
* resolv/ns_netint.c: Likewise.
* resolv/ns_parse.c: Likewise.
* resolv/ns_print.c: Likewise.
* resolv/ns_samedomain.c: Likewise.
* resolv/ns_ttl.c: Likewise.
* resolv/arpa/nameser_compat.h: Likewise.
* resolv/arpa/nameser.h: Likewise. Remove macros which redirect
function calls.
* resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Use __ns_get16
instead of ns_get16.
* resolv/nss_dns/dns-host.c (getanswer_r): Use __ns_get16 and
__ns_get32 instead of ns_get16 and ns_get32 respectively.
(gaih_getanswer_slice): Likewise.
* resolv/Makefile (libresolv-routines): Add ns_date.
* resolv/ns_date.c: New file.
Use it instead of locally defined resplen2 variable.
(res_nsend): Adjust for __libc_res_nsend interface change.
(send_vc): Initialize *resplen2 if necessary. Read length of
package into an appropriately aligned variable. Store converted length
in new variable and use it appropriately.
Add branch prediction help.
* resolv/res_query.c (__libc_res_nquery): Take additional parameter
and pass it on to __libc_res_nsend. Adjust all callers.
(__libc_res_nsearch): Likewise.
(__libc_res_nqeurydomain): Likewise.
* resolv/nss_dns/dns-host.c: Adjust for __libc_res_nsearch interface
change.
(_nss_dns_gethostbyname4): Don't unconditionally allocate tmp array.
Define resplen2 variable and pass it to __libc_res_nsearch and then
to gaih_getanswer.
(getanswer_r): In case of incorrect DNS data don't overread buffer.
Add branch prediction.
(gaih_getanswer_slice): Likewise. Check for invalid data types.
(gaih_getanswer): Don't decode second slice if first one failed due
to a too small buffer. Don't let not found status of second
decoder shadow results of the first.
* resolv/gethnamaddr.c (gethostbyname2): Adjust for __libc_res_nsearch
and __libc_res_nquery interface changes
(gethostbyaddr): Adjust for __libc_res_nquery interface change.
* include/resolv.h: Adjust prototypes for __libc_res_nquery,
__libc_res_nsearch, and __libc_res_nsend.
* resolv/nss_dns/dns-canon.c: Adjust for __libc_res_nquery interface
change.
* resolv/nss_dns/dns-network.c: Adjust for __libc_res_nquery and
__libc_res_nsearch interface changes.
answer was too short don't try to read that answer's header.
* resolv/res_send.c (send_dg): In case of timeout and there are
two queries and one has been answered, return value indicating
success.