当设置 IP_PKTINFO 时,recvmsg returns 意外 in_pktinfo
When IP_PKTINFO is set, recvmsg returns an unexpected in_pktinfo
我正在编写一个使用 UDP 多播的程序。我需要过滤掉来自指定接口的消息。我设置IP_PKTINFO为socket:
int enable = 1;
OS_Result rc = setsockopt(readArg->conn->sock, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable));
然后,我打印出in_pktinfo的内容:
for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msgHdr); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgHdr, cmsg)) {
// ignore the control headers that don't match what we want
if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) {
continue;
}
struct in_pktinfo *pi = (struct in_pktinfo *)CMSG_DATA(cmsg);
char interName[20];
memset(interName, 0, 20);
if_indextoname(pi->ipi_ifindex, interName);
printf("! ================================================= !\n");
printf("ipi_ifindex: %d\n", pi->ipi_ifindex);
printf("interface name: %s\n", interName);
printf("ipi_addr: %s\n", inet_ntoa(pi->ipi_addr));
printf("ipi_spec_dst: %s\n", inet_ntoa(pi->ipi_spec_dst));
printf("! ================================================= !\n");
}
没想到多次执行程序后会出现ipi_ifindex和ipi_spec_dst:
! ================================================= !
ipi_ifindex: 0 <------ exception
interface name:
ipi_addr: 239.255.0.1
ipi_spec_dst: 0.0.0.0
! ================================================= !
! ================================================= !
ipi_ifindex: 2
interface name: ens3
ipi_addr: 239.255.0.1
ipi_spec_dst: 192.168.122.50
! ================================================= !
! ================================================= !
ipi_ifindex: 2
interface name: ens3
ipi_addr: 239.255.0.1
ipi_spec_dst: 192.168.122.50
! ================================================= !
似乎Linux 没有正确解析出UDP 消息是从哪个接口接收的。这种现象出现在socket收到的前几个包中,概率出现
我已经解决了这个问题。一旦套接字绑定到 IP 地址和端口,它就开始接收数据包。所以UDP Socket的属性应该在调用bind()
函数之前设置。
我正在编写一个使用 UDP 多播的程序。我需要过滤掉来自指定接口的消息。我设置IP_PKTINFO为socket:
int enable = 1;
OS_Result rc = setsockopt(readArg->conn->sock, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable));
然后,我打印出in_pktinfo的内容:
for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msgHdr); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgHdr, cmsg)) {
// ignore the control headers that don't match what we want
if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) {
continue;
}
struct in_pktinfo *pi = (struct in_pktinfo *)CMSG_DATA(cmsg);
char interName[20];
memset(interName, 0, 20);
if_indextoname(pi->ipi_ifindex, interName);
printf("! ================================================= !\n");
printf("ipi_ifindex: %d\n", pi->ipi_ifindex);
printf("interface name: %s\n", interName);
printf("ipi_addr: %s\n", inet_ntoa(pi->ipi_addr));
printf("ipi_spec_dst: %s\n", inet_ntoa(pi->ipi_spec_dst));
printf("! ================================================= !\n");
}
没想到多次执行程序后会出现ipi_ifindex和ipi_spec_dst:
! ================================================= !
ipi_ifindex: 0 <------ exception
interface name:
ipi_addr: 239.255.0.1
ipi_spec_dst: 0.0.0.0
! ================================================= !
! ================================================= !
ipi_ifindex: 2
interface name: ens3
ipi_addr: 239.255.0.1
ipi_spec_dst: 192.168.122.50
! ================================================= !
! ================================================= !
ipi_ifindex: 2
interface name: ens3
ipi_addr: 239.255.0.1
ipi_spec_dst: 192.168.122.50
! ================================================= !
似乎Linux 没有正确解析出UDP 消息是从哪个接口接收的。这种现象出现在socket收到的前几个包中,概率出现
我已经解决了这个问题。一旦套接字绑定到 IP 地址和端口,它就开始接收数据包。所以UDP Socket的属性应该在调用bind()
函数之前设置。