Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ResolverConfigurationImpl.java « dns « net « sun « openjdk - github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 167faad99ac2e74b5a3c2d2217d60dd1eb6f9217 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.net.dns;

import java.util.List;
import java.util.LinkedList;
import java.util.StringTokenizer;
import java.io.IOException;
import cli.System.Net.NetworkInformation.IPAddressCollection;
import cli.System.Net.NetworkInformation.IPInterfaceProperties;
import cli.System.Net.NetworkInformation.NetworkInterface;

/*
 * An implementation of sun.net.ResolverConfiguration for Windows.
 */

public class ResolverConfigurationImpl
    extends ResolverConfiguration
{
    // Lock helds whilst loading configuration or checking
    private static Object lock = new Object();

    // Resolver options
    private final Options opts;

    // Addreses have changed
    private static boolean changed = false;

    // Time of last refresh.
    private static long lastRefresh = -1;

    // Cache timeout (120 seconds) - should be converted into property
    // or configured as preference in the future.
    private static final int TIMEOUT = 120000;

    // DNS suffix list and name servers populated by native method
    private static String os_searchlist;
    private static String os_nameservers;

    // Cached lists
    private static LinkedList searchlist;
    private static LinkedList nameservers;

    // Parse string that consists of token delimited by space or commas
    // and return LinkedHashMap
    private LinkedList<String> stringToList(String str) {
        LinkedList<String> ll = new LinkedList<>();

        // comma and space are valid delimites
        StringTokenizer st = new StringTokenizer(str, ", ");
        while (st.hasMoreTokens()) {
            String s = st.nextToken();
            if (!ll.contains(s)) {
                ll.add(s);
            }
        }
        return ll;
    }

    // Load DNS configuration from OS

    private void loadConfig() {
        assert Thread.holdsLock(lock);

        // if address have changed then DNS probably changed aswell;
        // otherwise check if cached settings have expired.
        //
        if (changed) {
            changed = false;
        } else {
            if (lastRefresh >= 0) {
                long currTime = System.currentTimeMillis();
                if ((currTime - lastRefresh) < TIMEOUT) {
                    return;
                }
            }
        }

        // load DNS configuration, update timestamp, create
        // new HashMaps from the loaded configuration
        //
        loadDNSconfig0();

        lastRefresh = System.currentTimeMillis();
        searchlist = stringToList(os_searchlist);
        nameservers = stringToList(os_nameservers);
        os_searchlist = null;                       // can be GC'ed
        os_nameservers = null;
    }

    ResolverConfigurationImpl() {
        opts = new OptionsImpl();
    }

    public List<String> searchlist() {
        synchronized (lock) {
            loadConfig();

            // List is mutable so return a shallow copy
            return (List)searchlist.clone();
        }
    }

    public List<String> nameservers() {
        synchronized (lock) {
            loadConfig();

            // List is mutable so return a shallow copy
            return (List)nameservers.clone();
         }
    }

    public Options options() {
        return opts;
    }

    // --- Address Change Listener

    static class AddressChangeListener extends Thread {
        public void run() {
            for (;;) {
                // wait for configuration to change
                if (notifyAddrChange0() != 0)
                    return;
                synchronized (lock) {
                    changed = true;
                }
            }
        }
    }


    // --- Native methods --

    static void init0() {
    }

    static void loadDNSconfig0() {
	String searchlist = "";
	String nameservers = "";
	for (NetworkInterface iface : NetworkInterface.GetAllNetworkInterfaces()) {
	    IPInterfaceProperties props = iface.GetIPProperties();
	    IPAddressCollection addresses = props.get_DnsAddresses();
	    for (int i = 0; i < addresses.get_Count(); i++) {
	        cli.System.Net.IPAddress addr = addresses.get_Item(i);
	        // no IPv6 support
	        if (addr.get_AddressFamily().Value == cli.System.Net.Sockets.AddressFamily.InterNetwork) {
                    nameservers = strAppend(nameservers, addr.toString());
	        }
	    }
	    try {
	        if (false) throw new cli.System.PlatformNotSupportedException();
		searchlist = strAppend(searchlist, props.get_DnsSuffix());
	    }
	    catch (cli.System.PlatformNotSupportedException _) {
	    }
	}
	os_searchlist = searchlist;
	os_nameservers = nameservers;
    }
    
    private static String strAppend(String s, String app) {
        if (s.equals("")) {
            return app;
        }
        if (app.equals("")) {
            return s;
        }
        return s + " " + app;
    }

    static int notifyAddrChange0() {
        // TODO we could use System.Net.NetworkInformation.NetworkChange to detect changes
        return -1;
    }

    static {
        java.security.AccessController.doPrivileged(
            new sun.security.action.LoadLibraryAction("net"));
        init0();

        // start the address listener thread
        AddressChangeListener thr = new AddressChangeListener();
        thr.setDaemon(true);
        thr.start();
    }
}

/**
 * Implementation of {@link ResolverConfiguration.Options}
 */
class OptionsImpl extends ResolverConfiguration.Options {
}