• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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