【问题标题】:getaddrinfo sorting IPv4 before IPv6 for localhost?getaddrinfo 在本地主机的 IPv6 之前排序 IPv4?
【发布时间】:2018-03-28 14:49:22
【问题描述】:

我为getaddrinfo写了一个非常简单的测试程序:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>

int main() {
    struct addrinfo hints;
    struct addrinfo *res, *rp;
    char hoststr[64], servstr[8];

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    getaddrinfo(NULL, "9998", &hints, &res);
    for (rp = res; rp != NULL; rp = rp->ai_next) {
        getnameinfo(rp->ai_addr, rp->ai_addrlen, hoststr, sizeof(hoststr),
                servstr, sizeof(servstr), NI_NUMERICHOST | NI_NUMERICSERV);
        printf("%s:%s\n", hoststr, servstr);
    }
}

当我编译并运行这个程序时,它会在 IPv6 地址之前给出 IPv4 地址:

# gcc -o getaddrinfo getaddrinfo.c
# ./getaddrinfo 
0.0.0.0:9998
:::9998

据我从其他来源得知,IPv6 地址应该优先于 IPv4。我正在使用默认的 /etc/gai.conf,这意味着 IPv6 应该优先于 IPv4。那么为什么 getaddrinfo 会这样排序呢?

# ip addr show lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever

【问题讨论】:

    标签: networking ipv6 getaddrinfo


    【解决方案1】:

    来自手册页:

    如果在hints.ai_flags中指定了AI_PASSIVE标志,并且节点是 NULL,则返回的套接字地址将适用于 绑定(2)一个将接受(2)连接的套接字。返回的 套接字地址将包含“通配符地址”(适用于 IPv4 的 INADDR_ANY 地址,IN6ADDR_ANY_INIT 用于 IPv6 地址)。通配符地址是 由打算接受任何主机网络地址上的连接的应用程序(通常是服务器)使用。如果节点不为 NULL, 然后忽略 AI_PASSIVE 标志。

    您所描述的行为是当您使用getaddrinfo() 查找名称以准备建立传出连接时。因为您正在做相反的事情,查找本地地址以绑定服务,所以地址的显示顺序无关紧要。

    【讨论】:

      猜你喜欢
      • 2011-01-17
      • 2020-02-17
      • 1970-01-01
      • 2012-03-01
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      相关资源
      最近更新 更多