On Friday and Saturday I sent messages to this list but they appear to have been filtered out. I try again and CC: Helmut Grohne this time so at least he will receive this message and we can continue the discussion over e-mail.
My Friday message contained a C program and its output when run on my own machine. The purpose was to illustrate a program re-reading resolv.conf when it changes. Since then Helmut has posted a long message[0] which among other things makes the same point, so there's no need for me to belabor it here. However, there is one remaining question where we still have different findings and I think we should get to the bottom of this difference since it is relevant for how we think about ntpd bug report #683061. Helmut Grohne wrote: > On Sun, Jun 30, 2013 at 10:40:03PM +0200, Thomas Hood wrote: > > A problem is that getaddrinfo() doesn't distinguish in its return > > > > > > status between "couldn't reach a nameserver" and "nameserver > > > > > > says the name doesn't exist". Either way it returns EAI_SYSTEM > > > > > > with errno=2 (ENOENT). > > > > > > I cannot confirm this observation and assume it to be wrong. Helmut Grohne wrote: > So what happens when you getaddrinfo ... > > ... a non-existent name? -> EAI_SYSTEM ENOENT > ... something when nothing is bound to port 53? > -> EAI_SYSTEM ECONNREFUSED > ... something when port 53 is bound, but does not answer? > -> EAI_SYSTEM ETIMEDOUT I don't get these results. I attach a program "x.c" and append the output below, run on Ubuntu 13.04. It shows that when resolv.conf is an empty file and getaddrinfo() is called (... I have no local nameserver running, so this causes failure to find a nameserver...) the return value and errno are -11 and 2: EAI_SYSTEM and ENOENT. The return values are the same when getaddrinfo() is called with a nonexistent domain name. It was on the basis of a quick test like this that I wrote what Helmut quoted. But that was on an Ubuntu 13.04 system. I next ran the program on Debian 7.0 and got the same results except that the return value was -2 (EAI_NONAME) instead of -11, both in the case of the bogus domain name and in the case of the unreachable nameserver. Ubuntu and Debian thus differ on the return value, but neither of them distinguishes between name-doesn't-exist and nameserver-not-found. Comparing my program with Helmut's the only significant difference I saw was that he gave getaddrinfo() NULL as the "hints" argument. I changed my program to give NULL hints but the results were the same. I wonder why Helmut and I are getting different results. === x.c run on Ubuntu 13.04 === $ sudo ./a.out Making resolv.conf empty Results of looking up www.google.com: status = -11, errno = 2 Results of looking up a bogus name: status = -11, errno = 2 Writing nameserver option to resolv.conf Results of looking up www.google.com: status = 0, errno = 101 Results of looking up a bogus name: status = -11, errno = 2 Making resolv.conf empty Results of looking up www.google.com: status = -11, errno = 2 Results of looking up a bogus name: status = -11, errno = 2 Writing nameserver option to resolv.conf Results of looking up www.google.com: status = 0, errno = 101 Results of looking up a bogus name: status = -11, errno = 2 === x.c run on Debian 7.0 === $ su # ./a.out Making resolv.conf empty Results of looking up www.google.com: status = -2, errno = 2 Results of looking up a bogus name: status = -2, errno = 2 Writing nameserver option to resolv.conf Results of looking up www.google.com: status = 0, errno = 101 Results of looking up a bogus name: status = -2, errno = 2 Making resolv.conf empty Results of looking up www.google.com: status = -2, errno = 2 Results of looking up a bogus name: status = -2, errno = 2 Writing nameserver option to resolv.conf Results of looking up www.google.com: status = 0, errno = 101 Results of looking up a bogus name: status = -2, errno = 2 [0] http://lists.debian.org/debian-devel/2013/07/msg00201.html -- Thomas Hood
#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <errno.h> #include <stdio.h> struct addrinfo hints; struct addrinfo *res; void check_google() { int status; status = getaddrinfo("www.google.com", 0, NULL, &res); printf("Results of looking up www.google.com: status = %d, errno = %d\n", status, errno); status = getaddrinfo("sjfkdsjfswfloo0f02938sjf28398sd.com", 0, NULL, &res); printf("Results of looking up a bogus name: status = %d, errno = %d\n", status, errno); } int main() { hints.ai_family = 0; hints.ai_socktype = 0; hints.ai_protocol = SOCK_STREAM; hints.ai_flags = AI_CANONNAME; FILE *fp; printf("Making resolv.conf empty\n"); fp = fopen("/etc/resolv.conf", "w+"); fclose(fp); sleep(1); check_google(); printf("Writing nameserver option to resolv.conf\n"); fp = fopen("/etc/resolv.conf", "w+"); fprintf(fp, "nameserver 192.168.1.254\n"); fclose(fp); sleep(1); check_google(); printf("Making resolv.conf empty\n"); fp = fopen("/etc/resolv.conf", "w+"); fclose(fp); sleep(1); check_google(); printf("Writing nameserver option to resolv.conf\n"); fp = fopen("/etc/resolv.conf", "w+"); fprintf(fp, "nameserver 192.168.1.254\n"); fclose(fp); sleep(1); check_google(); }