javasocketsroutesmulticastnetwork-interface

Router does not forward multicast packet across interfaces


My router has three network interfaces:

I have a program that sends and receives packets on a multicast address (I set it to 239.5.6.7) on port 10468.

For my tests I have two devices (one sender and one receiver) that exchange information. If both devices are connected to the same interface of the router (let's say, both connected to the 5GHz WiFi) then the devices will be able to communicate.

On the other hand, if the devices are on two different interfaces (one 5GHz and one Ethernet), packets will not be exchanged (as if the router does not forward multicast traffic to one interface to the others).

All three interfaces support multicast (examining traffic with WireShark shows that every host is able to join the multicast group), but it seems like the router is blocking this cross-interface exchange.

It really is a shitty router issue? Or I did something wrong on my end?

Both the sender and receiver communicate with the multicast group with all their interfaces (as long as they have a link-local IP address). getActiveInterfaces() is a method that gathers such interfaces and saves them in an array list.

Sender snippet (getActiveInterfaces() returns only the ethernet connection):

static final int port = 10468;
    public static void main(String[] args) {
        try {
            ArrayList<NetworkInterface> interfaces = getActiveInterfaces();
            // Initialize sockets
            ArrayList<MulticastSocket> sockets = new ArrayList<>(interfaces.size());
            for (NetworkInterface networkInterface : interfaces) {
                MulticastSocket socket = new MulticastSocket();
                socket.setOption(StandardSocketOptions.IP_MULTICAST_TTL, 1);
                socket.setNetworkInterface(networkInterface);
                sockets.add(socket);
            }

        InetSocketAddress group = new InetSocketAddress(InetAddress.getByName("239.5.6.7"), port);

        byte[] buf = new byte[128];
        String msg = "Hello";
        DatagramPacket toSend = new DatagramPacket(msg.getBytes(), msg.getBytes().length, group);

        while (true) {
            Thread.sleep(1000);
            for (MulticastSocket socket : sockets)
                socket.send(toSend);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
}

Receiver snippet (getActiveInterfaces() returns only the 2.4GHz wireless connection):

static final int port = 10468;
public static void main(String[] args) {
    try(MulticastSocket s = new MulticastSocket(port)) {
        InetSocketAddress group = new InetSocketAddress(InetAddress.getByName("239.5.6.7"), port);

        ArrayList<NetworkInterface> activeInterfaces = getActiveInterfaces();
        for (NetworkInterface networkInterface : activeInterfaces) {
            s.joinGroup(group, networkInterface);
        }

        DatagramPacket rec = new DatagramPacket(new byte[128], 128);

        while(true) {
            s.receive(rec);
            System.out.println(new String(rec.getData(), StandardCharsets.UTF_8).replaceAll("\0", ""));
        }

    }catch (Exception e) {
        e.printStackTrace();
    }
}

Solution

  • After some investigations, I came to a conclusion that this is a router issue.

    It seems that there is some sort of whitelisting going on.

    For example, packets sent to the reserved Local Control Block multicast addresses (224.0.0.1-224.0.0.255) do not have this issue. Well-known multicast IPs are also whitelisted (like 239.255.255.250, used for SSDP).

    Even changing to the next multicast address (239.255.255.249 or 239.255.255.251) leads to the same issue.

    The only solution I could come up with is to use one of these whitelisted addresses and to use a different port number (not one linked with the actual address).