mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-21 10:57:56 +00:00
7012768: InetAddress lookupTable leaks/deadlocks when using unsupported name service spi
Reviewed-by: alanb, michaelm
This commit is contained in:
parent
5eb8f2a9ef
commit
e615d63fad
@ -677,8 +677,7 @@ class InetAddress implements java.io.Serializable {
|
||||
|
||||
static InetAddressImpl impl;
|
||||
|
||||
private static HashMap<String, InetAddress[]> lookupTable
|
||||
= new HashMap<String, InetAddress[]>();
|
||||
private static final HashMap<String, Void> lookupTable = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Represents a cache entry
|
||||
@ -737,7 +736,7 @@ class InetAddress implements java.io.Serializable {
|
||||
|
||||
// As we iterate in insertion order we can
|
||||
// terminate when a non-expired entry is found.
|
||||
LinkedList<String> expired = new LinkedList<String>();
|
||||
LinkedList<String> expired = new LinkedList<>();
|
||||
long now = System.currentTimeMillis();
|
||||
for (String key : cache.keySet()) {
|
||||
CacheEntry entry = cache.get(key);
|
||||
@ -1227,43 +1226,45 @@ class InetAddress implements java.io.Serializable {
|
||||
// lookupTable and return null so the
|
||||
// following code would do a lookup itself.
|
||||
if ((addresses = checkLookupTable(host)) == null) {
|
||||
// This is the first thread which looks up the addresses
|
||||
// this host or the cache entry for this host has been
|
||||
// expired so this thread should do the lookup.
|
||||
for (NameService nameService : nameServices) {
|
||||
try {
|
||||
/*
|
||||
* Do not put the call to lookup() inside the
|
||||
* constructor. if you do you will still be
|
||||
* allocating space when the lookup fails.
|
||||
*/
|
||||
try {
|
||||
// This is the first thread which looks up the addresses
|
||||
// this host or the cache entry for this host has been
|
||||
// expired so this thread should do the lookup.
|
||||
for (NameService nameService : nameServices) {
|
||||
try {
|
||||
/*
|
||||
* Do not put the call to lookup() inside the
|
||||
* constructor. if you do you will still be
|
||||
* allocating space when the lookup fails.
|
||||
*/
|
||||
|
||||
addresses = nameService.lookupAllHostAddr(host);
|
||||
success = true;
|
||||
break;
|
||||
} catch (UnknownHostException uhe) {
|
||||
if (host.equalsIgnoreCase("localhost")) {
|
||||
InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
|
||||
addresses = local;
|
||||
addresses = nameService.lookupAllHostAddr(host);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
addresses = unknown_array;
|
||||
success = false;
|
||||
ex = uhe;
|
||||
} catch (UnknownHostException uhe) {
|
||||
if (host.equalsIgnoreCase("localhost")) {
|
||||
InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
|
||||
addresses = local;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
addresses = unknown_array;
|
||||
success = false;
|
||||
ex = uhe;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the addresses.
|
||||
cacheAddresses(host, addresses, success);
|
||||
// Delete the host from the lookupTable, and
|
||||
// notify all threads waiting for the monitor
|
||||
// for lookupTable.
|
||||
updateLookupTable(host);
|
||||
if (!success && ex != null)
|
||||
throw ex;
|
||||
// Cache the addresses.
|
||||
cacheAddresses(host, addresses, success);
|
||||
if (!success && ex != null)
|
||||
throw ex;
|
||||
} finally {
|
||||
// Delete host from the lookupTable and notify
|
||||
// all threads waiting on the lookupTable monitor.
|
||||
updateLookupTable(host);
|
||||
}
|
||||
}
|
||||
|
||||
return addresses;
|
||||
@ -1271,16 +1272,13 @@ class InetAddress implements java.io.Serializable {
|
||||
|
||||
|
||||
private static InetAddress[] checkLookupTable(String host) {
|
||||
// make sure addresses is null.
|
||||
InetAddress[] addresses = null;
|
||||
|
||||
synchronized (lookupTable) {
|
||||
// If the host isn't in the lookupTable, add it in the
|
||||
// lookuptable and return null. The caller should do
|
||||
// the lookup.
|
||||
if (lookupTable.containsKey(host) == false) {
|
||||
lookupTable.put(host, null);
|
||||
return addresses;
|
||||
return null;
|
||||
}
|
||||
|
||||
// If the host is in the lookupTable, it means that another
|
||||
@ -1298,10 +1296,11 @@ class InetAddress implements java.io.Serializable {
|
||||
// the host. This thread should retry to get the addresses
|
||||
// from the addressCache. If it doesn't get the addresses from
|
||||
// the cache, it will try to look up the addresses itself.
|
||||
addresses = getCachedAddresses(host);
|
||||
InetAddress[] addresses = getCachedAddresses(host);
|
||||
if (addresses == null) {
|
||||
synchronized (lookupTable) {
|
||||
lookupTable.put(host, null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
Simple1NameServiceDescriptor
|
||||
Simple2NameServiceDescriptor
|
||||
@ -1,2 +0,0 @@
|
||||
# name service provider descriptor
|
||||
SimpleNameServiceDescriptor
|
||||
@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2011, 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
|
||||
|
||||
Simple1NameServiceDescriptor
|
||||
Simple2NameServiceDescriptor
|
||||
@ -25,15 +25,17 @@
|
||||
* @test
|
||||
* @bug 4762344
|
||||
* @summary 2nd nameservice provider is non functional
|
||||
* @build B4762344 SimpleNameService Simple1NameServiceDescriptor Simple2NameServiceDescriptor
|
||||
* @run main/othervm -Dsun.net.spi.nameservice.provider.1=simple1,sun -Dsun.net.spi.nameservice.provider.2=simple2,sun B4762344
|
||||
* @compile -XDignore.symbol.file=true SimpleNameService.java
|
||||
* Simple1NameServiceDescriptor.java
|
||||
* Simple2NameServiceDescriptor.java
|
||||
* @run main/othervm -Dsun.net.spi.nameservice.provider.1=simple1,sun -Dsun.net.spi.nameservice.provider.2=simple2,sun Providers
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class B4762344 {
|
||||
public class Providers {
|
||||
private static String[][] hostnames = new String[][] {
|
||||
// both providers know this host, but with different address
|
||||
new String[] {"blade", "10.0.0.1"},
|
||||
46
jdk/test/sun/net/InetAddress/nameservice/deadlock/Hang.java
Normal file
46
jdk/test/sun/net/InetAddress/nameservice/deadlock/Hang.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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 7012768
|
||||
* @compile -XDignore.symbol.file=true ThrowingNameService.java
|
||||
* ThrowingNameServiceDescriptor.java
|
||||
* @run main/othervm/timeout=30 -Dsun.net.spi.nameservice.provider.1=throwing,sun Hang
|
||||
* @summary InetAddress lookupTable leaks/deadlocks when using unsupported
|
||||
* name service spi
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
public class Hang {
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
// 1st attempt - IllegalStateException caught below
|
||||
InetAddress.getByName("host.company.com");
|
||||
} catch (IllegalStateException e) { }
|
||||
|
||||
// 2nd attempt - Stuck here forever if bug exists
|
||||
InetAddress.getByName("host.company.com");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2011, 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.
|
||||
|
||||
ThrowingNameServiceDescriptor
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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.
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import sun.net.spi.nameservice.NameService;
|
||||
|
||||
public class ThrowingNameService implements NameService {
|
||||
static boolean firstCall = true;
|
||||
|
||||
@Override
|
||||
public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
|
||||
if (firstCall) {
|
||||
firstCall = false;
|
||||
// throw unchecked exception first time round
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
// return any valid address
|
||||
return new InetAddress[] { InetAddress.getLoopbackAddress() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostByAddr(byte[] addr) throws UnknownHostException {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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.
|
||||
*/
|
||||
|
||||
import sun.net.spi.nameservice.*;
|
||||
|
||||
public class ThrowingNameServiceDescriptor implements NameServiceDescriptor {
|
||||
public NameService createNameService() {
|
||||
return new ThrowingNameService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProviderName() {
|
||||
return "sun";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "throwing";
|
||||
}
|
||||
}
|
||||
@ -26,8 +26,8 @@
|
||||
* @summary Check that InetAddress doesn't continue to throw UHE
|
||||
* after the name service has recovered and the negative ttl
|
||||
* on the initial lookup has expired.
|
||||
*
|
||||
* @build CacheTest SimpleNameService SimpleNameServiceDescriptor
|
||||
* @compile -XDignore.symbol.file=true SimpleNameService.java
|
||||
* SimpleNameServiceDescriptor.java
|
||||
* @run main/othervm/timeout=200 -Dsun.net.spi.nameservice.provider.1=simple,sun CacheTest
|
||||
*/
|
||||
import java.net.InetAddress;
|
||||
@ -25,15 +25,15 @@
|
||||
* @bug 6442088
|
||||
* @summary Change default DNS caching behavior for code not running under
|
||||
* security manager.
|
||||
*
|
||||
* @build B6442088 SimpleNameService SimpleNameServiceDescriptor
|
||||
* @run main/othervm/timeout=200 -Dsun.net.inetaddr.ttl=20 -Dsun.net.spi.nameservice.provider.1=simple,sun B6442088
|
||||
* @compile -XDignore.symbol.file=true SimpleNameService.java
|
||||
* SimpleNameServiceDescriptor.java
|
||||
* @run main/othervm/timeout=200 -Dsun.net.inetaddr.ttl=20 -Dsun.net.spi.nameservice.provider.1=simple,sun DefaultCaching
|
||||
*/
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.Security;
|
||||
|
||||
public class B6442088 {
|
||||
public class DefaultCaching {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2011, 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.
|
||||
|
||||
SimpleNameServiceDescriptor # name service provider descriptor
|
||||
Loading…
x
Reference in New Issue
Block a user