【发布时间】:2013-10-24 06:29:49
【问题描述】:
在 IPv4 的情况下,我看到 sendmsg 的以下行为:
假设 10.1.2.3 是客户端 IP。 并且在客户端的其中一个接口上配置了10.1.2.10。
在 UDP 消息中,将以下控制信息添加到数据包中:
这只是服务器在回复客户端时应该使用的源地址或接口地址:
cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(sa->sin_addr);
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_SENDSRCADDR_WITH_ERROR;
* (struct in_addr *)CMSG_DATA(cmsg) = sa->sin_addr;
cmsg = (struct cmsghdr *)((caddr_t) cmsg + ALIGN(cmsg->cmsg_len));
消息被发送为:
sendmsg(fd, send_msg, 0);
如果我将 10.1.2.10 配置为 source-ip,并且将其添加到 cmsg 中,一切正常。 服务器回复 10.1.2.10。
但是,如果我在客户端的任何接口上配置了一些无法访问的 IP 地址或未配置的 IP,sendmsg 将失败并出现以下错误:
向 10.1.2.3(10.1.2.3).1813 发送消息失败:无法分配 请求地址
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
但我没有看到 IPv6 的相同行为:
假设 2001::1 是客户端 IP。 并且2001::2001配置在客户端的其中一个接口上。
IPv6源地址添加到控制消息中如下:
cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_PKTINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
memcpy((struct in6_addr *)CMSG_DATA(cmsg), &(sa6->sin6_addr),
sizeof(sa6->sin6_addr));
cmsg = (struct cmsghdr *)((caddr_t) cmsg + ALIGN(cmsg->cmsg_len));
如果我将 2001::2001 配置为源 IP 并且服务器确实回复此地址,则它工作正常。
但是,如果我配置了一个无法访问的 IPv6 源地址,比如 1001::1001,那么 sendmsg 不会出现类似于我们在 IPv4 案例中看到的错误消息。消息仍使用原始 IPv6 发送,即 2001::1。
有人可以建议可能是什么问题吗?
谢谢。
【问题讨论】: