1 /* 2 * Copyright (c) 1998, 2010, 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 88 Integer tmp = java.security.AccessController.doPrivileged( 89 new PrivilegedAction<Integer>() { 90 public Integer run() { 91 try { 92 String tmpString = Security.getProperty(cachePolicyProp); 93 if (tmpString != null) { 94 return Integer.valueOf(tmpString); 95 } 96 } catch (NumberFormatException ignored) { 97 // Ignore 98 } 99 100 try { 101 String tmpString = System.getProperty(cachePolicyPropFallback); 102 if (tmpString != null) { 103 return Integer.decode(tmpString); 104 } 105 } catch (NumberFormatException ignored) { 106 // Ignore 107 } 108 return null; 109 } 110 }); 111 112 if (tmp != null) { 113 cachePolicy = tmp.intValue(); 114 if (cachePolicy < 0) { 115 cachePolicy = FOREVER; 116 } 117 propertySet = true; 118 } else { 119 /* No properties defined for positive caching. If there is no 120 * security manager then use the default positive cache value. 121 */ 122 if (System.getSecurityManager() == null) { 123 cachePolicy = DEFAULT_POSITIVE; 124 } 125 } 126 tmp = java.security.AccessController.doPrivileged ( 127 new PrivilegedAction<Integer>() { 128 public Integer run() { 129 try { 130 String tmpString = Security.getProperty(negativeCachePolicyProp); 131 if (tmpString != null) { 132 return Integer.valueOf(tmpString); 133 } 134 } catch (NumberFormatException ignored) { 135 // Ignore 136 } 137 138 try { 139 String tmpString = System.getProperty(negativeCachePolicyPropFallback); 140 if (tmpString != null) { 141 return Integer.decode(tmpString); 142 } 143 } catch (NumberFormatException ignored) { 144 // Ignore 145 } 146 return null; 147 } 148 }); 149 150 if (tmp != null) { 151 negativeCachePolicy = tmp.intValue(); 152 if (negativeCachePolicy < 0) { 153 negativeCachePolicy = FOREVER; 154 } 155 propertyNegativeSet = true; 156 } 157 } 158 get()159 public static synchronized int get() { 160 return cachePolicy; 161 } 162 getNegative()163 public static synchronized int getNegative() { 164 return negativeCachePolicy; 165 } 166 167 /** 168 * Sets the cache policy for successful lookups if the user has not 169 * already specified a cache policy for it using a 170 * command-property. 171 * @param newPolicy the value in seconds for how long the lookup 172 * should be cached 173 */ setIfNotSet(int newPolicy)174 public static synchronized void setIfNotSet(int newPolicy) { 175 /* 176 * When setting the new value we may want to signal that the 177 * cache should be flushed, though this doesn't seem strictly 178 * necessary. 179 */ 180 if (!propertySet) { 181 checkValue(newPolicy, cachePolicy); 182 cachePolicy = newPolicy; 183 } 184 } 185 186 /** 187 * Sets the cache policy for negative lookups if the user has not 188 * already specified a cache policy for it using a 189 * command-property. 190 * @param newPolicy the value in seconds for how long the lookup 191 * should be cached 192 */ setNegativeIfNotSet(int newPolicy)193 public static synchronized void setNegativeIfNotSet(int newPolicy) { 194 /* 195 * When setting the new value we may want to signal that the 196 * cache should be flushed, though this doesn't seem strictly 197 * necessary. 198 */ 199 if (!propertyNegativeSet) { 200 // Negative caching does not seem to have any security 201 // implications. 202 // checkValue(newPolicy, negativeCachePolicy); 203 negativeCachePolicy = newPolicy; 204 } 205 } 206 checkValue(int newPolicy, int oldPolicy)207 private static void checkValue(int newPolicy, int oldPolicy) { 208 /* 209 * If malicious code gets a hold of this method, prevent 210 * setting the cache policy to something laxer or some 211 * invalid negative value. 212 */ 213 if (newPolicy == FOREVER) 214 return; 215 216 if ((oldPolicy == FOREVER) || 217 (newPolicy < oldPolicy) || 218 (newPolicy < FOREVER)) { 219 220 throw new 221 SecurityException("can't make InetAddress cache more lax"); 222 } 223 } 224 } 225