IPv6を介してデータグラムを受信しようとしています。私が興味を持っているニュースは次のとおりです。
$ sudo tcpdump | grep 20001
[sudo] password for miroslavv:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:00:59.981338 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 86
13:00:59.981348 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.981733 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 114
13:00:59.981744 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 67
13:00:59.981940 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 60
13:00:59.982276 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982492 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982656 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982974 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 69
13:00:59.982985 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 111
13:00:59.983335 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 152
私のプラットフォームはテスト用のDebianです。私はPythonを試しましたはい、彼らは同じマシン上で互いに完全に通信しているようです。ただし、上記のデータグラムを受信するようにサーバーを構成すると、サーバーは停止しますrecv()
。
ファイアウォール設定:
$ sudo iptables -L
[sudo] password for miroslavv:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
私はIPv6を持っています:
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.42.92 netmask 255.255.248.0 broadcast 192.168.47.255
inet6 fd01:e671:2015:e3ff:219:fff:fe26:a27e prefixlen 48 scopeid 0x0<global>
inet6 fe80::219:fff:fe26:a27e prefixlen 64 scopeid 0x20<link>
ether 00:19:0f:26:a2:7e txqueuelen 1000 (Ethernet)
RX packets 3360785 bytes 943676498 (899.9 MiB)
RX errors 0 dropped 6185 overruns 0 frame 0
TX packets 473236 bytes 77103917 (73.5 MiB)
TX errors 1 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 140 bytes 7912 (7.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 140 bytes 7912 (7.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
netcat
また沈黙します:
$ netcat -u -l -p20001
興味深い観察が続きます。メッセージを読むためにC ++コードを取得しました。もしboost::asio
同じIPとポートから同時に読みます。改善されたポーリングを停止すると、私のコードもメッセージの受信を停止します。
私はいくつかのサンプルCプログラムを試しましたが、誰でも1つのUDPパケットを受信することはできません。1、2、サム、4。
ここで何が起こっているのでしょうか?
答え1
実際、マルチキャストグループに参加する機会を逃しました。 ipv6マルチキャストの例は非常にまれで、テストされたコードは次のとおりです。
struct addrinfo hint {}, *res;
hint.ai_flags = AI_PASSIVE;
hint.ai_family = AF_INET6;
hint.ai_socktype = SOCK_DGRAM;
getaddrinfo( server._rep.c_str(), std::to_string( port ).c_str(), &hint, &res )
mreq.ipv6mr_multiaddr = reinterpret_cast< sockaddr_in6* >( res->ai_addr )->sin6_addr;
mreq.ipv6mr_interface if_nametoindex( iface.c_str();
setsockopt( _fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (void*)mreq, sizeof( mreq ) )
PS:このトピックに関するいくつかの有用なリソース:
http://www.iitk.ac.in/LDP/HOWTO/Multicast-HOWTO.html#toc6
http://docs.oracle.com/cd/E19253-01/817-4415/sockets-149/index.html