getaddrinfo() returns two identical results

Yuri Kanivetsky yuri.kanivetsky@gmail.com
Sat Jan 6 22:54:00 GMT 2018


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



More information about the Libc-help mailing list