This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nscd/15890] New: GETAI(AF_UNSPEC) does not return both IPv6 and IPv4 addresses on first request from /etc/hosts


http://sourceware.org/bugzilla/show_bug.cgi?id=15890

            Bug ID: 15890
           Summary: GETAI(AF_UNSPEC) does not return both IPv6 and IPv4
                    addresses on first request from /etc/hosts
           Product: glibc
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: nscd
          Assignee: siddhesh at redhat dot com
          Reporter: siddhesh at redhat dot com
                CC: drepper.fsp at gmail dot com

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:

/*
 * Sorry about the state of this code. It's a quick hack to debug case 00836659
 * (nscd caching problem).
 */

#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.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]