gpt4 book ai didi

c - 如何使用 C 套接字 API 监听所有 IPV6 地址

转载 作者:太空狗 更新时间:2023-10-29 16:40:21 26 4
gpt4 key购买 nike

我维护 GPSD,这是一个广泛部署的开源服务守护程序,用于监控 GPS 和其他大地测量传感器。它在 IPv4 和 IPv6 上的端口 2947 上监听客户端应用程序连接。为了安全和隐私,它通常只监听环回地址,但守护进程有一个 -G 选项,旨在使其监听任何地址。

问题:-G 选项适用于 IPv4,但我不知道如何让它适用于 IPv6。基于各种教程示例应该工作的方法没有,而是产生一个错误,提示该地址已在使用中。我正在向有 IPv6 网络编程经验的人寻求帮助来解决这个问题。

相关代码在http://git.berlios.de/cgi-bin/gitweb.cgi?p=gpsd;a=blob;f=gpsd.c;h=ee2156caf03ca23405f57f3e04e9ef306a75686f;hb=HEAD

这段代码在 IPv4 下的 -G 和非 -G 情况下都可以正确运行,这很容易用 netstat -l 验证。

现在查看“case AF_INET6:”之后的第 398 行。 listen_global 选项由-G 设置;为假时,代码成功。目前有以下评论,继承自一位不知名的贡献者,内容如下:

/* else */
/* BAD: sat.sa_in6.sin6_addr = in6addr_any;
* the simple assignment will not work (except as an initializer)
* because sin6_addr is an array not a simple type
* we could do something like this:
* memcpy(sat.sa_in6.sin6_addr, in6addr_any, sizeof(sin6_addr));
* BUT, all zeros is IPv6 wildcard, and we just zeroed the array
* so really nothing to do here
*/

根据我查阅的各种教程示例,赋值“sat.sa_in6.sin6_addr = in6addr_any;”是(尽管有评论)是正确的,并且确实可以编译。但是,使用 -G 启动会失败,声称监听地址已在使用中。

赋值是“sat.sa_in6.sin6_addr = in6addr_any;”在这里名义上正确吗?如果有的话,我还缺少什么吗?

最佳答案

地址已被使用的原因是因为在许多 IPv6 网络堆栈上,默认情况下 IPv6 套接字将同时监听 IPv4 和 IPv6。 IPv4 连接将被透明地处理并映射到 subset of the IPv6 space .但是,这意味着您不能在不更改 IPv6 套接字设置的情况下将 IPv6 套接字绑定(bind)到与 IPv4 套接字相同的端口上。有道理吗?

只需在调用 bind 之前执行此操作(这取 self 的一个项目):

int on = 1;
if (addr->sa_family == AF_INET6) {
r = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
if (r)
/* error */
}

不幸的是,IPV6_V6ONLY 没有跨平台的默认值——这基本上意味着如果您需要,您总是需要明确地打开或关闭它,除非您不关心其他平台. Linux 默认关闭它,Windows 默认打开它...

关于c - 如何使用 C 套接字 API 监听所有 IPV6 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7474066/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com