8056264: Multicast support improvements
Summary: avoid passing a null ifname string to GetStringUTFChars native fn calls within a NetworkInterface method call flows
Reviewed-by: chegar, alanb
--- a/jdk/src/java.base/share/classes/java/net/MulticastSocket.java Thu Sep 11 10:12:33 2014 -0700
+++ b/jdk/src/java.base/share/classes/java/net/MulticastSocket.java Fri Sep 12 16:11:40 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2014, 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
@@ -569,7 +569,7 @@
public NetworkInterface getNetworkInterface() throws SocketException {
NetworkInterface ni
= (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
- if (ni.getIndex() == 0) {
+ if ((ni.getIndex() == 0) || (ni.getIndex() == -1)) {
InetAddress[] addrs = new InetAddress[1];
addrs[0] = InetAddress.anyLocalAddress();
return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
--- a/jdk/src/java.base/unix/native/libnet/NetworkInterface.c Thu Sep 11 10:12:33 2014 -0700
+++ b/jdk/src/java.base/unix/native/libnet/NetworkInterface.c Fri Sep 12 16:11:40 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -274,7 +274,6 @@
if (index <= 0) {
return NULL;
}
-
ifs = enumInterfaces(env);
if (ifs == NULL) {
return NULL;
@@ -551,9 +550,14 @@
jboolean isCopy;
int ret = -1;
int sock;
- const char* name_utf;
+ const char* name_utf = NULL;
- name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+ if (name != NULL) {
+ name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+ } else {
+ JNU_ThrowNullPointerException(env, "network interface name is NULL");
+ return ret;
+ }
if (name_utf == NULL) {
if (!(*env)->ExceptionCheck(env))
JNU_ThrowOutOfMemoryError(env, NULL);
@@ -581,7 +585,13 @@
const char* name_utf;
int flags = 0;
- name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+ if (name != NULL) {
+ name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+ } else {
+ JNU_ThrowNullPointerException(env, "network interface name is NULL");
+ return -1;
+ }
+
if (name_utf == NULL) {
if (!(*env)->ExceptionCheck(env))
JNU_ThrowOutOfMemoryError(env, NULL);
@@ -1063,6 +1073,7 @@
*/
#ifdef AF_INET6
+// unused arg ifname and struct if2
static int openSocketWithFallback(JNIEnv *env, const char *ifname){
int sock;
struct ifreq if2;
@@ -1453,9 +1464,14 @@
static int getMTU(JNIEnv *env, int sock, const char *ifname) {
struct ifreq if2;
+ memset((char *) &if2, 0, sizeof(if2));
- memset((char *) &if2, 0, sizeof(if2));
- strcpy(if2.ifr_name, ifname);
+ if (ifname != NULL) {
+ strcpy(if2.ifr_name, ifname);
+ } else {
+ JNU_ThrowNullPointerException(env, "network interface name is NULL");
+ return -1;
+ }
if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
--- a/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Thu Sep 11 10:12:33 2014 -0700
+++ b/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Fri Sep 12 16:11:40 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -62,7 +62,6 @@
#include "jvm.h"
#include "jni_util.h"
#include "net_util.h"
-
#include "java_net_SocketOptions.h"
#include "java_net_PlainDatagramSocketImpl.h"
#include "java_net_NetworkInterface.h"
@@ -83,6 +82,7 @@
extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him);
extern int getDefaultScopeID(JNIEnv *env);
+
/*
* Returns a java.lang.Integer based on 'i'
*/
@@ -1447,10 +1447,12 @@
static jmethodID ni_ctrID;
static jfieldID ni_indexID;
static jfieldID ni_addrsID;
+ static jfieldID ni_nameID;
jobjectArray addrArray;
jobject addr;
jobject ni;
+ jobject ni_name;
struct in_addr in;
struct in_addr *inP = ∈
@@ -1500,6 +1502,8 @@
ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
"[Ljava/net/InetAddress;");
CHECK_NULL_RETURN(ni_addrsID, NULL);
+ ni_nameID = (*env)->GetFieldID(env, c,"name", "Ljava/lang/String;");
+ CHECK_NULL_RETURN(ni_nameID, NULL);
ni_class = (*env)->NewGlobalRef(env, c);
CHECK_NULL_RETURN(ni_class, NULL);
}
@@ -1521,6 +1525,10 @@
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;
}
@@ -1537,14 +1545,16 @@
static jfieldID ni_indexID;
static jfieldID ni_addrsID;
static jclass ia_class;
+ static jfieldID ni_nameID;
static jmethodID ia_anyLocalAddressID;
- int index;
+ int index = 0;
socklen_t len = sizeof(index);
jobjectArray addrArray;
jobject addr;
jobject ni;
+ jobject ni_name;
if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
(char*)&index, &len) < 0) {
@@ -1573,6 +1583,8 @@
"anyLocalAddress",
"()Ljava/net/InetAddress;");
CHECK_NULL_RETURN(ia_anyLocalAddressID, NULL);
+ ni_nameID = (*env)->GetFieldID(env, c,"name", "Ljava/lang/String;");
+ CHECK_NULL_RETURN(ni_nameID, NULL);
ni_class = (*env)->NewGlobalRef(env, c);
CHECK_NULL_RETURN(ni_class, NULL);
}
@@ -1633,6 +1645,10 @@
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;
}
#endif