1 /* 2 * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.net; 27 28 import java.security.PrivilegedAction; 29 import java.security.Security; 30 31 public final class InetAddressCachePolicy { 32 33 // Controls the cache policy for successful lookups only 34 private static final String cachePolicyProp = "networkaddress.cache.ttl"; 35 private static final String cachePolicyPropFallback = 36 "sun.net.inetaddr.ttl"; 37 38 // Controls the cache policy for negative lookups only 39 private static final String negativeCachePolicyProp = 40 "networkaddress.cache.negative.ttl"; 41 private static final String negativeCachePolicyPropFallback = 42 "sun.net.inetaddr.negative.ttl"; 43 44 public static final int FOREVER = -1; 45 public static final int NEVER = 0; 46 47 /* default value for positive lookups */ 48 public static final int DEFAULT_POSITIVE = 30; 49 50 /* The Java-level namelookup cache policy for successful lookups: 51 * 52 * -1: caching forever 53 * any positive value: the number of seconds to cache an address for 54 * 55 * default value is forever (FOREVER), as we let the platform do the 56 * caching. For security reasons, this caching is made forever when 57 * a security manager is set. 58 */ 59 private static int cachePolicy = FOREVER; 60 61 /* The Java-level namelookup cache policy for negative lookups: 62 * 63 * -1: caching forever 64 * any positive value: the number of seconds to cache an address for 65 * 66 * default value is 0. It can be set to some other value for 67 * performance reasons. 68 */ 69 private static int negativeCachePolicy = NEVER; 70 71 /* 72 * Whether or not the cache policy for successful lookups was set 73 * using a property (cmd line). 74 */ 75 private static boolean propertySet; 76 77 /* 78 * Whether or not the cache policy for negative lookups was set 79 * using a property (cmd line). 80 */ 81 private static boolean propertyNegativeSet; 82 83 /* 84 * Initialize 85 */ 86 static { 87 Integer tmp = null; 88 89 try { 90 tmp = new Integer( 91 java.security.AccessController.doPrivileged ( 92 new PrivilegedAction<String>() { 93 public String run() { 94 return Security.getProperty(cachePolicyProp); 95 } 96 })); 97 } catch (NumberFormatException e) { 98 // ignore 99 } 100 if (tmp != null) { 101 cachePolicy = tmp.intValue(); 102 if (cachePolicy < 0) { 103 cachePolicy = FOREVER; 104 } 105 propertySet = true; 106 } else { 107 tmp = java.security.AccessController.doPrivileged 108 (new sun.security.action.GetIntegerAction(cachePolicyPropFallback)); 109 if (tmp != null) { 110 cachePolicy = tmp.intValue(); 111 if (cachePolicy < 0) { 112 cachePolicy = FOREVER; 113 } 114 propertySet = true; 115 } else { 116 /* No properties defined for positive caching. If there is no 117 * security manager then use the default positive cache value. 118 */ 119 if (System.getSecurityManager() == null) { 120 cachePolicy = DEFAULT_POSITIVE; 121 } 122 } 123 } 124 125 try { 126 tmp = new Integer( 127 java.security.AccessController.doPrivileged ( 128 new PrivilegedAction<String>() { 129 public String run() { 130 return Security.getProperty(negativeCachePolicyProp); 131 } 132 })); 133 } catch (NumberFormatException e) { 134 // ignore 135 } 136 137 if (tmp != null) { 138 negativeCachePolicy = tmp.intValue(); 139 if (negativeCachePolicy < 0) { 140 negativeCachePolicy = FOREVER; 141 } 142 propertyNegativeSet = true; 143 } else { 144 tmp = java.security.AccessController.doPrivileged 145 (new sun.security.action.GetIntegerAction(negativeCachePolicyPropFallback)); 146 if (tmp != null) { 147 negativeCachePolicy = tmp.intValue(); 148 if (negativeCachePolicy < 0) { 149 negativeCachePolicy = FOREVER; 150 } 151 propertyNegativeSet = true; 152 } 153 } 154 } 155 156 public static synchronized int get() { 157 return cachePolicy; 158 } 159 160 public static synchronized int getNegative() { 161 return negativeCachePolicy; 162 } 163 164 /** 165 * Sets the cache policy for successful lookups if the user has not 166 * already specified a cache policy for it using a 167 * command-property. 168 * @param newPolicy the value in seconds for how long the lookup 169 * should be cached 170 */ 171 public static synchronized void setIfNotSet(int newPolicy) { 172 /* 173 * When setting the new value we may want to signal that the 174 * cache should be flushed, though this doesn't seem strictly 175 * necessary. 176 */ 177 if (!propertySet) { 178 checkValue(newPolicy, cachePolicy); 179 cachePolicy = newPolicy; 180 } 181 } 182 183 /** 184 * Sets the cache policy for negative lookups if the user has not 185 * already specified a cache policy for it using a 186 * command-property. 187 * @param newPolicy the value in seconds for how long the lookup 188 * should be cached 189 */ 190 public static synchronized void setNegativeIfNotSet(int newPolicy) { 191 /* 192 * When setting the new value we may want to signal that the 193 * cache should be flushed, though this doesn't seem strictly 194 * necessary. 195 */ 196 if (!propertyNegativeSet) { 197 // Negative caching does not seem to have any security 198 // implications. 199 // checkValue(newPolicy, negativeCachePolicy); 200 negativeCachePolicy = newPolicy; 201 } 202 } 203 204 private static void checkValue(int newPolicy, int oldPolicy) { 205 /* 206 * If malicious code gets a hold of this method, prevent 207 * setting the cache policy to something laxer or some 208 * invalid negative value. 209 */ 210 if (newPolicy == FOREVER) 211 return; 212 213 if ((oldPolicy == FOREVER) || 214 (newPolicy < oldPolicy) || 215 (newPolicy < FOREVER)) { 216 217 throw new 218 SecurityException("can't make InetAddress cache more lax"); 219 } 220 } 221 }