J'ai affaire à une ancienne base de code, dans laquelle ipv6 multicast ne semble pas fonctionner. Lorsque j'essaie de lier() le socket à ff01 :: 1, il échoue. Le socket est en cours de création dans mon interface ethernet. Liaison du socket à in6addr_any, qui est "::", aboutit à une liaison réussie, mais aucun paquet n'est jamais reçu, sauf pour ceux qui sont envoyés par l'application elle-même, en utilisant le socket donné (IPV6_MULTICAST_LOOP est défini) . Ces paquets ne semblent jamais quitter l'application non plus. Ils ne sont pas visibles dans wireshark lorsque vous essayez de capturer des paquets dans l'interface ethernet. Seuls les paquets de multidiffusion externes entrants sont visibles. Aucun d'eux n'atteint mon application.Quelles sont les exigences pour la multidiffusion ipv6 utilisant des douilles simples?
Le système est Ubuntu 16.04 avec Linux 4.4.0.
Un échantillon du code de configuration:
#define MCASTADDRC "ff01::1"
int mcast::bind_mcast(const char *interface) {
this->net = socket(AF_INET6, SOCK_DGRAM, 0);
inet_pton(AF_INET6,MCASTADDRC,&this->multicast.ipv6mr_multiaddr);
this->ifaceaddr.sin6_family = AF_INET6;
this->ifaceaddr.sin6_port = htons(SRVPORT);
this->ifaceaddr.sin6_addr = in6addr_any;
// interface for multicast
this->mcastaddr.sin6_family = AF_INET6;
this->mcastaddr.sin6_port = htons(SRVPORT);
this->mcastaddr.sin6_addr = this->multicast.ipv6mr_multiaddr;
int opcoes = fcntl(this->net, F_GETFL, 0);
if (fcntl(this->net, F_SETFL, opcoes | O_NONBLOCK) == -1) {
// fail
return(false);
}
if (bind(net, (struct sockaddr *) &this->ifaceaddr, sizeof(this->ifaceaddr)) == -1) {
// fail
return(false);
}
this->ifaceindex = if_nametoindex(interface);
this->multicast.ipv6mr_interface = this->ifaceindex;
this->ifaceaddr.sin6_scope_id = this->ifaceindex;
int mcast_loop = 1;
if (setsockopt(this->net, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &mcast_loop, sizeof(mcast_loop))) {
//fail
return(false);
}
if (setsockopt(this->net, IPPROTO_IPV6, IPV6_MULTICAST_IF, &this->ifaceindex, sizeof(this->ifaceindex))) {
//fail
return(false);
}
if (setsockopt(this->net, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &this->multicast, sizeof(this->multicast))) {
//fail
return(false);
}
int optval = 6000000;
int optlen = sizeof(optval);
if (setsockopt(this->net, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval))) {
exit(0);
}
if (getsockopt(this->net, SOL_SOCKET, SO_RCVBUF, &optval, (socklen_t *)&optlen)) {
// fail
exit(0);
}
if(optval < 262142) {
// buffer is too small, we failed
exit(0);
}
return(true); // success
}
Ceci est C++, pas c! – Olaf
@Olaf Vous avez raison, juste parce que les fonctions que j'utilise ont un lien C cela ne signifie pas que mon code est C. J'ai édité la question en conséquence. –