8168840: InetAddress.getByName() throws java.net.UnknownHostException no such interface when used with virtual interfaces on Solaris
authorvtewari
Fri, 23 Dec 2016 13:53:22 +0530
changeset 42945 1a9931e1c0f5
parent 42944 641db7ce5057
child 42946 955f6bc7abfd
8168840: InetAddress.getByName() throws java.net.UnknownHostException no such interface when used with virtual interfaces on Solaris Reviewed-by: chegar, clanger
jdk/src/java.base/unix/native/libnet/NetworkInterface.c
jdk/test/java/net/NetworkInterface/SubNetworkInterfaceTest.java
--- a/jdk/src/java.base/unix/native/libnet/NetworkInterface.c	Fri Dec 23 07:54:05 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/NetworkInterface.c	Fri Dec 23 13:53:22 2016 +0530
@@ -219,6 +219,8 @@
     netif *ifs, *curr;
     jboolean isCopy;
     const char* name_utf;
+    char *colonP;
+    char searchName[IFNAMESIZE];
     jobject obj = NULL;
 
     if (name != NULL) {
@@ -239,15 +241,33 @@
         return NULL;
     }
 
-    // search the list of interfaces based on name
+    // search the list of interfaces based on name,
+    // if it is virtual sub interface search with parent first.
+    strncpy(searchName, name_utf, IFNAMESIZE);
+    searchName[IFNAMESIZE - 1] = '\0';
+    colonP = strchr(searchName, ':');
+    if (colonP != NULL) {
+        *colonP = '\0';
+    }
     curr = ifs;
     while (curr != NULL) {
-        if (strcmp(name_utf, curr->name) == 0) {
+        if (strcmp(searchName, curr->name) == 0) {
             break;
         }
         curr = curr->next;
     }
 
+    // search the child list
+    if (colonP != NULL && curr != NULL) {
+        curr = curr->childs;
+        while (curr != NULL) {
+            if (strcmp(name_utf, curr->name) == 0) {
+                break;
+            }
+            curr = curr->next;
+        }
+    }
+
     // if found create a NetworkInterface
     if (curr != NULL) {
         obj = createNetworkInterface(env, curr);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/NetworkInterface/SubNetworkInterfaceTest.java	Fri Dec 23 13:53:22 2016 +0530
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, 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 8168840
+ * @summary InetAddress.getByName() throws java.net.UnknownHostException no such
+ * interface when used with virtual interfaces on Solaris
+ */
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Collections;
+import java.util.Enumeration;
+
+public class SubNetworkInterfaceTest {
+
+    public static void main(String args[]) throws SocketException, UnknownHostException {
+        Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
+        for (NetworkInterface netIf : Collections.list(nets)) {
+            doReverseLookup(netIf);
+        }
+    }
+
+    static void doReverseLookup(NetworkInterface netIf) throws SocketException, UnknownHostException {
+        for (NetworkInterface subIf : Collections.list(netIf.getSubInterfaces())) {
+            Enumeration<InetAddress> subInetAddresses = subIf.getInetAddresses();
+            while (subInetAddresses != null && subInetAddresses.hasMoreElements()) {
+                InetAddress inetAddress = subInetAddresses.nextElement();
+                String reversalString = inetAddress.getHostAddress();
+                //should not throw UHE in case of virtual sub interface
+                InetAddress.getByName(reversalString);
+            }
+        }
+    }
+}