2
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
28
import java.util.List;
29
import java.util.LinkedList;
30
import java.util.StringTokenizer;
31
import java.io.IOException;
32
import cli.System.Net.NetworkInformation.IPAddressCollection;
33
import cli.System.Net.NetworkInformation.IPInterfaceProperties;
34
import cli.System.Net.NetworkInformation.NetworkInterface;
37
* An implementation of sun.net.ResolverConfiguration for Windows.
40
public class ResolverConfigurationImpl
41
extends ResolverConfiguration
43
// Lock helds whilst loading configuration or checking
44
private static Object lock = new Object();
47
private final Options opts;
49
// Addreses have changed
50
private static boolean changed = false;
52
// Time of last refresh.
53
private static long lastRefresh = -1;
55
// Cache timeout (120 seconds) - should be converted into property
56
// or configured as preference in the future.
57
private static final int TIMEOUT = 120000;
59
// DNS suffix list and name servers populated by native method
60
private static String os_searchlist;
61
private static String os_nameservers;
64
private static LinkedList searchlist;
65
private static LinkedList nameservers;
67
// Parse string that consists of token delimited by space or commas
68
// and return LinkedHashMap
69
private LinkedList<String> stringToList(String str) {
70
LinkedList<String> ll = new LinkedList<>();
72
// comma and space are valid delimites
73
StringTokenizer st = new StringTokenizer(str, ", ");
74
while (st.hasMoreTokens()) {
75
String s = st.nextToken();
76
if (!ll.contains(s)) {
83
// Load DNS configuration from OS
85
private void loadConfig() {
86
assert Thread.holdsLock(lock);
88
// if address have changed then DNS probably changed aswell;
89
// otherwise check if cached settings have expired.
94
if (lastRefresh >= 0) {
95
long currTime = System.currentTimeMillis();
96
if ((currTime - lastRefresh) < TIMEOUT) {
102
// load DNS configuration, update timestamp, create
103
// new HashMaps from the loaded configuration
107
lastRefresh = System.currentTimeMillis();
108
searchlist = stringToList(os_searchlist);
109
nameservers = stringToList(os_nameservers);
110
os_searchlist = null; // can be GC'ed
111
os_nameservers = null;
114
ResolverConfigurationImpl() {
115
opts = new OptionsImpl();
118
public List<String> searchlist() {
119
synchronized (lock) {
122
// List is mutable so return a shallow copy
123
return (List)searchlist.clone();
127
public List<String> nameservers() {
128
synchronized (lock) {
131
// List is mutable so return a shallow copy
132
return (List)nameservers.clone();
136
public Options options() {
140
// --- Address Change Listener
142
static class AddressChangeListener extends Thread {
145
// wait for configuration to change
146
if (notifyAddrChange0() != 0)
148
synchronized (lock) {
156
// --- Native methods --
158
static void init0() {
161
static void loadDNSconfig0() {
162
String searchlist = "";
163
String nameservers = "";
164
for (NetworkInterface iface : NetworkInterface.GetAllNetworkInterfaces()) {
165
IPInterfaceProperties props = iface.GetIPProperties();
166
IPAddressCollection addresses = props.get_DnsAddresses();
167
for (int i = 0; i < addresses.get_Count(); i++) {
168
cli.System.Net.IPAddress addr = addresses.get_Item(i);
170
if (addr.get_AddressFamily().Value == cli.System.Net.Sockets.AddressFamily.InterNetwork) {
171
nameservers = strAppend(nameservers, addr.toString());
175
if (false) throw new cli.System.PlatformNotSupportedException();
176
searchlist = strAppend(searchlist, props.get_DnsSuffix());
178
catch (cli.System.PlatformNotSupportedException _) {
181
os_searchlist = searchlist;
182
os_nameservers = nameservers;
185
private static String strAppend(String s, String app) {
189
if (app.equals("")) {
192
return s + " " + app;
195
static int notifyAddrChange0() {
196
// TODO we could use System.Net.NetworkInformation.NetworkChange to detect changes
201
java.security.AccessController.doPrivileged(
202
new sun.security.action.LoadLibraryAction("net"));
205
// start the address listener thread
206
AddressChangeListener thr = new AddressChangeListener();
213
* Implementation of {@link ResolverConfiguration.Options}
215
class OptionsImpl extends ResolverConfiguration.Options {