Я пишу программу, которая использует многоадресную передачу UDP. Мне нужно отфильтровать сообщения из указанного интерфейса. Я устанавливаю IP_PKTINFO в сокет:
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. Это явление происходит в первых нескольких пакетах, полученных сокетом, и появляется вероятность