mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-28 15:51:02 +00:00
8233307: MulticastSocket getOption(IP_MULTICAST_IF) returns interface when not set
The MulticastSocket method getOption has been changed to conform to the behavior described in StandardSocketOptions.IP_MULTICAST_IF. Reviewed-by: chegar, dfuchs
This commit is contained in:
parent
558aadf608
commit
55da7d34c9
@ -576,7 +576,7 @@ public class MulticastSocket extends DatagramSocket {
|
||||
public NetworkInterface getNetworkInterface() throws SocketException {
|
||||
NetworkInterface ni
|
||||
= (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
|
||||
if ((ni.getIndex() == 0) || (ni.getIndex() == -1)) {
|
||||
if (ni == null) {
|
||||
InetAddress[] addrs = new InetAddress[1];
|
||||
addrs[0] = InetAddress.anyLocalAddress();
|
||||
return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
|
||||
|
||||
@ -1494,25 +1494,7 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
|
||||
if (ni) {
|
||||
return ni;
|
||||
}
|
||||
|
||||
/*
|
||||
* The address doesn't appear to be bound at any known
|
||||
* NetworkInterface. Therefore we construct a NetworkInterface
|
||||
* with this address.
|
||||
*/
|
||||
ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
|
||||
CHECK_NULL_RETURN(ni, NULL);
|
||||
|
||||
(*env)->SetIntField(env, ni, ni_indexID, -1);
|
||||
addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL);
|
||||
CHECK_NULL_RETURN(addrArray, NULL);
|
||||
(*env)->SetObjectArrayElement(env, addrArray, 0, addr);
|
||||
(*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
|
||||
ni_name = (*env)->NewStringUTF(env, "");
|
||||
if (ni_name != NULL) {
|
||||
(*env)->SetObjectField(env, ni, ni_nameID, ni_name);
|
||||
}
|
||||
return ni;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1619,19 +1601,6 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
|
||||
if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
|
||||
return addr;
|
||||
}
|
||||
|
||||
ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
|
||||
CHECK_NULL_RETURN(ni, NULL);
|
||||
(*env)->SetIntField(env, ni, ni_indexID, -1);
|
||||
addrArray = (*env)->NewObjectArray(env, 1, ia_class, NULL);
|
||||
CHECK_NULL_RETURN(addrArray, NULL);
|
||||
(*env)->SetObjectArrayElement(env, addrArray, 0, addr);
|
||||
(*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
|
||||
ni_name = (*env)->NewStringUTF(env, "");
|
||||
if (ni_name != NULL) {
|
||||
(*env)->SetObjectField(env, ni, ni_nameID, ni_name);
|
||||
}
|
||||
return ni;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1691,7 +1691,6 @@ static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint
|
||||
static jfieldID ni_indexID;
|
||||
static jfieldID ni_addrsID;
|
||||
|
||||
jobjectArray addrArray;
|
||||
jobject addr;
|
||||
jobject ni;
|
||||
|
||||
@ -1749,19 +1748,7 @@ static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint
|
||||
if (ni) {
|
||||
return ni;
|
||||
}
|
||||
if (ipv4Mode) {
|
||||
ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
|
||||
CHECK_NULL_RETURN(ni, NULL);
|
||||
|
||||
(*env)->SetIntField(env, ni, ni_indexID, -1);
|
||||
addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL);
|
||||
CHECK_NULL_RETURN(addrArray, NULL);
|
||||
(*env)->SetObjectArrayElement(env, addrArray, 0, addr);
|
||||
(*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
|
||||
} else {
|
||||
ni = NULL;
|
||||
}
|
||||
return ni;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1898,26 +1885,6 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
|
||||
return netObject;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Multicast to any address - return anyLocalAddress
|
||||
* or a NetworkInterface with addrs[0] set to anyLocalAddress
|
||||
*/
|
||||
|
||||
addr = (*env)->CallStaticObjectMethod(env, ia_class, ia_anyLocalAddressID,
|
||||
NULL);
|
||||
if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
|
||||
return addr;
|
||||
}
|
||||
|
||||
ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
|
||||
CHECK_NULL_RETURN(ni, NULL);
|
||||
(*env)->SetIntField(env, ni, ni_indexID, -1);
|
||||
addrArray = (*env)->NewObjectArray(env, 1, ia_class, NULL);
|
||||
CHECK_NULL_RETURN(addrArray, NULL);
|
||||
(*env)->SetObjectArrayElement(env, addrArray, 0, addr);
|
||||
(*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
|
||||
return ni;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
147
test/jdk/java/net/NetworkInterface/NoSetNetworkInterface.java
Normal file
147
test/jdk/java/net/NetworkInterface/NoSetNetworkInterface.java
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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 8233307
|
||||
* @library /test/lib
|
||||
* @run main/othervm NoSetNetworkInterface
|
||||
* @run main/othervm -Djava.net.preferIPv4Stack=true NoSetNetworkInterface
|
||||
* @run main/othervm -Djava.net.preferIPv6Addresses=true NoSetNetworkInterface
|
||||
* @summary Check that methods that are used to set and get the NetworkInterface
|
||||
* for a MulticastSocket work as expected. This test also checks that getOption
|
||||
* returns null correctly when a NetworkInterface has not been set
|
||||
*/
|
||||
|
||||
import jdk.test.lib.NetworkConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.StandardSocketOptions;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class NoSetNetworkInterface {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
NetworkConfiguration nc = NetworkConfiguration.probe();
|
||||
|
||||
// check set and get methods work as expected
|
||||
nc.multicastInterfaces(true).forEach(ni -> {
|
||||
checkSetInterface(ni);
|
||||
checkSetNetworkInterface(ni);
|
||||
checkSetOption(ni);
|
||||
});
|
||||
|
||||
// Check that dummy NetworkInterface is returned when not set
|
||||
checkDummyNetworkInterface();
|
||||
}
|
||||
|
||||
public static void checkSetInterface(NetworkInterface ni) {
|
||||
try (MulticastSocket ms = new MulticastSocket()) {
|
||||
Optional<InetAddress> iAddr = ni.inetAddresses()
|
||||
.filter(Predicate.not(InetAddress::isAnyLocalAddress))
|
||||
.findFirst();
|
||||
if (iAddr.isPresent()) {
|
||||
ms.setInterface(iAddr.get());
|
||||
checkForCorrectNetworkInterface("setInterface", ms, ni);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkSetNetworkInterface(NetworkInterface ni) {
|
||||
try (MulticastSocket ms = new MulticastSocket()) {
|
||||
ms.setNetworkInterface(ni);
|
||||
checkForCorrectNetworkInterface("setNetworkInterface", ms, ni);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkSetOption(NetworkInterface ni) {
|
||||
try (MulticastSocket ms = new MulticastSocket()) {
|
||||
ms.setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
|
||||
checkForCorrectNetworkInterface("setOption", ms, ni);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkForCorrectNetworkInterface(String setterMethod,
|
||||
MulticastSocket ms,
|
||||
NetworkInterface ni) throws IOException {
|
||||
|
||||
// getInterface
|
||||
InetAddress testAddr = ms.getInterface();
|
||||
if (!ni.inetAddresses().anyMatch(i -> i.equals(testAddr))) {
|
||||
throw new RuntimeException(setterMethod + " != getInterface");
|
||||
}
|
||||
|
||||
// getNetworkInterface
|
||||
if (!ni.equals(ms.getNetworkInterface())) {
|
||||
throw new RuntimeException(setterMethod + " != getNetworkInterface");
|
||||
}
|
||||
|
||||
// getOption
|
||||
if (!ni.equals(ms.getOption(StandardSocketOptions.IP_MULTICAST_IF))) {
|
||||
throw new RuntimeException(setterMethod + " != getOption");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkDummyNetworkInterface() throws IOException {
|
||||
|
||||
try(MulticastSocket ms = new MulticastSocket()) {
|
||||
|
||||
// getOption with no Network Interface set
|
||||
NetworkInterface n0 = ms.getOption(StandardSocketOptions.IP_MULTICAST_IF);
|
||||
if (n0 != null) {
|
||||
throw new RuntimeException("NetworkInterface should be null");
|
||||
}
|
||||
|
||||
// getNetworkInterface with no Network Interface set
|
||||
NetworkInterface n1 = ms.getNetworkInterface();
|
||||
if (n1 == null) {
|
||||
throw new RuntimeException("getNetworkInterface() should not return null");
|
||||
} else if (!((n1.getName().equals("0.0.0.0") || n1.getName().equals("::"))
|
||||
&& (n1.getIndex() == 0)
|
||||
&& (n1.inetAddresses().count() == 1))) {
|
||||
|
||||
throw new RuntimeException("Dummy NetworkInterface not returned as expected");
|
||||
}
|
||||
|
||||
// getInterface with no Network Interface set
|
||||
InetAddress iaddr = ms.getInterface();
|
||||
if (iaddr == null) {
|
||||
throw new RuntimeException("getInterface() should not return null");
|
||||
} else if (!iaddr.isAnyLocalAddress()) {
|
||||
throw new RuntimeException("getInterface() should return anyLocalAddress");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user