1 /* 2 * Copyright (c) 2002, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.net.dns; 27 28 import java.util.List; 29 import java.util.LinkedList; 30 import java.util.StringTokenizer; 31 import java.io.IOException; 32 33 /* 34 * An implementation of sun.net.ResolverConfiguration for Windows. 35 */ 36 37 public class ResolverConfigurationImpl 38 extends ResolverConfiguration 39 { 40 // Lock helds whilst loading configuration or checking 41 private static Object lock = new Object(); 42 43 // Resolver options 44 private final Options opts; 45 46 // Addreses have changed 47 private static boolean changed = false; 48 49 // Time of last refresh. 50 private static long lastRefresh = -1; 51 52 // Cache timeout (120 seconds) - should be converted into property 53 // or configured as preference in the future. 54 private static final int TIMEOUT = 120000; 55 56 // DNS suffix list and name servers populated by native method 57 private static String os_searchlist; 58 private static String os_nameservers; 59 60 // Cached lists 61 private static LinkedList searchlist; 62 private static LinkedList nameservers; 63 64 // Parse string that consists of token delimited by space or commas 65 // and return LinkedHashMap 66 private LinkedList stringToList(String str) { 67 LinkedList ll = new LinkedList(); 68 69 // comma and space are valid delimites 70 StringTokenizer st = new StringTokenizer(str, ", "); 71 while (st.hasMoreTokens()) { 72 String s = st.nextToken(); 73 if (!ll.contains(s)) { 74 ll.add(s); 75 } 76 } 77 return ll; 78 } 79 80 // Load DNS configuration from OS 81 82 private void loadConfig() { 83 assert Thread.holdsLock(lock); 84 85 // if address have changed then DNS probably changed aswell; 86 // otherwise check if cached settings have expired. 87 // 88 if (changed) { 89 changed = false; 90 } else { 91 if (lastRefresh >= 0) { 92 long currTime = System.currentTimeMillis(); 93 if ((currTime - lastRefresh) < TIMEOUT) { 94 return; 95 } 96 } 97 } 98 99 // load DNS configuration, update timestamp, create 100 // new HashMaps from the loaded configuration 101 // 102 loadDNSconfig0(); 103 104 lastRefresh = System.currentTimeMillis(); 105 searchlist = stringToList(os_searchlist); 106 nameservers = stringToList(os_nameservers); 107 os_searchlist = null; // can be GC'ed 108 os_nameservers = null; 109 } 110 111 ResolverConfigurationImpl() { 112 opts = new OptionsImpl(); 113 } 114 115 public List searchlist() { 116 synchronized (lock) { 117 loadConfig(); 118 119 // List is mutable so return a shallow copy 120 return (List)searchlist.clone(); 121 } 122 } 123 124 public List nameservers() { 125 synchronized (lock) { 126 loadConfig(); 127 128 // List is mutable so return a shallow copy 129 return (List)nameservers.clone(); 130 } 131 } 132 133 public Options options() { 134 return opts; 135 } 136 137 // --- Address Change Listener 138 139 static class AddressChangeListener extends Thread { 140 public void run() { 141 for (;;) { 142 // wait for configuration to change 143 if (notifyAddrChange0() != 0) 144 return; 145 synchronized (lock) { 146 changed = true; 147 } 148 } 149 } 150 } 151 152 153 // --- Native methods -- 154 155 static native void init0(); 156 157 static native void loadDNSconfig0(); 158 159 static native int notifyAddrChange0(); 160 161 static { 162 java.security.AccessController.doPrivileged( 163 new sun.security.action.LoadLibraryAction("net")); 164 init0(); 165 166 // start the address listener thread 167 AddressChangeListener thr = new AddressChangeListener(); 168 thr.setDaemon(true); 169 thr.start(); 170 } 171 } 172 173 /** 174 * Implementation of {@link ResolverConfiguration.Options} 175 */ 176 class OptionsImpl extends ResolverConfiguration.Options { 177 }