为什么没有收到"Relayed"组播数据包?

  • 本文关键字:Relayed 数据包 multicast
  • 更新时间 :
  • 英文 :


我编写了一个测试程序来诊断多播路由问题。该程序有几种操作模式:

  • 发送方(发送多个多播数据包(
  • 接收器(接收多个多播数据包(
  • 请求者(发送多播数据包,然后等待响应,重复多次(
  • 响应程序(接收多播数据包,然后发送响应,重复多次(
  • 中继(类似于响应程序,但不响应发送地址,而是响应多播地址(

;继电器";模式是最近添加的,所有其他模式都按预期工作,但";继电器";不会(即使与其他模式做得或多或少相同(:中继只接收它自己的响应,但请求者不接收任何响应。

我在同一台主机上比较了(请求者、响应者(和(请求者和中继(的组合:

请求者1

~/src/C/multicast> ./mc-tester -l 224.7.7.7/123 -d 224.7.7.7/1234 -m requester -c100 -v1
[1] verbosity = 1
[1] Sending 100 requests on 3...
[1] Sending "224.7.7.7/1234: v04 request #1/100" size 39 to 224.7.7.7/1234 on 3
[1] Receiving message #1 on 3...
[1] v04 received #1/1 from 172.20.16.35/60248 (TTL -1): "172.20.16.35/35949 v04: response #1/10 for #1"
[1] Sending "224.7.7.7/1234: v04 request #2/100" size 39 to 224.7.7.7/1234 on 3
[1] Receiving message #1 on 3...
[1] v04 received #1/2 from 172.20.16.35/60248 (TTL -1): "172.20.16.35/35949 v04: response #2/10 for #2"
[1] Sending "224.7.7.7/1234: v04 request #3/100" size 39 to 224.7.7.7/1234 on 3
[1] Receiving message #1 on 3...
[1] v04 received #1/3 from 172.20.16.35/60248 (TTL -1): "172.20.16.35/35949 v04: response #3/10 for #3"
^C

("TTL-1"表示所接收的TTL是未知的(

响应程序1

~windl/src/C/multicast/mc-tester -v3 -l 224.7.7.7/1234 -m responder -d 224.7.7.7/1234 -c10
[1] verbosity = 3
[2] /home/windl/src/C/multicast/mc-tester: 224.7.7.7/1234 -> 224.7.7.7/1234 (16)
[1] op_mode = 3
[2] /home/windl/src/C/multicast/mc-tester: 224.7.7.7/1234 -> 224.7.7.7/1234 (16)
[1] msg_count = 10
[2] socket(PF_INET, SOCK_DGRAM, 0)...
[2] setsockopt(3, SO_REUSEADDR, 1)...
[2] socket(PF_INET, SOCK_DGRAM, 0)...
[2] setsockopt(4, SO_REUSEADDR, 0)...
[2] bind(3, 224.7.7.7/1234)...
[2] recv_socket: getsockname(3) returned 224.7.7.7/1234
[2] setsockopt(3, IP_MULTICAST_LOOP, 0)...
[2] setsockopt(3, IP_RECVTTL, 1)...
[2] setsockopt(3, IP_ADD_MEMBERSHIP, 224.7.7.7/1234)...
[2] setsockopt(4, IP_MULTICAST_TTL, 3)...
[1] Receiving 10 messages on 3...
[1] v04 received #1/10 from 172.20.16.35/35949 (TTL 3): "224.7.7.7/1234: v04 request #1/100"
[1] Sending "172.20.16.35/35949 v04: response #1/10 for #1" size 50 to 172.20.16.35/35949 on 4
[1] v04 received #2/10 from 172.20.16.35/35949 (TTL 3): "224.7.7.7/1234: v04 request #2/100"
[1] Sending "172.20.16.35/35949 v04: response #2/10 for #2" size 50 to 172.20.16.35/35949 on 4
[1] v04 received #3/10 from 172.20.16.35/35949 (TTL 3): "224.7.7.7/1234: v04 request #3/100"
[1] Sending "172.20.16.35/35949 v04: response #3/10 for #3" size 50 to 172.20.16.35/35949 on 4
^C

因此,这种组合不出所料。现在没有的组合:

请求者2

/src/C/multicast> ./mc-tester -l 224.7.7.7/123 -d 224.7.7.7/1234 -m requester -c100 -v1
[1] verbosity = 1
[1] Sending 100 requests on 3...
[1] Sending "224.7.7.7/1234: v04 request #1/100" size 39 to 224.7.7.7/1234 on 3
select timed out
[1] Sending "224.7.7.7/1234: v04 request #2/100" size 39 to 224.7.7.7/1234 on 3
select timed out
[1] Sending "224.7.7.7/1234: v04 request #3/100" size 39 to 224.7.7.7/1234 on 3
^C

("select timed out"表示接收,而不是发送(

继电器

~windl/src/C/multicast/mc-tester -v3 -l 224.7.7.7/1234 -m relay -d 224.7.7.7/1234 -c10
[1] verbosity = 3
[2] /home/windl/src/C/multicast/mc-tester: 224.7.7.7/1234 -> 224.7.7.7/1234 (16)
[1] op_mode = 4
[2] /home/windl/src/C/multicast/mc-tester: 224.7.7.7/1234 -> 224.7.7.7/1234 (16)
[1] msg_count = 10
[2] socket(PF_INET, SOCK_DGRAM, 0)...
[2] setsockopt(3, SO_REUSEADDR, 0)...
[2] socket(PF_INET, SOCK_DGRAM, 0)...
[2] setsockopt(4, SO_REUSEADDR, 1)...
[2] bind(3, 224.7.7.7/1234)...
[2] recv_socket: getsockname(3) returned 224.7.7.7/1234
[2] setsockopt(3, IP_MULTICAST_LOOP, 0)...
[2] setsockopt(3, IP_RECVTTL, 1)...
[2] setsockopt(3, IP_ADD_MEMBERSHIP, 224.7.7.7/1234)...
[2] setsockopt(4, IP_MULTICAST_TTL, 3)...
[2] setsockopt(4, IP_ADD_MEMBERSHIP, 224.7.7.7/1234)...
[1] Relaying 10 messages on 3...
[1] v04 received #1/10 from 172.20.16.35/33488 (TTL 3): "224.7.7.7/1234: v04 request #1/100"
[1] Sending "224.7.7.7/1234 v04: relay #1/10 for #1" size 43 to 224.7.7.7/1234 on 4
[1] v04 received #2/10 from 172.20.16.35/44217 (TTL 3): "224.7.7.7/1234 v04: relay #1/10 for #1"
[1] Sending "224.7.7.7/1234 v04: relay #2/10 for #1" size 43 to 224.7.7.7/1234 on 4
[1] v04 received #3/10 from 172.20.16.35/44217 (TTL 3): "224.7.7.7/1234 v04: relay #2/10 for #1"
[1] Sending "224.7.7.7/1234 v04: relay #3/10 for #2" size 43 to 224.7.7.7/1234 on 4
[1] v04 received #4/10 from 172.20.16.35/44217 (TTL 3): "224.7.7.7/1234 v04: relay #3/10 for #2"
[1] Sending "224.7.7.7/1234 v04: relay #4/10 for #3" size 43 to 224.7.7.7/1234 on 4

[1] v04 received #9/10 from 172.20.16.35/44217 (TTL 3): "224.7.7.7/1234 v04: relay #8/10 for #7"
[1] Sending "224.7.7.7/1234 v04: relay #9/10 for #8" size 43 to 224.7.7.7/1234 on 4
[1] v04 received #10/10 from 172.20.16.35/44217 (TTL 3): "224.7.7.7/1234 v04: relay #9/10 for #8"
[1] Sending "224.7.7.7/1234 v04: relay #10/10 for #9" size 44 to 224.7.7.7/1234 on 4
[1] Received 10 messages
[2] setsockopt(3, IP_DROP_MEMBERSHIP)...
[2] setsockopt(4, IP_DROP_MEMBERSHIP)...
[2] close(4)...
[2] close(3)...

因此,中继中的消息在本地循环。该测试是在Linux(SLES12 SP4(上完成的。

我决定不用程序的C源来延长这个问题,但当被要求时,我可以介绍相关部分或继电器的ltrace/strace。

如果绑定到同一端口,您将收到自己的消息。

有一个选项可以关闭:IP_MULTICAST_LOOP

见ip(7(;我认为这是Linux特有的。

IP_MULTICAST_LOOP (since Linux 1.2)
Set or read a boolean integer argument that determines
whether sent multicast packets should be looped back to
the local sockets.

假设您的中继在多主机上;发送时,您需要确保有一个绑定到(每个(传出接口的套接字,并在每个接口上发送(要中继到的每个接口的套接字(。

这已经有一段时间了,但代码可能有点烦人,但如果你要求用户提供你可以绑定(2(UDP套接字的接口的IP(IPv4的IP,IPv6的接口(,代码会更简单。

干杯,Cameron

最新更新