私はipv6マルチキャストが動作しないような古いコードベースを扱っています。ソケットをff01 :: 1にbind()しようとすると失敗します。ソケットは私のイーサネットインターフェイスで作成されています。プレーンソケットを使用したipv6マルチキャストの要件は何ですか?
ソケットをin6addr_anyにバインドすると(「::」)、バインドは成功しますが、パケットは受信されません。特定のソケットを使用して、アプリケーション自体が送信しているパケットを除いてはパケットは受信されません(IPV6_MULTICAST_LOOPが設定されています) 。これらのパケットは決してアプリケーションから離れることはありません。イーサネットインターフェイスでパケットをキャプチャしようとすると、wiresharkには表示されません。着信する外部マルチキャストパケットだけが表示されます。それらのどれも私のアプリケーションに到達しません。
システムは、Linux 4.4.0のUbuntu 16.04です。
セットアップコードのサンプル:
#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
}
これはCではなく、Cです! – Olaf
@Olaf私が使用している関数がCリンケージを持っているからといって、これは私のコードがCであるとは限りません。私はそれに応じて質問を編集しました。 –