9

This question is about sending and receiving multicasts inside the same host, while simultaneously sending it to other hosts.

Even after hours of googling, I have not been able to sort out, how multicast datagrams are routed within the same host..!

Here comes a detailed description of the problem:

Linux box "A" is cable-connected to a switch/router (let's call the switch/router as "R").

In linux box A, I have a process (A0) that sends UDP packets to multicast address "224.0.0.0", port 5000.

Likewise, in the same box A, I have two processes (A1 and A2), both connecting to 224.0.0.0, port 5000 and consuming UDP packets.

Now, how does the kernel in box A manage the routing?

So, A0 sends a datagram which is consumed by A1 and A2. Does such a datagram do a round-trip A --> R --> A ?

.. or is the kernel routing in "A" smart enough to avoid this unnecessary round-trip? (i.e. datagram is sent by A0 and consumed right away by A1 and A2, never leaving A).

Of course, one can ensure that multicast datagram never leave A, by creating and enforcing a loopback device for multicast:

sudo ifconfig lo multicast
sudo route add -net 224.0.0.0 netmask 240.0.0.0 dev lo

But now, if I want to consume the UDP datagram simultaneously in another linux box, say, "B", there is no way they arrive there.

So, ideally, (1) datagram consumed in A should never leave A (i.e. no round trip A --> R --> A), while (2) datagram consumed in B should go normally as A --> R --> B. I'd like to achieve these two things simultaneously.

Any way to achieve this, for example, with the "route" command ?

Sockets is processes A1 and A2 have the following flags set:

SO_REUSEADDR
SO_REUSEPORT

While I have checked that process A0 (the one that sends multicast datagram) has the following flag on:

IP_MULTICAST_LOOP
user207421
  • 305,947
  • 44
  • 307
  • 483
El Sampsa
  • 1,673
  • 3
  • 17
  • 33
  • 'Multicast stream' is a contradiction in terms, and the unit of UDP transmission is a datagram. – user207421 Oct 21 '15 at 23:48
  • Is it possible? Do you solve this task? – vinnitu Feb 24 '23 at 17:19
  • "Does such a datagram do a round-trip A --> R --> A" - Why haven't you just used tcpdump to look yourself if that is the case or not? To Answer that question, all you need to do is starting the multicasting, join the group and then look with tcpdump if the packets get echoed to you by R or if that never happens. Might be interesting to dig deeper into the kernel code and see how other systems are doing it but to just answer that one question, all you need is to have a quick look yourself. Other than that, what even was the question? – Mecki Feb 25 '23 at 01:15

3 Answers3

3

Looping back to local processes (local sockets) should work without adding a multicast route to lo. Just make sure you have a useful route set to some external interface. The packets will still be routed internally. (Linux does a lot of routing behind the scenes.)

You need IP_MULTICAST_LOOP, this looks good.

Did you properly join the multicast group in all processes? IP_ADD_MEMBERSHIP? Without this you get all kinds of bogus behavior.

You can look at the local routing table to see what Linux does locally to packets. It is usually far from trivial:

sudo ip route show table local

You can also look at the current multicast group memberships:

netstat -g

Does the output and the ref counts make sense in your case?

Johannes Overmann
  • 4,914
  • 22
  • 38
1

Firs config your network adapter:

ifconfig lo 127.0.0.1 netmask 224.0.0.0 up

Then follow below codes: /send/

gst-launch-1.0 -v imxv4l2videosrc device=/dev/video0 ! imxvpuenc_h264 bitrate=10000 ! rtph264pay ! udpsink host=224.0.0.0 port=5000 auto-multicast=true multicast-iface=lo force-ipv4=true sync=false &

/Receive/

gst-launch-1.0 udpsrc multicast-group=224.0.0.0 port=5000 auto-multicast=true multicast-iface=lo ! application/x-rtp ! rtph264depay ! h264parse ! imxvpudec ! imxipuvideosink framebuffer=/dev/fb0 sync=false &
gst-launch-1.0 udpsrc multicast-group=224.0.0.0 port=5000 auto-multicast=true multicast-iface=lo ! application/x-rtp ! rtph264depay ! h264parse ! imxvpudec ! imxipuvideosink framebuffer=/dev/fb2 sync=false &
0

From the IP man page of macOS, FreeBSD and OpenBSD (man ip):

If a multicast datagram is sent to a group to which the sending host itself belongs (on the outgoing interface), a copy of the datagram is, by default, looped back by the IP layer for local delivery. The IP_MULTICAST_LOOP option gives the sender explicit control over whether or not subsequent datagrams are looped back.

[...]

This option improves performance for applications that may have no more than one instance on a single host (such as a router demon), by eliminating the overhead of receiving their own transmissions. It should generally not be used by applications for which there may be more than one instance on a single host (such as a conferencing program) or for which the sender does not belong to the destination group (such as a time querying program).

The Linux man page is a bit less detailed (which really is an understatement):

Set or read a boolean integer argument that determines whether sent multicast packets should be looped back to the local sockets.

e.g. it does not mention if the "sending host" also must belong to the group, but I would expect it to follow the same behavior as BSD systems.

For the sake of completeness, let's check what Windows says:

For a socket that is joined to one or more multicast groups, this controls whether it will receive a copy of outgoing packets sent to those multicast groups via the selected multicast interface. By default, IP_MULTICAST_LOOP is enabled (value 1/TRUE), so sockets will receive matching multicast packets sent by the current machine. Disabling this option (by setting it to 0/FALSE) means that this socket will not receive multicasts sent from the local machine, even if the socket is open on the loopback interface.

This is not compatible with the POSIX version of IP_MULTICAST_LOOP— the option must be set on the receiving socket; while the POSIX option must be set on the sending socket.

The behavior is the same, so it will also function the same but what the second paragraph. As usual, Microsoft must ensure to be incompatible with the rest of thew world. But since it is also enabled by default, it usually will just work.

So to answer you question:

or is the kernel routing in "A" smart enough to avoid this unnecessary round-trip?

Yes, it is but it only behaves that way if IP_MULTICAST_LOOP is set; which is set by default on all systems. In that case each packet goes once A->A and once A->R from where it can go to other hosts (A->R->B). If that option is disabled, there is no loopback and then then packets really go A->R->A, which is desirable under some circumstances; see second part of the BSD man page.

The reason why operating systems must support such an option is because how multicast is handled on a layer 2 level. On a layer 2 level multicast packets are special broadcasts. On a layer 3 level a router may have no problem to forward a multicast packet to the same IP address it originated from (A->R->A), but multicast also works in a LAN that doesn't even have a router as long as all switches in the LAN support multicast or will otherwise fall back to using broadcast packets in that LAN. And here switches must prevent loops! So a switch will never forward a broadcast or multicast packet back to the same port from that it received that packet, as that would create a loop. In a LAN without a router, you have no chance to ever get back your own multicast packets without looping them back locally directly on the sender host.

Mecki
  • 125,244
  • 33
  • 244
  • 253