Created
January 19, 2016 15:18
-
-
Save robinsk/47e95a7181180bd620cb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 1998, 2010, 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. Oracle designates this | |
* particular file as subject to the "Classpath" exception as provided | |
* by Oracle in the LICENSE file that accompanied this code. | |
* | |
* 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. | |
*/ | |
package sun.net; | |
import java.security.PrivilegedAction; | |
import java.security.Security; | |
public final class InetAddressCachePolicy { | |
// Controls the cache policy for successful lookups only | |
private static final String cachePolicyProp = "networkaddress.cache.ttl"; | |
private static final String cachePolicyPropFallback = | |
"sun.net.inetaddr.ttl"; | |
// Controls the cache policy for negative lookups only | |
private static final String negativeCachePolicyProp = | |
"networkaddress.cache.negative.ttl"; | |
private static final String negativeCachePolicyPropFallback = | |
"sun.net.inetaddr.negative.ttl"; | |
public static final int FOREVER = -1; | |
public static final int NEVER = 0; | |
/* default value for positive lookups */ | |
public static final int DEFAULT_POSITIVE = 30; | |
/* The Java-level namelookup cache policy for successful lookups: | |
* | |
* -1: caching forever | |
* any positive value: the number of seconds to cache an address for | |
* | |
* default value is forever (FOREVER), as we let the platform do the | |
* caching. For security reasons, this caching is made forever when | |
* a security manager is set. | |
*/ | |
private static int cachePolicy = FOREVER; | |
/* The Java-level namelookup cache policy for negative lookups: | |
* | |
* -1: caching forever | |
* any positive value: the number of seconds to cache an address for | |
* | |
* default value is 0. It can be set to some other value for | |
* performance reasons. | |
*/ | |
private static int negativeCachePolicy = NEVER; | |
/* | |
* Whether or not the cache policy for successful lookups was set | |
* using a property (cmd line). | |
*/ | |
private static boolean propertySet; | |
/* | |
* Whether or not the cache policy for negative lookups was set | |
* using a property (cmd line). | |
*/ | |
private static boolean propertyNegativeSet; | |
/* | |
* Initialize | |
*/ | |
static { | |
Integer tmp = null; | |
try { | |
tmp = new Integer( | |
java.security.AccessController.doPrivileged ( | |
new PrivilegedAction<String>() { | |
public String run() { | |
return Security.getProperty(cachePolicyProp); | |
} | |
})); | |
} catch (NumberFormatException e) { | |
// ignore | |
} | |
if (tmp != null) { | |
cachePolicy = tmp.intValue(); | |
if (cachePolicy < 0) { | |
cachePolicy = FOREVER; | |
} | |
propertySet = true; | |
} else { | |
tmp = java.security.AccessController.doPrivileged | |
(new sun.security.action.GetIntegerAction(cachePolicyPropFallback)); | |
if (tmp != null) { | |
cachePolicy = tmp.intValue(); | |
if (cachePolicy < 0) { | |
cachePolicy = FOREVER; | |
} | |
propertySet = true; | |
} else { | |
/* No properties defined for positive caching. If there is no | |
* security manager then use the default positive cache value. | |
*/ | |
if (System.getSecurityManager() == null) { | |
cachePolicy = DEFAULT_POSITIVE; | |
} | |
} | |
} | |
try { | |
tmp = new Integer( | |
java.security.AccessController.doPrivileged ( | |
new PrivilegedAction<String>() { | |
public String run() { | |
return Security.getProperty(negativeCachePolicyProp); | |
} | |
})); | |
} catch (NumberFormatException e) { | |
// ignore | |
} | |
if (tmp != null) { | |
negativeCachePolicy = tmp.intValue(); | |
if (negativeCachePolicy < 0) { | |
negativeCachePolicy = FOREVER; | |
} | |
propertyNegativeSet = true; | |
} else { | |
tmp = java.security.AccessController.doPrivileged | |
(new sun.security.action.GetIntegerAction(negativeCachePolicyPropFallback)); | |
if (tmp != null) { | |
negativeCachePolicy = tmp.intValue(); | |
if (negativeCachePolicy < 0) { | |
negativeCachePolicy = FOREVER; | |
} | |
propertyNegativeSet = true; | |
} | |
} | |
} | |
public static synchronized int get() { | |
return cachePolicy; | |
} | |
public static synchronized int getNegative() { | |
return negativeCachePolicy; | |
} | |
/** | |
* Sets the cache policy for successful lookups if the user has not | |
* already specified a cache policy for it using a | |
* command-property. | |
* @param newPolicy the value in seconds for how long the lookup | |
* should be cached | |
*/ | |
public static synchronized void setIfNotSet(int newPolicy) { | |
/* | |
* When setting the new value we may want to signal that the | |
* cache should be flushed, though this doesn't seem strictly | |
* necessary. | |
*/ | |
if (!propertySet) { | |
checkValue(newPolicy, cachePolicy); | |
cachePolicy = newPolicy; | |
} | |
} | |
/** | |
* Sets the cache policy for negative lookups if the user has not | |
* already specified a cache policy for it using a | |
* command-property. | |
* @param newPolicy the value in seconds for how long the lookup | |
* should be cached | |
*/ | |
public static synchronized void setNegativeIfNotSet(int newPolicy) { | |
/* | |
* When setting the new value we may want to signal that the | |
* cache should be flushed, though this doesn't seem strictly | |
* necessary. | |
*/ | |
if (!propertyNegativeSet) { | |
// Negative caching does not seem to have any security | |
// implications. | |
// checkValue(newPolicy, negativeCachePolicy); | |
negativeCachePolicy = newPolicy; | |
} | |
} | |
private static void checkValue(int newPolicy, int oldPolicy) { | |
/* | |
* If malicious code gets a hold of this method, prevent | |
* setting the cache policy to something laxer or some | |
* invalid negative value. | |
*/ | |
if (newPolicy == FOREVER) | |
return; | |
if ((oldPolicy == FOREVER) || | |
(newPolicy < oldPolicy) || | |
(newPolicy < FOREVER)) { | |
throw new | |
SecurityException("can't make InetAddress cache more lax"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment