4
votes

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.

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

Steps

  1. Configure so that only Source1 is sending to the multicast address
  2. Start a reader (reader1) that binds to the multicast address and joins the multicast with ssm src as Source1 and interface as Interface1
  3. Observe that data is seen on reader1
  4. Do the same (reader2) but using Source2 and Interface2

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

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.

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.

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. How is SSM supposed to be used in general? does it make sense to have one multicast address with N sources?

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

Thanks for any assistance.

1

1 Answers

4
votes

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

  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.

  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.

  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.