001: /*
002: * @(#)InetAddressCachePolicy.java 1.14 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.net;
029:
030: import java.net.InetAddress;
031: import java.security.PrivilegedAction;
032: import java.security.Security;
033:
034: public final class InetAddressCachePolicy {
035:
036: // Controls the cache policy for successful lookups only
037: private static final String cachePolicyProp = "networkaddress.cache.ttl";
038: private static final String cachePolicyPropFallback = "sun.net.inetaddr.ttl";
039:
040: // Controls the cache policy for negative lookups only
041: private static final String negativeCachePolicyProp = "networkaddress.cache.negative.ttl";
042: private static final String negativeCachePolicyPropFallback = "sun.net.inetaddr.negative.ttl";
043:
044: public static final int FOREVER = -1;
045: public static final int NEVER = 0;
046:
047: /* The Java-level namelookup cache policy for successful lookups:
048: *
049: * -1: caching forever
050: * any positive value: the number of seconds to cache an address for
051: *
052: * default value is forever (FOREVER), as we let the platform do the
053: * caching. For security reasons, this caching is made forever when
054: * a security manager is set.
055: */
056: private static int cachePolicy;
057:
058: /* The Java-level namelookup cache policy for negative lookups:
059: *
060: * -1: caching forever
061: * any positive value: the number of seconds to cache an address for
062: *
063: * default value is 0. It can be set to some other value for
064: * performance reasons.
065: */
066: private static int negativeCachePolicy;
067:
068: /*
069: * Whether or not the cache policy for successful lookups was set
070: * using a property (cmd line).
071: */
072: private static boolean set = false;
073:
074: /*
075: * Whether or not the cache policy for negative lookups was set
076: * using a property (cmd line).
077: */
078: private static boolean negativeSet = false;
079:
080: /*
081: * Initialize
082: */
083: static {
084:
085: set = false;
086: negativeSet = false;
087:
088: cachePolicy = FOREVER;
089: negativeCachePolicy = 0;
090:
091: Integer tmp = null;
092:
093: try {
094: tmp = new Integer((String) java.security.AccessController
095: .doPrivileged(new PrivilegedAction() {
096: public Object run() {
097: return Security
098: .getProperty(cachePolicyProp);
099: }
100: }));
101: } catch (NumberFormatException e) {
102: // ignore
103: }
104: if (tmp != null) {
105: cachePolicy = tmp.intValue();
106: if (cachePolicy < 0) {
107: cachePolicy = FOREVER;
108: }
109: set = true;
110: } else {
111: tmp = (Integer) java.security.AccessController
112: .doPrivileged(new sun.security.action.GetIntegerAction(
113: cachePolicyPropFallback));
114: if (tmp != null) {
115: cachePolicy = tmp.intValue();
116: if (cachePolicy < 0) {
117: cachePolicy = FOREVER;
118: }
119: set = true;
120: }
121: }
122:
123: try {
124: tmp = new Integer((String) java.security.AccessController
125: .doPrivileged(new PrivilegedAction() {
126: public Object run() {
127: return Security
128: .getProperty(negativeCachePolicyProp);
129: }
130: }));
131: } catch (NumberFormatException e) {
132: // ignore
133: }
134:
135: if (tmp != null) {
136: negativeCachePolicy = tmp.intValue();
137: if (negativeCachePolicy < 0) {
138: negativeCachePolicy = FOREVER;
139: }
140: negativeSet = true;
141: } else {
142: tmp = (Integer) java.security.AccessController
143: .doPrivileged(new sun.security.action.GetIntegerAction(
144: negativeCachePolicyPropFallback));
145: if (tmp != null) {
146: negativeCachePolicy = tmp.intValue();
147: if (negativeCachePolicy < 0) {
148: negativeCachePolicy = FOREVER;
149: }
150: negativeSet = true;
151: }
152: }
153: }
154:
155: public static synchronized int get() {
156: return cachePolicy;
157: }
158:
159: public static synchronized int getNegative() {
160: return negativeCachePolicy;
161: }
162:
163: /**
164: * Sets the cache policy for successful lookups if the user has not
165: * already specified a cache policy for it using a
166: * command-property.
167: * @param newPolicy the value in seconds for how long the lookup
168: * should be cached
169: */
170: public static synchronized void setIfNotSet(int newPolicy) {
171:
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:
178: if (!set) {
179: checkValue(newPolicy, cachePolicy);
180: cachePolicy = newPolicy;
181: }
182:
183: }
184:
185: /**
186: * Sets the cache policy for negative lookups if the user has not
187: * already specified a cache policy for it using a
188: * command-property.
189: * @param newPolicy the value in seconds for how long the lookup
190: * should be cached
191: */
192: public static synchronized void setNegativeIfNotSet(int newPolicy) {
193:
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:
200: if (!negativeSet) {
201: // Negative caching does not seem to have any security
202: // implications.
203: // checkValue(newPolicy, negativeCachePolicy);
204: negativeCachePolicy = newPolicy;
205: }
206: }
207:
208: private static void checkValue(int newPolicy, int oldPolicy) {
209:
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:
216: if (newPolicy == FOREVER)
217: return;
218:
219: if ((oldPolicy == FOREVER) || (newPolicy < oldPolicy)
220: || (newPolicy < FOREVER)) {
221:
222: throw new SecurityException(
223: "can't make InetAddress cache more lax");
224:
225: }
226: }
227: }
|