1 /*
2 * Copyright 2017 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 package io.netty5.resolver.dns;
17
18 import io.netty5.util.NetUtil;
19 import io.netty5.util.internal.PlatformDependent;
20 import io.netty5.util.internal.SocketUtils;
21 import io.netty5.util.internal.logging.InternalLogger;
22 import io.netty5.util.internal.logging.InternalLoggerFactory;
23
24 import java.net.Inet6Address;
25 import java.net.InetSocketAddress;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.List;
29
30 import static io.netty5.resolver.dns.DnsServerAddresses.sequential;
31
32 /**
33 * A {@link DnsServerAddressStreamProvider} which will use predefined default DNS servers to use for DNS resolution.
34 * These defaults do not respect your host's machines defaults.
35 * <p>
36 * This may use the JDK's blocking DNS resolution to bootstrap the default DNS server addresses.
37 */
38 public final class DefaultDnsServerAddressStreamProvider implements DnsServerAddressStreamProvider {
39 private static final InternalLogger logger =
40 InternalLoggerFactory.getInstance(DefaultDnsServerAddressStreamProvider.class);
41 public static final DefaultDnsServerAddressStreamProvider INSTANCE = new DefaultDnsServerAddressStreamProvider();
42
43 private static final List<InetSocketAddress> DEFAULT_NAME_SERVER_LIST;
44 private static final DnsServerAddresses DEFAULT_NAME_SERVERS;
45 static final int DNS_PORT = 53;
46
47 static {
48 final List<InetSocketAddress> defaultNameServers = new ArrayList<>(2);
49 if (!PlatformDependent.isAndroid()) {
50 // Only try to use when not on Android as the classes not exists there:
51 // See https://github.com/netty/netty/issues/8654
52 DirContextUtils.addNameServers(defaultNameServers, DNS_PORT);
53 }
54
55 if (!defaultNameServers.isEmpty()) {
56 if (logger.isDebugEnabled()) {
57 logger.debug(
58 "Default DNS servers: {} (sun.net.dns.ResolverConfiguration)", defaultNameServers);
59 }
60 } else {
61 // Depending if IPv6 or IPv4 is used choose the correct DNS servers provided by google:
62 // https://developers.google.com/speed/public-dns/docs/using
63 // https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
64 if (NetUtil.isIpV6AddressesPreferred() ||
65 NetUtil.LOCALHOST instanceof Inet6Address && !NetUtil.isIpV4StackPreferred()) {
66 Collections.addAll(
67 defaultNameServers,
68 SocketUtils.socketAddress("2001:4860:4860::8888", DNS_PORT),
69 SocketUtils.socketAddress("2001:4860:4860::8844", DNS_PORT));
70 } else {
71 Collections.addAll(
72 defaultNameServers,
73 SocketUtils.socketAddress("8.8.8.8", DNS_PORT),
74 SocketUtils.socketAddress("8.8.4.4", DNS_PORT));
75 }
76
77 if (logger.isWarnEnabled()) {
78 logger.warn(
79 "Default DNS servers: {} (Google Public DNS as a fallback)", defaultNameServers);
80 }
81 }
82
83 DEFAULT_NAME_SERVER_LIST = Collections.unmodifiableList(defaultNameServers);
84 DEFAULT_NAME_SERVERS = sequential(DEFAULT_NAME_SERVER_LIST);
85 }
86
87 private DefaultDnsServerAddressStreamProvider() {
88 }
89
90 @Override
91 public DnsServerAddressStream nameServerAddressStream(String hostname) {
92 return DEFAULT_NAME_SERVERS.stream();
93 }
94
95 /**
96 * Returns the list of the system DNS server addresses. If it failed to retrieve the list of the system DNS server
97 * addresses from the environment, it will return {@code "8.8.8.8"} and {@code "8.8.4.4"}, the addresses of the
98 * Google public DNS servers.
99 */
100 public static List<InetSocketAddress> defaultAddressList() {
101 return DEFAULT_NAME_SERVER_LIST;
102 }
103
104 /**
105 * Returns the {@link DnsServerAddresses} that yields the system DNS server addresses sequentially. If it failed to
106 * retrieve the list of the system DNS server addresses from the environment, it will use {@code "8.8.8.8"} and
107 * {@code "8.8.4.4"}, the addresses of the Google public DNS servers.
108 * <p>
109 * This method has the same effect with the following code:
110 * <pre>
111 * DnsServerAddresses.sequential(DnsServerAddresses.defaultAddressList());
112 * </pre>
113 * </p>
114 */
115 public static DnsServerAddresses defaultAddresses() {
116 return DEFAULT_NAME_SERVERS;
117 }
118 }