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