Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

glibc: getaddrinfo only returns ipv4 address for localhost even if ipv6 is enabled #19148

Closed
nhooyr opened this issue Oct 2, 2016 · 7 comments · Fixed by #19185
Closed

glibc: getaddrinfo only returns ipv4 address for localhost even if ipv6 is enabled #19148

nhooyr opened this issue Oct 2, 2016 · 7 comments · Fixed by #19185

Comments

@nhooyr
Copy link
Contributor

nhooyr commented Oct 2, 2016

Issue description

When localhost is mapped to both 127.0.0.1 and ::1 in /etc/hosts, getaddrinfo(3) still only returns 127.0.0.1. It should be returning both with ipv6 first.

Steps to reproduce

Run the following program as ./a.out localhost

#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
    if (argc < 2)
    exit(1);

    struct addrinfo* hints = calloc(1, sizeof(struct addrinfo));
    hints->ai_socktype = SOCK_STREAM;

    struct addrinfo* res;
    int ecode = getaddrinfo(argv[1], NULL, hints, &res) != 0;
    if (ecode != 0) {
    printf("error: %s\n", gai_strerror(ecode));
    return ecode;
    }

    while (res) {
    void* ptr;
    switch (res->ai_family) {
    case AF_INET:
        ptr = &((struct sockaddr_in*)res->ai_addr)->sin_addr;
        break;
    case AF_INET6:
        ptr = &((struct sockaddr_in6*)res->ai_addr)->sin6_addr;
        break;
    }
    char addr[INET6_ADDRSTRLEN];
    inet_ntop(res->ai_family, ptr, addr, sizeof(addr));
    printf("IPv%d address: %s\n", res->ai_family == PF_INET6 ? 6 : 4,
        addr);
    res = res->ai_next;
    }

    return 0;
}

On gentoo, OSX and arch the program returns something like:

IPv6 address: ::1
IPv4 address: 127.0.0.1

Whereas on nixos, it returns:

IPv4 address: 127.0.0.1

Technical details

  • System: (NixOS: nixos-version, Ubuntu/Fedora: lsb_release -a, ...) 17.03.git.792d277 (Gorilla)
  • Nix version: (run nix-env --version) nix-env (Nix) 1.11.4
  • Nixpkgs version: (run nix-instantiate --eval '<nixpkgs>' -A lib.nixpkgsVersion) 17.03.git.792d277
@nhooyr nhooyr changed the title glibc: getaddrinfo returns only ipv4 address for localhost when ipv6 is enabled glibc: getaddrinfo only returns ipv4 address for localhost even if ipv6 is enabled Oct 2, 2016
@Mic92
Copy link
Member

Mic92 commented Oct 2, 2016

There is also no /etc/gai.conf in nixos.

@vcunat
Copy link
Member

vcunat commented Oct 2, 2016

On Ubuntu 14.04.4 LTS, compiling your code with nix's gcc:

$ ./tests/localhost localhost
IPv6 address: ::1
IPv4 address: 127.0.0.1

The machine has those entries in /etc/hosts file.
(I compiled with gcc from the latest unstable channel, as your nixpkgs version seems to be unreachable from official branches.)

@abbradar
Copy link
Member

abbradar commented Oct 2, 2016

FWIW neither adding /etc/gai.conf from Arch or stopping nscd (a shot in the dark) fixed this.

@bennofs
Copy link
Contributor

bennofs commented Oct 2, 2016

The same issue can be demonstrated with getent ahosts localhost. Note that it works in a docker archlinux container on NixOS (using --net host), which means that the network stack itself is not the problem since the container shares the network stack with the host.

@bennofs
Copy link
Contributor

bennofs commented Oct 2, 2016

Found the issue: The difference is in the file /etc/host.conf. On archlinux, this file contains the following line:

multi on

NixOS doesn't use a non-default /etc/host.conf, so multi is set to its default value, which is off.

From man host.conf:

multi  Valid values are on and off.  If set to on, the resolver library will return all valid addresses for a
       host that appears in the /etc/hosts file, instead of only the first.  This is off by  default,  as  it
       may cause a substantial performance loss at sites with large hosts files.

@nhooyr
Copy link
Contributor Author

nhooyr commented Oct 2, 2016

@ben0x539 Should be a easy fix then right?

@cstrahan
Copy link
Contributor

cstrahan commented Oct 3, 2016

Following other popular distros is probably the way to go, perhaps with a config option to opt out.

Mic92 added a commit to Mic92/nixpkgs that referenced this issue Oct 3, 2016
this allows to return ipv4/ipv6 addresses for the same host in /etc/hosts.
fixes NixOS#19148
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants