-
Type:
CSR
-
Resolution: Approved
-
Priority:
P4
-
Component/s: core-libs
-
None
-
behavioral
-
low
-
The DatagramSocket::setOption and DatagramSocket::getOption methods were added in Java SE 9. Only the behavior of those two methods is changed, and only for StandardSocketOptions.IP_MULTICAST_LOOP.
-
Java API
-
SE
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
-