8234148: DatagramSocket.setOption/getOption/supportedOption should support multicast options

Fix adds multicast socket options to DatagramSocket

Reviewed-by: alanb, dfuchs, vtewari
This commit is contained in:
Patrick Concannon 2019-12-09 14:25:37 +00:00
parent 3f259d8e3a
commit 22e26b2a81
4 changed files with 83 additions and 38 deletions
src/java.base
test/jdk/java/net

@ -404,22 +404,8 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
ExtendedSocketOptions.getInstance();
private static final Set<SocketOption<?>> datagramSocketOptions = datagramSocketOptions();
private static final Set<SocketOption<?>> multicastSocketOptions = multicastSocketOptions();
private static Set<SocketOption<?>> datagramSocketOptions() {
HashSet<SocketOption<?>> options = new HashSet<>();
options.add(StandardSocketOptions.SO_SNDBUF);
options.add(StandardSocketOptions.SO_RCVBUF);
options.add(StandardSocketOptions.SO_REUSEADDR);
options.add(StandardSocketOptions.SO_BROADCAST);
options.add(StandardSocketOptions.IP_TOS);
if (isReusePortAvailable())
options.add(StandardSocketOptions.SO_REUSEPORT);
options.addAll(ExtendedSocketOptions.datagramSocketOptions());
return Collections.unmodifiableSet(options);
}
private static Set<SocketOption<?>> multicastSocketOptions() {
HashSet<SocketOption<?>> options = new HashSet<>();
options.add(StandardSocketOptions.SO_SNDBUF);
options.add(StandardSocketOptions.SO_RCVBUF);
@ -437,9 +423,6 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
@Override
protected Set<SocketOption<?>> supportedOptions() {
if (isMulticast)
return multicastSocketOptions;
else
return datagramSocketOptions;
}

@ -25,9 +25,14 @@
package java.net;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.JavaIOFileDescriptorAccess;
import sun.net.ext.ExtendedSocketOptions;
/**
* This class defines the plain DatagramSocketImpl that is used on
* Windows platforms greater than or equal to Windows Vista. These
@ -230,6 +235,19 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
return returnValue;
}
@Override
protected Set<SocketOption<?>> supportedOptions() {
HashSet<SocketOption<?>> options = new HashSet<>();
options.add(StandardSocketOptions.SO_SNDBUF);
options.add(StandardSocketOptions.SO_RCVBUF);
options.add(StandardSocketOptions.SO_REUSEADDR);
options.add(StandardSocketOptions.SO_BROADCAST);
options.add(StandardSocketOptions.IP_TOS);
options.addAll(ExtendedSocketOptions.datagramSocketOptions());
return Collections.unmodifiableSet(options);
}
/* Multicast specific methods.
* Multicasting on a dual layer TCP/IP stack is always done with
* TwoStacksPlainDatagramSocketImpl. This is to overcome the lack

@ -0,0 +1,58 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8234148
* @library /test/lib
* @summary checks that the DatagramSocket supportedOptions set contains all
* MulticastSocket socket options
* @run testng SupportedOptionsCheck
*/
import jdk.test.lib.Platform;
import org.testng.annotations.Test;
import java.net.DatagramSocket;
import java.net.StandardSocketOptions;
import java.util.Set;
import static org.testng.Assert.assertTrue;
public class SupportedOptionsCheck {
@Test
public void checkMulticastOptionsAreReturned() throws Exception {
try (DatagramSocket ds = new DatagramSocket())
{
Set<?> options = ds.supportedOptions();
Set<?> multicastOptions = Set.of(
StandardSocketOptions.IP_MULTICAST_IF,
StandardSocketOptions.IP_MULTICAST_TTL,
StandardSocketOptions.IP_MULTICAST_LOOP);
if (!Platform.isWindows())
assertTrue(options.containsAll(multicastOptions));
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,8 @@
*/
import java.io.IOException;
import java.net.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Set;
import static java.lang.System.out;
import jdk.test.lib.net.IPSupport;
@ -54,39 +55,24 @@ public class SupportedOptionsSet {
static void first() throws IOException {
try (Socket s = new Socket();
ServerSocket ss = new ServerSocket();
DatagramSocket ds = new DatagramSocket();
MulticastSocket ms = new MulticastSocket()) {
ServerSocket ss = new ServerSocket())
{
Set<?> first = s.supportedOptions();
Set<?> second = ss.supportedOptions();
assertNotEqual(first, second,
"Socket and ServerSocket should have different options.");
first = ds.supportedOptions();
second = ms.supportedOptions();
assertNotEqual(first, second,
"DatagramSocket and MulticastSocket should have different options.");
}
}
/** Tests with the order of access to supportedOptions reversed. */
static void second() throws IOException {
try (ServerSocket ss = new ServerSocket();
Socket s = new Socket();
DatagramSocket ds = new DatagramSocket();
MulticastSocket ms = new MulticastSocket()) {
Socket s = new Socket())
{
Set<?> first = ss.supportedOptions();
Set<?> second = s.supportedOptions();
assertNotEqual(first, second,
"ServerSocket and Socket should have different options.");
first = ms.supportedOptions();
second = ds.supportedOptions();
assertNotEqual(first, second,
"MulticastSocket and DatagramSocket should have different options.");
}
}