001: /*
002: * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.net.dns;
027:
028: import java.util.List;
029: import java.util.LinkedList;
030: import java.util.StringTokenizer;
031: import java.io.IOException;
032:
033: /*
034: * An implementation of sun.net.ResolverConfiguration for Windows.
035: */
036:
037: public class ResolverConfigurationImpl extends ResolverConfiguration {
038: // Lock helds whilst loading configuration or checking
039: private static Object lock = new Object();
040:
041: // Resolver options
042: private final Options opts;
043:
044: // Addreses have changed
045: private static boolean changed = false;
046:
047: // Time of last refresh.
048: private static long lastRefresh = -1;
049:
050: // Cache timeout (120 seconds) - should be converted into property
051: // or configured as preference in the future.
052: private static final int TIMEOUT = 120000;
053:
054: // DNS suffix list and name servers populated by native method
055: private static String os_searchlist;
056: private static String os_nameservers;
057:
058: // Cached lists
059: private static LinkedList searchlist;
060: private static LinkedList nameservers;
061:
062: // Parse string that consists of token delimited by space or commas
063: // and return LinkedHashMap
064: private LinkedList stringToList(String str) {
065: LinkedList ll = new LinkedList();
066:
067: // comma and space are valid delimites
068: StringTokenizer st = new StringTokenizer(str, ", ");
069: while (st.hasMoreTokens()) {
070: String s = st.nextToken();
071: if (!ll.contains(s)) {
072: ll.add(s);
073: }
074: }
075: return ll;
076: }
077:
078: // Load DNS configuration from OS
079:
080: private void loadConfig() {
081: assert Thread.holdsLock(lock);
082:
083: // if address have changed then DNS probably changed aswell;
084: // otherwise check if cached settings have expired.
085: //
086: if (changed) {
087: changed = false;
088: } else {
089: if (lastRefresh >= 0) {
090: long currTime = System.currentTimeMillis();
091: if ((currTime - lastRefresh) < TIMEOUT) {
092: return;
093: }
094: }
095: }
096:
097: // load DNS configuration, update timestamp, create
098: // new HashMaps from the loaded configuration
099: //
100: loadDNSconfig0();
101:
102: lastRefresh = System.currentTimeMillis();
103: searchlist = stringToList(os_searchlist);
104: nameservers = stringToList(os_nameservers);
105: os_searchlist = null; // can be GC'ed
106: os_nameservers = null;
107: }
108:
109: ResolverConfigurationImpl() {
110: opts = new OptionsImpl();
111: }
112:
113: public List searchlist() {
114: synchronized (lock) {
115: loadConfig();
116:
117: // List is mutable so return a shallow copy
118: return (List) searchlist.clone();
119: }
120: }
121:
122: public List nameservers() {
123: synchronized (lock) {
124: loadConfig();
125:
126: // List is mutable so return a shallow copy
127: return (List) nameservers.clone();
128: }
129: }
130:
131: public Options options() {
132: return opts;
133: }
134:
135: // --- Address Change Listener
136:
137: static class AddressChangeListener extends Thread {
138: public void run() {
139: for (;;) {
140: // wait for configuration to change
141: if (notifyAddrChange0() != 0)
142: return;
143: synchronized (lock) {
144: changed = true;
145: }
146: }
147: }
148: }
149:
150: // --- Native methods --
151:
152: static native void init0();
153:
154: static native void loadDNSconfig0();
155:
156: static native int notifyAddrChange0();
157:
158: static {
159: java.security.AccessController
160: .doPrivileged(new sun.security.action.LoadLibraryAction(
161: "net"));
162: init0();
163:
164: // start the address listener thread
165: AddressChangeListener thr = new AddressChangeListener();
166: thr.setDaemon(true);
167: thr.start();
168: }
169: }
170:
171: /**
172: * Implementation of {@link ResolverConfiguration.Options}
173: */
174: class OptionsImpl extends ResolverConfiguration.Options {
175: }
|