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.
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
nixos-version, Ubuntu/Fedora: lsb_release -a, ...) 17.03.git.792d277 (Gorilla)nix-env --version) nix-env (Nix) 1.11.4nix-instantiate --eval '<nixpkgs>' -A lib.nixpkgsVersion) 17.03.git.792d277There is also no /etc/gai.conf in nixos.
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.)
FWIW neither adding /etc/gai.conf from Arch or stopping nscd (a shot in the dark) fixed this.
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.
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.
@ben0x539 Should be a easy fix then right?
Following other popular distros is probably the way to go, perhaps with a config option to opt out.
Most helpful comment
Found the issue: The difference is in the file
/etc/host.conf. On archlinux, this file contains the following line:NixOS doesn't use a non-default
/etc/host.conf, somultiis set to its default value, which is off.From
man host.conf: