Bug#582916: libc6: getaddrinfo() returns EAI_NONAME for temporary problem.
see the same here under specific circumstances:
to reproduce the following test (see also the comments):
/*BINFMTC:
test for getaddrinfo bug:
getaddrinfo returns EAI_NONAME when it should return EAI_EAGAIN
getaddrinfo returns EAI_NONAME when it should return EAI_EAGAIN for
hosts with A but no AAAA record and there is packet loss and/or a an
overloaded dns server
to easily reproduce, fake packet loss/overloaded dns server
on linux do something like:
# iptables -I OUTPUT -p udp -m udp --dport 53 -j DROP
# iptables -I OUTPUT -p udp -m udp --dport 53 -j LOG --log-prefix "DROP DNS REQUEST "
# iptables -I OUTPUT -p udp -m udp --dport 53 -m limit --limit 10/sec -j ACCEPT
first
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
struct addrinfo hints; // all 0
int main(int argc, char** argv) {
struct addrinfo* res;
int i;
hints.ai_family = AF_INET;
/* should work on mosts setups
(there is another bug involving mdns
if it fails try to replace the hosts line in /etc/nsswitch.conf
with something like:
"hosts: files dns"
)
*/
for(i=0;i<1000;++i) {
/* test host must have a A record but no AAAA record */
int r=getaddrinfo("karme.de",0,&hints,&res);
if(!((r==0)||(r==EAI_AGAIN))) {
printf("%s:%d: error: r=%d %s\n",__FILE__,__LINE__,r,gai_strerror(r));
exit(EXIT_FAILURE);
}
if (!r) freeaddrinfo(res);
}
/* this will fail sometimes
what happens?
DNS request for A record is sent but no answer is received
DNS request for AAAA record is sent and answer without entries received
now getaddrinfo returns EAI_NONAME when in fact it should return EAI_AGAIN
*/
hints.ai_family = AF_UNSPEC;
for(i=0;i<1000;++i) {
int r=getaddrinfo("karme.de",0,&hints,&res);
if(!((r==0)||(r==EAI_AGAIN))) {
printf("%s:%d: error: r=%d %s\n",__FILE__,__LINE__,r,gai_strerror(r));
exit(EXIT_FAILURE);
}
if (!r) freeaddrinfo(res);
}
return EXIT_SUCCESS;
}
Reply to: