Getaddrinfo()返回通配符地址,尽管没有设置AI_PASSIVE

时间:2017-11-04 08:53:46

标签: c dns

来自getaddrinfo()的手册页......

  

如果没有在hints.ai_flags中设置AI_PASSIVE标志,那么          返回的套接字地址适用于connect(2),          sendto(2),或sendmsg(2)。

但我正在为某些网站返回0.0.0.0。我不应该得到通配符地址吗?

void checkAddresses(char * addrName)
{
    struct addrinfo hints;
    struct addrinfo * infoptr = 0;
    struct addrinfo * node = 0;
    int gai_return = 0;
    int socket_fd = 0;
    int gni_return = 0;
    char host_buffer[255] = { 0 };
    struct sockaddr_in * h = 0;

    memset(host_buffer, 0, sizeof(host_buffer));

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = 0;
    hints.ai_protocol = 0;
    hints.ai_canonname = NULL;
    hints.ai_addr = NULL;
    hints.ai_next = NULL;

    gai_return = getaddrinfo(addrName, 0, &hints, &infoptr);
    if(gai_return != 0)
    {
        perror("Getaddrinfo() failure");
        exit(1);
    }

    for (node = infoptr; node != NULL; node = node->ai_next)
    {
        h = (struct sockaddr_in *) node->ai_addr;
        strcpy(host_buffer, inet_ntoa(h->sin_addr));
        puts(host_buffer);
    }

    freeaddrinfo(infoptr);
}

1 个答案:

答案 0 :(得分:1)

您指定了AF_UNSPEC,这意味着未指定的地址系列。 现在这意味着您将同时获得AF_INETAF_INET6。如果你想要的只是AF_INET,那么请说出来。

请注意,特别是如果您正在查找localhost,IPv6地址::1将具有二进制表示

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01

现在,如果您将前4个字节重新解释为IPv4地址(如果将指针强制转换为struct sockaddr_in *则会发生这种情况)......

使用AF_UNSPEC,您必须检查node->ai_family; IPv4套接字为AF_INET,IPv6为AF_INET6 - 其他可能是其他东西。

但请注意,大多数情况下,您根本不会检查地址 - 没有必要。相反,您只需将uncast struct sockaddr *ai_addr传递给sendto(对于UDP套接字)。