| Summary: | GETAI(AF_UNSPEC) does not return both IPv6 and IPv4 addresses on first request from /etc/hosts | ||
|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Siddhesh Poyarekar <spoyarek> |
| Component: | glibc | Assignee: | Siddhesh Poyarekar <spoyarek> |
| Status: | CLOSED RAWHIDE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
| Severity: | high | Docs Contact: | |
| Priority: | urgent | ||
| Version: | rawhide | CC: | akarlsso, ashankar, codonell, fweimer, jakub, jdonohue, law, mfranc, mnewsome, pfrankli, richard.alpe, schwab, snagar, spoyarek |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | Bug Fix | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2013-08-26 10:12:57 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
GETAI only returns the IPv4 result via nscd on first request via getaddrinfo (PF_UNSPEC) if the host is resolved from /etc/hosts (localhost for example). One may run `nscd -i hosts` and then call getaddrinfo to work around this. How to reproduce: Sample program: #include <stdio.h> #include <stdlib.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <strings.h> #ifndef NI_MAXHOST #define NI_MAXHOST 1025 #endif int main(int argc, char *argv[]) { struct addrinfo *result; struct addrinfo hints = {0}; struct addrinfo *res; int error; char *host = argv[1]; if (argc > 2) { if (strcasecmp(argv[1], "AF_INET6") == 0) hints.ai_family = AF_INET6; if (strcasecmp(argv[1], "AF_INET") == 0) hints.ai_family = AF_INET; host = argv[2]; } printf("Hints family=%d\n", hints.ai_family); /* resolve the domain name into a list of addresses */ error = getaddrinfo(host, NULL, &hints, &result); if (error != 0) { if (error == EAI_SYSTEM) { perror("getaddrinfo"); } else { fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error)); } exit(EXIT_FAILURE); } /* loop over all returned results and do inverse lookup */ for (res = result; res != NULL; res = res->ai_next) { char hostname[NI_MAXHOST] = ""; char buf[130] = {0}; error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0); if (error != 0) { fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error)); continue; } if (*hostname != '\0') { if (res->ai_family == AF_INET) inet_ntop(res->ai_family, &((struct sockaddr_in *)res->ai_addr)->sin_addr, buf, sizeof(buf)); if (res->ai_family == AF_INET6) inet_ntop(res->ai_family, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, buf, sizeof(buf)); printf("host=%s, family=%d addr=%s\n", hostname, res->ai_family, buf); } } freeaddrinfo(result); printf("\n"); return 0; } Delete nscd cache, Build and run program: # service nscd stop # rm -f /var/db/nscd/* # service nscd start # gcc foo.c # ./a.out localhost Actual Result: Hints family=0 host=localhost, family=2 addr=127.0.0.1 host=localhost, family=2 addr=127.0.0.1 host=localhost, family=2 addr=127.0.0.1 Expected Result: Hints family=0 host=localhost, family=10 addr=::1 host=localhost, family=10 addr=::1 host=localhost, family=10 addr=::1 host=localhost, family=2 addr=127.0.0.1 host=localhost, family=2 addr=127.0.0.1 host=localhost, family=2 addr=127.0.0.1 This is because res_hconf is not initialized in aicache.c.