* Re: getaddrinfo() returns two identical results
2018-01-05 17:39 getaddrinfo() returns two identical results Yuri Kanivetsky
@ 2018-01-06 22:54 ` Yuri Kanivetsky
0 siblings, 0 replies; 2+ messages in thread
From: Yuri Kanivetsky @ 2018-01-06 22:54 UTC (permalink / raw)
To: libc-help
Hi,
Okay, I more or less see now:
int
getaddrinfo (const char *name, const char *service,
const struct addrinfo *hints, struct addrinfo **pai)
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=2c4b6d6793a4c3a96eb1e545570ac28867681751;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l2206
last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=2c4b6d6793a4c3a96eb1e545570ac28867681751;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l2304
static int
gaih_inet (const char *name, const struct gaih_service *service,
const struct addrinfo *req, struct addrinfo **pai,
unsigned int *naddrs, struct scratch_buffer *tmpbuf)
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=2c4b6d6793a4c3a96eb1e545570ac28867681751;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l342
rc = __gethostbyname2_r (name, AF_INET, &th,
tmpbuf->data, tmpbuf->length,
&h, &h_errno);
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=2c4b6d6793a4c3a96eb1e545570ac28867681751;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l595
int
INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM
EXTRA_PARAMS)
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/getXXbyYY_r.c;h=bce80e05dd2d176467809faf353828f50cf76eaf;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l189
status = DL_CALL_FCT (fct.l, (ADD_VARIABLES, resbuf, buffer, buflen,
&errno H_ERRNO_VAR EXTRA_VARIABLES));
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/getXXbyYY_r.c;h=bce80e05dd2d176467809faf353828f50cf76eaf;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l316
enum nss_status
_nss_files_gethostbyname2_r (const char *name, int af, struct
hostent *result,
char *buffer, size_t buflen, int *errnop,
int *herrnop)
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-hosts.c;h=6f7cc4d94ba69ab58d684f63cc685f6fa5c6ad4a;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l385
return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen,
errnop, herrnop, NULL, NULL);
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-hosts.c;h=6f7cc4d94ba69ab58d684f63cc685f6fa5c6ad4a;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l389
enum nss_status
_nss_files_gethostbyname3_r (const char *name, int af, struct
hostent *result,
char *buffer, size_t buflen, int *errnop,
int *herrnop, int32_t *ttlp, char **canonp)
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-hosts.c;h=6f7cc4d94ba69ab58d684f63cc685f6fa5c6ad4a;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l334
Here we get first match, and—if multi is on in /etc/host.conf—the rest of them:
while ((status = internal_getent (stream, result, buffer, buflen, errnop,
herrnop, af, flags))
== NSS_STATUS_SUCCESS)
{
LOOKUP_NAME_CASE (h_name, h_aliases)
}
if (status == NSS_STATUS_SUCCESS
&& _res_hconf.flags & HCONF_FLAG_MULTI)
status = gethostbyname3_multi
(stream, name, af, result, buffer, buflen, errnop, herrnop, flags);
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-hosts.c;h=6f7cc4d94ba69ab58d684f63cc685f6fa5c6ad4a;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l352
static enum nss_status
gethostbyname3_multi (FILE * stream, const char *name, int af,
struct hostent *result, char *buffer, size_t buflen,
int *errnop, int *herrnop, int flags)
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-hosts.c;h=6f7cc4d94ba69ab58d684f63cc685f6fa5c6ad4a;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l127
status = internal_getent (stream, &tmp_result_buf, tmp_buffer.data,
tmp_buffer.length, errnop, herrnop, af,
flags);
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-hosts.c;h=6f7cc4d94ba69ab58d684f63cc685f6fa5c6ad4a;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l162
static enum nss_status
internal_getent (FILE *stream, struct STRUCTURE *result,
char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO
EXTRA_ARGS_DECL)
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-XXX.c;h=265331ef21cd60ed301ab49eac4d6681d74bb388;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l178
|| ! (parse_result = parse_line (p, result, data, buflen, errnop
EXTRA_ARGS)));
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-XXX.c;h=265331ef21cd60ed301ab49eac4d6681d74bb388;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l222
Here we parse "::1 localhost.localdomain localhost" line. We try
to run inet_pton over "::1". That fails, since af == AF_INET. Then we
notice that "::1" is IPv6 loopback address, so we return IPv4 loopback
address:
LINE_PARSER
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-hosts.c;h=6f7cc4d94ba69ab58d684f63cc685f6fa5c6ad4a;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l51
if (inet_pton (af == AF_UNSPEC ? AF_INET : af, addr, entdata->host_addr)
> 0)
af = af == AF_UNSPEC ? AF_INET : af;
else
{
if (...)
...
else if (af == AF_INET
&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
{
if (...)
...
else if (IN6_IS_ADDR_LOOPBACK (entdata->host_addr))
{
in_addr_t localhost = htonl (INADDR_LOOPBACK);
memcpy (entdata->host_addr, &localhost, sizeof (localhost));
}
https://sourceware.org/git/?p=glibc.git;a=blob;f=nss/nss_files/files-hosts.c;h=6f7cc4d94ba69ab58d684f63cc685f6fa5c6ad4a;hb=633e2f7f3d88df6427aa3a7a984d3a6b796d9611#l59
Can you explain why does not fail in this case? For what it's needed?
Also, it doesn't look like a major issue, but the behavior doesn't
seem to be expected. Should I report a bug?
Regards,
Yuri
^ permalink raw reply [flat|nested] 2+ messages in thread