在同一个多播地址上连接一个源特定的多播

时间:2021-01-27 18:10:24

I am trying to set up multicast sources for an application on linux using source specific multicast (SSM) and the code is going ok (using the C interface) but I would like to verify that the system will behave as I expect it to.

我正在尝试使用源特定的多播(SSM)为linux上的应用程序设置多播源,并且代码运行良好(使用C接口),但是我想验证系统是否按照我的预期运行。

Setup:
Multicast address - 233.X.X.X:9876
Source1 - 192.X.X.1
Source2 - 192.X.X.2
Interface1 - 192.X.X.100
Interface1 - 192.X.X.101

设置:多播地址- 233.X.X。X:9876 Source1 - 192. x.x。1 Source2 - 192. x.x。2 Interface1 - 192. x.x。100年Interface1 - 192. x.x.101

Steps

步骤

  1. Configure so that only Source1 is sending to the multicast address
  2. 配置,使只有Source1正在发送到多播地址
  3. Start a reader (reader1) that binds to the multicast address and joins the multicast with ssm src as Source1 and interface as Interface1
  4. 启动一个读取器(reader1),该读取器绑定到多播地址,并以ssm src作为Source1连接多播,接口作为Interface1
  5. Observe that data is seen on reader1
  6. 观察在reader1上看到的数据
  7. Do the same (reader2) but using Source2 and Interface2
  8. 做同样的事情(reader2)但是使用Source2和Interface2

Desired Outcome:
Reader1 can see the data from the multicast.
Reader2 can't see the data from the multicast.

期望的结果:Reader1可以看到来自多播的数据。Reader2无法从多播中看到数据。

I am concerned that the above will not be the case as in my testing using non source specific multicast an IP_ADD_MEMBERSHIP has global effect. So reader2's socket sees data because it is bound to the unique multicast address which has been joined to an interface seeing data. The info at this link under "Joining a Multicast" matches up with my observations.

我担心的是,在我的测试中,使用非源特定组播一个IP_ADD_MEMBERSHIP会有全局影响。所以reader2的套接字可以看到数据,因为它被绑定到唯一的多播地址,这个地址已经被连接到一个可以看到数据的接口。在“加入多播”的链接中的信息与我的观察相符。

It may well be that IP_ADD_SOURCE_MEMBERSHIP behaves differently to IP_ADD_MEMBERSHIP but the documentation is sparse and not specific in this regard.

IP_ADD_SOURCE_MEMBERSHIP的行为可能与IP_ADD_MEMBERSHIP不同,但文档很少,在这方面也不是很具体。

Specific questions:

具体问题:

  1. Is a multicast join using IP_ADD_SOURCE_MEMBERSHIP global i.e. will that cause any socket bind()'d to the multicast address to receive packets from that source.
  2. 是一个使用IP_ADD_SOURCE_MEMBERSHIP全局的多播连接,它将导致任何套接字绑定()'d到多播地址以接收来自该源的数据包。
  3. How is SSM supposed to be used in general? does it make sense to have one multicast address with N sources?
  4. SSM一般如何使用?有一个包含N个源的多播地址有意义吗?

I am inexperienced with network programming so please forgive any shortcomings in my understanding.

我对网络编程缺乏经验,请原谅我在理解上的不足。

Thanks for any assistance.

感谢任何帮助。

1 个解决方案

#1


2  

I've worked through this and after obtaining a copy of Unix Network Programming the behaviour at least seems clear and understandable.

我已经解决了这个问题,在获得了Unix网络编程的副本之后,这种行为至少看起来是清晰易懂的。

  1. The answer is yes all multicast joins are global whether they be SSM or otherwise. The reason for this is that the join actually takes effect a couple of layers down from a process issuing a join request. Basically, it tells the IP layer to accept multicast packets from the source specified and provide them to any process bound to the socket with the multicast address.

    答案是肯定的,所有的组播连接都是全局的,不管它们是SSM还是其他。这样做的原因是,连接实际上在发出连接请求的进程下面的几个层起作用。基本上,它告诉IP层从指定的源接收多播包,并将它们提供给绑定到多播地址的套接字的任何进程。

  2. SSM was actually introduced because of the limited address space of IPv4. When using multicast on the internet there are not nearly enough unique multicast addresses such that each person who want to use one could have a unique address. SSM pairs a source address with a multicast address which as a pair form a globally unique identifier i.e. shared multicast address e.g. 239.10.5.1 and source 192.168.1.5. So the reason that SSM exists is purely for this purpose of facilitating multicast in a limited address space. In the environment that our software is working in (Cisco) SSM is being used for redundancy and convenience of transmission, stacking multiple streams of data on the same IP:port combo and having downstream clients select the stream they want. This all works just fine until a given host wants access to more than one stream in the multicast, because they're all on the same multicast address all subscribed processes get all the data, and this is unavoidable due to the way the network stack works.

    由于IPv4的地址空间有限,所以实际上引入了SSM。在internet上使用多播时,几乎没有足够的唯一多播地址,因此想要使用多播的每个人都可以有一个唯一的地址。SSM将一个源地址与一个组播地址配对,组播地址作为一个全局唯一标识符,即共享的组播地址,如239.10.5.1和192.168.1.5。因此,SSM的存在纯粹是为了在有限的地址空间中实现多播的目的。在我们的软件正在(Cisco)中工作的环境中,SSM被用于冗余和方便传输,在同一个IP上堆叠多个数据流:端口组合和让下游客户选择他们想要的流。这一切都很好,直到给定的主机希望访问多播中的多个流,因为它们都位于相同的多播地址上,所有订阅的进程都获得所有数据,这是不可避免的,因为网络堆栈的工作方式。

  3. Final solution
    Now that the behaviour has been understood the solution is straightforward, but does require additional code in each running process. Each process must filter the incoming data from the multicast address and only read data from the source(s) that they are interested in. I had hoped that there was some "magic" in built into SSM to do this automatically, but there is not. recvfrom() already provides the senders address so doing this is relatively low cost.

    既然已经理解了行为,那么最终的解决方案就很简单了,但是在每个正在运行的进程中都需要额外的代码。每个进程必须过滤来自多播地址的传入数据,并且只从它们感兴趣的源读取数据。我曾希望在内置的SSM中有一些“魔法”可以自动完成,但是没有。recvfrom()已经提供了发送方地址,因此这样做的成本相对较低。

#1


2  

I've worked through this and after obtaining a copy of Unix Network Programming the behaviour at least seems clear and understandable.

我已经解决了这个问题,在获得了Unix网络编程的副本之后,这种行为至少看起来是清晰易懂的。

  1. The answer is yes all multicast joins are global whether they be SSM or otherwise. The reason for this is that the join actually takes effect a couple of layers down from a process issuing a join request. Basically, it tells the IP layer to accept multicast packets from the source specified and provide them to any process bound to the socket with the multicast address.

    答案是肯定的,所有的组播连接都是全局的,不管它们是SSM还是其他。这样做的原因是,连接实际上在发出连接请求的进程下面的几个层起作用。基本上,它告诉IP层从指定的源接收多播包,并将它们提供给绑定到多播地址的套接字的任何进程。

  2. SSM was actually introduced because of the limited address space of IPv4. When using multicast on the internet there are not nearly enough unique multicast addresses such that each person who want to use one could have a unique address. SSM pairs a source address with a multicast address which as a pair form a globally unique identifier i.e. shared multicast address e.g. 239.10.5.1 and source 192.168.1.5. So the reason that SSM exists is purely for this purpose of facilitating multicast in a limited address space. In the environment that our software is working in (Cisco) SSM is being used for redundancy and convenience of transmission, stacking multiple streams of data on the same IP:port combo and having downstream clients select the stream they want. This all works just fine until a given host wants access to more than one stream in the multicast, because they're all on the same multicast address all subscribed processes get all the data, and this is unavoidable due to the way the network stack works.

    由于IPv4的地址空间有限,所以实际上引入了SSM。在internet上使用多播时,几乎没有足够的唯一多播地址,因此想要使用多播的每个人都可以有一个唯一的地址。SSM将一个源地址与一个组播地址配对,组播地址作为一个全局唯一标识符,即共享的组播地址,如239.10.5.1和192.168.1.5。因此,SSM的存在纯粹是为了在有限的地址空间中实现多播的目的。在我们的软件正在(Cisco)中工作的环境中,SSM被用于冗余和方便传输,在同一个IP上堆叠多个数据流:端口组合和让下游客户选择他们想要的流。这一切都很好,直到给定的主机希望访问多播中的多个流,因为它们都位于相同的多播地址上,所有订阅的进程都获得所有数据,这是不可避免的,因为网络堆栈的工作方式。

  3. Final solution
    Now that the behaviour has been understood the solution is straightforward, but does require additional code in each running process. Each process must filter the incoming data from the multicast address and only read data from the source(s) that they are interested in. I had hoped that there was some "magic" in built into SSM to do this automatically, but there is not. recvfrom() already provides the senders address so doing this is relatively low cost.

    既然已经理解了行为,那么最终的解决方案就很简单了,但是在每个正在运行的进程中都需要额外的代码。每个进程必须过滤来自多播地址的传入数据,并且只从它们感兴趣的源读取数据。我曾希望在内置的SSM中有一些“魔法”可以自动完成,但是没有。recvfrom()已经提供了发送方地址,因此这样做的成本相对较低。