Update -- Recent Improvements in handling this problem:
The problem described below is OS-specific. As of October 2008, recent or shortly upcoming releases of JBoss projects include code changes to work around the problem on Linux:
- JGroups 2.6.5 has a workaround for the issue for the UDP transport protocol.
- JGroups 2.6.6 will include a workaround for the MPING discovery protocol.
- JBoss AS 5.0.0.GA will include a workaround for the HA-JNDI service's automatic discovery feature.
Problem: Different clusters receive each others traffic
There is a bug in various OSs which lets clusters with different multicast addresses but the same ports
receive each others traffic, e.g.
Appl A1 joins 220.127.116.11:7500
Appl A2 joins 18.104.22.168:7500
A1 and A2 receive each others traffic
Solution: to separate traffic, pick diffent multicast addresses and ports !
The test below discussed below has shown the problem on several different distributions of Linux as well as HPUX and Mac OSX. There is an entry in the Red Hat bugzilla database for the issue in the Red Hat distributions of Linux.
Note that there is a Sun bug database entry related to this issue, but we have been able to reproduce it with non-Sun JDKs and with a test written in C. Our understanding is it is an OS issue.
Here is a description of why binding only to a port doesn't work on the Linux kernel.
Checking for the existence of this problem
Attached is promiscuoustraffic.jar which contains a simple test class that will show whether the problem exists or not for a particular JDK / OS combo. To run the test, simply download the jar, open a command prompt in the dir where the jar is, and:
java -jar promiscuoustraffic.jar
A successful outcome looks like this:
c:\temp>java -jar promiscuoustraffic.jar Binding mcast socket to port:64000 Binding mcast socket to port:64000 Listening on address /22.214.171.124 Listening on address /126.96.36.199 Sending 'Hello' on /188.8.131.52:64000 /184.108.40.206:64000 -- Received Hello Good news. Did not detect the Promiscuous Traffic problem.
If the "promiscuous traffic" problem exists, the outcome will be more like this:
[brian@host brian]$ java -jar promiscuoustraffic.jar Binding mcast socket to port:64000 Binding mcast socket to port:64000 Listening on address /220.127.116.11 Listening on address /18.104.22.168 Sending 'Hello' on /22.214.171.124:64000 /126.96.36.199:64000 -- Received Hello /188.8.131.52:64000 -- Received Hello Bad news. Detected the Promiscuous Traffic problem. Received Hello on undesired address /184.108.40.206
If you want to tailor the test to your local environment, there are a number of arguments you can pass to main. You can pass zero or more of the following; not all need be present, but none can be skipped if subsequent values are desired. Default values are in parentheses:
Interface sender should bind to (machine default interface, i.e. value returned by InetAddress.getLocalHost())
Interface receivers should bind to (same interface as sender)
Multicast address on which packets will be sent (220.127.116.11)
Multicast address on which receipt of packet means promiscuous traffic problem is present (18.104.22.168)
Multicast port (64000)
TTL of multicast packet (0)
- Whether or not to bind multicast socket to a socket address formed from multicast address and port (true) or multicast port only (false)
An example with all options specified:
java -jar promiscuoustraffic.jar 192.168.0.100 192.168.0.101 22.214.171.124 126.96.36.199 55555 1 false
If you are interested in how this test works, the jar includes the source code in the same dir as the classes. Basically it opens sender and receiver sockets on a multicast address, and another receiver on a different multicast address but with the same port. Send a packet; confirm the expected receiver got it and the one with the different address didn't.
Option 7 controls whether the multicast socket is bound to a socket formed from the multicast address and port (using the constructor MulticastSocket(SocketAddress bindAddress)) or whether it is bound to the multicast port only (using the constructor MulticastSocket(int port)).
Here is more information related to cross talking.