简体   繁体   中英

When IP_PKTINFO is set, recvmsg returns an unexpected in_pktinfo

I am writing a program that uses UDP multicast. I need to filter out messages from the specified interface. I set IP_PKTINFO to socket:

int enable = 1;
OS_Result rc = setsockopt(readArg->conn->sock, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable));

Then, I print out the contents of 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");
}

Unexpected ipi_ifindex and ipi_spec_dst will appear after executing the program multiple times:

! ================================================= !
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
! ================================================= !

It seems that Linux does not correctly parse out which interface the UDP message is received from. This phenomenon occurs in the first few packets received by socket and the probability appears

I have solved this problem. Once the socket is bound to the IP address and port, it begins to receive packets. So the property of UDP Socket should be set before calling the bind() function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM