blob: d84320067125ca810bfa02f669d1efb3240d1260 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.net.dns;
27
28import java.util.List;
29import java.util.LinkedList;
30import java.util.StringTokenizer;
31import java.io.BufferedReader;
32import java.io.FileReader;
33import java.io.IOException;
34
35/*
36 * An implementation of ResolverConfiguration for Solaris
37 * and Linux.
38 */
39
40public class ResolverConfigurationImpl
41 extends ResolverConfiguration
42{
43 // Lock helds whilst loading configuration or checking
44 private static Object lock = new Object();
45
46 // Time of last refresh.
47 private static long lastRefresh = -1;
48
49 // Cache timeout (300 seconds) - should be converted into property
50 // or configured as preference in the future.
51 private static final int TIMEOUT = 300000;
52
53 // Resolver options
54 private final Options opts;
55
56 // Parse /etc/resolv.conf to get the values for a particular
57 // keyword.
58 //
59 private LinkedList resolvconf(String keyword, int maxperkeyword, int maxkeywords) {
60 LinkedList ll = new LinkedList();
61
62 try {
63 BufferedReader in =
64 new BufferedReader(new FileReader("/etc/resolv.conf"));
65 String line;
66 while ((line = in.readLine()) != null) {
67 int maxvalues = maxperkeyword;
68 if (line.length() == 0)
69 continue;
70 if (line.charAt(0) == '#' || line.charAt(0) == ';')
71 continue;
72 if (!line.startsWith(keyword))
73 continue;
74 String value = line.substring(keyword.length());
75 if (value.length() == 0)
76 continue;
77 if (value.charAt(0) != ' ' && value.charAt(0) != '\t')
78 continue;
79 StringTokenizer st = new StringTokenizer(value, " \t");
80 while (st.hasMoreTokens()) {
81 String val = st.nextToken();
82 if (val.charAt(0) == '#' || val.charAt(0) == ';') {
83 break;
84 }
85 ll.add(val);
86 if (--maxvalues == 0) {
87 break;
88 }
89 }
90 if (--maxkeywords == 0) {
91 break;
92 }
93 }
94 in.close();
95 } catch (IOException ioe) {
96 // problem reading value
97 }
98
99 return ll;
100 }
101
102 private LinkedList searchlist;
103 private LinkedList nameservers;
104
105
106 // Load DNS configuration from OS
107
108 private void loadConfig() {
109 assert Thread.holdsLock(lock);
110
111 // check if cached settings have expired.
112 if (lastRefresh >= 0) {
113 long currTime = System.currentTimeMillis();
114 if ((currTime - lastRefresh) < TIMEOUT) {
115 return;
116 }
117 }
118
119 // get the name servers from /etc/resolv.conf
120 nameservers =
121 (LinkedList)java.security.AccessController.doPrivileged(
122 new java.security.PrivilegedAction() {
123 public Object run() {
124 // typically MAXNS is 3 but we've picked 5 here
125 // to allow for additional servers if required.
126 return resolvconf("nameserver", 1, 5);
127 } /* run */
128 });
129
130 // get the search list (or domain)
131 searchlist = getSearchList();
132
133 // update the timestamp on the configuration
134 lastRefresh = System.currentTimeMillis();
135 }
136
137
138 // obtain search list or local domain
139
140 private LinkedList getSearchList() {
141
142 LinkedList sl;
143
144 // first try the search keyword in /etc/resolv.conf
145
146 sl = (LinkedList)java.security.AccessController.doPrivileged(
147 new java.security.PrivilegedAction() {
148 public Object run() {
149 LinkedList ll;
150
151 // first try search keyword (max 6 domains)
152 ll = resolvconf("search", 6, 1);
153 if (ll.size() > 0) {
154 return ll;
155 }
156
157 return null;
158
159 } /* run */
160
161 });
162 if (sl != null) {
163 return sl;
164 }
165
166 // No search keyword so use local domain
167
168
169 // LOCALDOMAIN has absolute priority on Solaris
170
171 String localDomain = localDomain0();
172 if (localDomain != null && localDomain.length() > 0) {
173 sl = new LinkedList();
174 sl.add(localDomain);
175 return sl;
176 }
177
178 // try domain keyword in /etc/resolv.conf
179
180 sl = (LinkedList)java.security.AccessController.doPrivileged(
181 new java.security.PrivilegedAction() {
182 public Object run() {
183 LinkedList ll;
184
185 ll = resolvconf("domain", 1, 1);
186 if (ll.size() > 0) {
187 return ll;
188 }
189 return null;
190
191 } /* run */
192 });
193 if (sl != null) {
194 return sl;
195 }
196
197 // no local domain so try fallback (RPC) domain or
198 // hostname
199
200 sl = new LinkedList();
201 String domain = fallbackDomain0();
202 if (domain != null && domain.length() > 0) {
203 sl.add(domain);
204 }
205
206 return sl;
207 }
208
209
210 // ----
211
212 ResolverConfigurationImpl() {
213 opts = new OptionsImpl();
214 }
215
216 public List searchlist() {
217 synchronized (lock) {
218 loadConfig();
219
220 // List is mutable so return a shallow copy
221 return (List)searchlist.clone();
222 }
223 }
224
225 public List nameservers() {
226 synchronized (lock) {
227 loadConfig();
228
229 // List is mutable so return a shallow copy
230 return (List)nameservers.clone();
231 }
232 }
233
234 public Options options() {
235 return opts;
236 }
237
238
239 // --- Native methods --
240
241 static native String localDomain0();
242
243 static native String fallbackDomain0();
244
245 static {
246 java.security.AccessController.doPrivileged(
247 new sun.security.action.LoadLibraryAction("net"));
248 }
249
250}
251
252/**
253 * Implementation of {@link ResolverConfiguration.Options}
254 */
255class OptionsImpl extends ResolverConfiguration.Options {
256}