Summary
MulticastSocket::getOption(StandardSocketOption.IP_LOOPBACK_MODE)
and MulticastSocket::setOption(StandardSocketOption.IP_LOOPBACK_MODE, Boolean value)
invert the value of IP_MULTICAST_LOOP
Problem
MulticastSocket
delegates getting and setting of options to a wrapped DatagramSocketImpl
implementing SocketOptions
; This implementation is not directly accessible to the code calling of MulticastSocket
.
Before JDK-8036979 was implemented, options could only be set by calling the legacy and ad-hoc option-specific getters and setters defined by MulticastSocket
/DatagramSocket
. For getting and setting the IP_MULTICAST_LOOP
option, MulticastSocket
defined an ad-hoc getLoopbackMode
/setLoopbackMode
getter/setter pair.
However the parameter passed to setLoopbackMode
is a boolean named disable
which when true
is specified to disable loopback mode. Similarly, getLoopbackMode
is specified to return true when loopback mode is disabled. This was implemented by directly passing/returning that value to the legacy DatagramSocketImpl::setOption
/getOption
methods inherited from the SocketOptions
interface. These legacy methods defined by the SocketOptions
interface take an int
constant to identify which option is get/set - (and not a SocketOption object).
When JDK-8036979 was implemented in JDK 9 to add public getOption
/setOption
methods to DatagramSocket
(and by extension to MulticastSocket
), a bridge was implemented in the internal AbstractPlainDatagramSocketImpl class to transform a call from the new DatagramSocket/MulticastSocket
getOption
/setOption
into a call to DatagramSocketImpl::getOption
/setOption
. However - that fact that true
had always been passed to disable loopback mode instead of enabling it as is defined by the newer StandardSocketOptions.IP_MULTICAST_LOOP
SocketOption
was overlooked.
In summary we ended up with:
(1) MulticastSocket::setLoopbackMode(true) => calls (2) with true => disable loopback
(2) DatagramSocketImpl::setOption(SocketOptions.IP_MULTICAST_LOOP, true) => disable loopback
(3) MulticastSocket::setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true) => calls(2) with true => disable loopback
This is this last behavior (3) which is problematic, as StandardSocketOptions.IP_MULTICAST_LOOP
specifies that true
means the option is enabled.
Solution
The solution is to change the behavior of MulticastSocket::setOption(StandardSocketOptions.IP_MULTICAST_LOOP, value)
and MulticastSocket::getOption(StandardSocketOptions.IP_MULTICAST_LOOP)
to conform to the specification of StandardSocketOptions.IP_MULTICAST_LOOP
.
The behavior of the other methods (MulticastSocket::set(get)LoopbackMode
and DatagramSocketImpl
implementation of the legacy SocketOptions
interface) are left unchanged.
In summary we want:
(1) MulticastSocket::setLoopbackMode(true) => calls (2) with true => disable loopback
(2) DatagramSocketImpl::setOption(SocketOptions.IP_MULTICAST_LOOP, true) => disable loopback
(3) MulticastSocket::setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true) => calls(2) with false => enable loopback
Specification
There is no specification change - only behavioral.
For convenience a webrev can be seen there: http://cr.openjdk.java.net/~dfuchs/webrev_8233296/webrev.00/
- csr of
-
JDK-8233296 MulticastSocket getOption/setOption inverts the value of IP_MULTICAST_LOOP
-
- Closed
-