while(do_again) {

       rc = gethostbyname_r(host, &hbuf, tmp, TMPLEN, &hp, &my_h_errno);
       if (rc != 0) {
          if(my_h_errno == TRY_AGAIN) {
             printf("HOST NOT FOUND: got a TRY_AGAIN response from gethostbyname_r()\n");
             continue;
          } else if (my_h_errno == HOST_NOT_FOUND) {
             printf("HOST NOT FOUND: Got an authoritative answer\n");
             exit(0);
          } else {
             printf("Other errors..\n");
             exit(0);
          }
       }
       do_again = false;
    }

Above code always returning with my_h_errno set to TRY_AGAIN for non-resolvable hostnames on Ubuntu 19.04 and 20.04. On previous versions of the OS or on other Linux flavors, it usually returns a more authoritative version, HOST_NOT_FOUND.

How does the call(gethostbyname_r) exactly work? And are there any changes on the dns or lookup mechanism on the latest versions of Ubuntu which is causing such behavior?

2

There are 2 answers

1
kjohri On

From the manual

The gethostbyname*(), gethostbyaddr*(), herror(), and hstrerror() functions are obsolete. Applications should use getaddrinfo(3), getnameinfo(3), and gai_strerror(3) instead.

1
afzal pasha On

[Update] Installing libnss-myhostname which kind of acts as a fallback mechanism for hostname resolving, fixed the issue.

Debugging on the glibc code got me to the point where there was a call to the above library functions, if exsits, where the h_errno was set to HOST_NOT_FOUND for non-resolvable hosts. That was initially being set to TRY_AGAIN in the glibc's gethostbyname_r functionality for such cases.