Я пытаюсь обработать поток многоадресных пакетов в Linux. В течение 266 - 278 с (это не всегда одинаковый период времени) прием работает нормально, но после этого пакеты больше не принимаются.
Вот как я инициализирую многоадресную рассылку:
int arg = 1;
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(fd == -1) {
fprintf(stderr, "Error creating socket, %s\n", strerror(errno));
return;
}
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0) {
fprintf(stderr, "Failed to set `SO_REUSEADDR`, %s\n", strerror(errno));
return;
}
fcntl(fd, F_SETFL, O_NONBLOCK);
static struct ifreq intf;
strncpy(intf.ifr_name, cfg->ifname_buf, IF_NAMESIZE);
if(setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (char*)&intf, sizeof(intf)) < 0) {
fprintf(stderr, "Failed to set `SO_BINDTODEVICE`, %s\n", strerror(errno));
return;
}
struct sockaddr_in sin;
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = htons(xxxxx);
sin.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");
if(bind(fd, (struct sockaddr*)&sin, sizeof(struct sockaddr)) < 0) {
fprintf(stderr, "Error on binding socket, %s\n", strerror(errno));
return;
}
ioctl(fd, SIOCGIFADDR, &intf);
struct ip_mreqn igmpv2_req;
memset(&igmpv2_req, 0, sizeof(struct ip_mreqn));
if(inet_pton(AF_INET, "xxx.xxx.xxx.xxx", &igmpv2_req.imr_multiaddr.s_addr)) {
memcpy(&igmpv2_req.imr_address, &cfg->ifaddr.sin_addr, sizeof(struct in_addr));
igmpv2_req.imr_ifindex = cfg->ifindex;
printf("Multiaddr: %s\n", inet_ntoa(igmpv2_req.imr_multiaddr));
printf("Interfaceaddr: %s\n", inet_ntoa(igmpv2_req.imr_address));
printf("Ifindex: %d\n", igmpv2_req.imr_ifindex);
if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &igmpv2_req, sizeof(struct ip_mreqn)) < 0) {
fprintf(stderr, "Failed to set `IP_ADD_MEMBERSHIP`: %s\n", strerror(errno));
return;
} else {
printf("Saved FD for igmp socket!\n");
cfg->socket_fd_igmp = fd;
}
} else {
fprintf(stderr, "Failed `inet_pton` igmp-multiaddr, %s\n", strerror(errno));
return;
}
Как я уже сказал, он отлично работает в течение 266 - 280 с. После этого пакеты не принимаются. Я не знаю, связано ли это с тем, как я добавляю интерфейс в группу многоадресной рассылки, или из-за переполнения некоторой очереди ядра (я получаю до 200 тыс. Пакетов в секунду).