This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
getaddrinfo() returns two identical results
- From: Yuri Kanivetsky <yuri dot kanivetsky at gmail dot com>
- To: libc-help at sourceware dot org
- Date: Fri, 5 Jan 2018 19:39:46 +0200
- Subject: getaddrinfo() returns two identical results
- Authentication-results: sourceware.org; auth=none
Hi,
Consider this test program:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
const char* family_to_string(int family)
{
return family == AF_INET ? "AF_INET"
: family == AF_INET6 ? "AF_INET6"
: "<unknown>";
}
const char* socktype_to_string(int socktype)
{
return socktype == SOCK_STREAM ? "SOCK_STREAM"
: socktype == SOCK_DGRAM ? "SOCK_DGRAM"
: "<unknown>";
}
const char* protocol_to_string(int protocol)
{
return protocol == IPPROTO_TCP ? "IPPROTO_TCP"
: protocol == IPPROTO_UDP ? "IPPROTO_UDP"
: "<unknown>";
}
void print_addrinfo(struct addrinfo *ai)
{
int r;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
r = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
if (r)
{
fputs("getnameinfo\n", stderr);
exit(EXIT_FAILURE);
}
const char *family = family_to_string(ai->ai_family);
const char *socktype = socktype_to_string(ai->ai_socktype);
const char *protocol = protocol_to_string(ai->ai_protocol);
const char *family2 = family_to_string(ai->ai_addr->sa_family);
printf("flags=%i, family=%s, socktype=%s, protocol=%s,
family=%s, host=%s, serv=%s\n",
ai->ai_flags, family, socktype, protocol, family2, hbuf, sbuf);
}
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
int r;
struct addrinfo hints;
struct addrinfo *result, *ai;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
r = getaddrinfo("localhost", "8000", &hints, &result);
if (r)
{
fputs("getaddrinfo\n", stderr);
exit(EXIT_FAILURE);
}
ai = result;
while (ai)
{
print_addrinfo(ai);
ai = ai->ai_next;
}
exit(EXIT_SUCCESS);
}
In /etc/hosts I have:
127.0.0.1 localhost.localdomain localhost
::1 localhost.localdomain localhost
When I set `hints.ai_family = AF_INET`, I get:
$ gcc -Wall -Wextra -pedantic -pedantic-errors -Werror -g
-gdwarf-2 -g3 % && ./a.out
flags=0, family=AF_INET, socktype=SOCK_STREAM,
protocol=IPPROTO_TCP, family=AF_INET, host=127.0.0.1, serv=8000
flags=0, family=AF_INET, socktype=SOCK_STREAM,
protocol=IPPROTO_TCP, family=AF_INET, host=127.0.0.1, serv=8000
Without it:
flags=0, family=AF_INET6, socktype=SOCK_STREAM,
protocol=IPPROTO_TCP, family=AF_INET6, host=::1, serv=8000
flags=0, family=AF_INET, socktype=SOCK_STREAM,
protocol=IPPROTO_TCP, family=AF_INET, host=127.0.0.1, serv=8000
>From what I can see, `hints` parameter is supposed to filter results.
Which I cannot reproduce on my machine.
Not sure which info can be of help here. Feel free to ask. I'm running
Arch Linux and glibc-2.26. I haven't used systemd-resolved, and it's
not running.
/etc/resolv.conf:
# Generated by resolvconf
search Dlink
nameserver 192.168.0.1
/etc/nsswitch.conf:
# Begin /etc/nsswitch.conf
passwd: compat mymachines systemd
group: compat mymachines systemd
shadow: compat
publickey: files
hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname
networks: files
protocols: files
services: files
ethers: files
rpc: files
netgroup: files
# End /etc/nsswitch.conf
I'm now building glibc with debugging information, hopefully it'll
shed some light on the matter. But if you've got any ideas what to
check, or possible explanation, feel free to reply.
P.S. Relevant Stack Overflow question:
https://stackoverflow.com/questions/48100853/getaddrinfo-returns-several-identical-results
Regards,
Yuri