diff --git a/minidns-android21/src/main/java/org/minidns/dnsserverlookup/android21/AndroidUsingLinkProperties.java b/minidns-android21/src/main/java/org/minidns/dnsserverlookup/android21/AndroidUsingLinkProperties.java index d5f7a49d..05f995f1 100644 --- a/minidns-android21/src/main/java/org/minidns/dnsserverlookup/android21/AndroidUsingLinkProperties.java +++ b/minidns-android21/src/main/java/org/minidns/dnsserverlookup/android21/AndroidUsingLinkProperties.java @@ -24,6 +24,7 @@ import org.minidns.DnsClient; import org.minidns.dnsserverlookup.AbstractDnsServerLookupMechanism; import org.minidns.dnsserverlookup.AndroidUsingExec; +import org.minidns.dnsserverlookup.IPPortPair; /** * A DNS server lookup mechanism using Android's Link Properties method available on Android API 21 or higher. Use @@ -61,7 +62,7 @@ public boolean isAvailable() { @Override @TargetApi(21) - public List getDnsServerAddresses() { + public List getDnsServerAddresses() { Network[] networks = connectivityManager.getAllNetworks(); if (networks == null) { return null; @@ -86,7 +87,7 @@ public List getDnsServerAddresses() { return null; } - return servers; + return stringCollectionToListOfIPPortPairs(servers); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) diff --git a/minidns-client/src/main/java/org/minidns/DnsClient.java b/minidns-client/src/main/java/org/minidns/DnsClient.java index 3dff40fe..8874bf58 100644 --- a/minidns-client/src/main/java/org/minidns/DnsClient.java +++ b/minidns-client/src/main/java/org/minidns/DnsClient.java @@ -18,6 +18,7 @@ import org.minidns.dnsserverlookup.AndroidUsingExec; import org.minidns.dnsserverlookup.AndroidUsingReflection; import org.minidns.dnsserverlookup.DnsServerLookupMechanism; +import org.minidns.dnsserverlookup.IPPortPair; import org.minidns.dnsserverlookup.UnixUsingEtcResolvConf; import org.minidns.util.CollectionsUtil; import org.minidns.util.ExceptionCallback; @@ -99,8 +100,8 @@ protected DnsMessage.Builder newQuestion(DnsMessage.Builder message) { return message; } - private List getServerAddresses() { - List dnsServerAddresses = findDnsAddresses(); + private List getServerAddresses() { + List dnsServerAddresses = findDnsAddresses(); InetAddress[] selectedHardcodedDnsServerAddresses = new InetAddress[2]; if (useHardcodedDnsServers) { @@ -126,7 +127,7 @@ private List getServerAddresses() { } for (InetAddress selectedHardcodedDnsServerAddress : selectedHardcodedDnsServerAddresses) { if (selectedHardcodedDnsServerAddress == null) continue; - dnsServerAddresses.add(selectedHardcodedDnsServerAddress); + dnsServerAddresses.add(new UpstreamDNSServer(selectedHardcodedDnsServerAddress, IPPortPair.DEFAULT_PORT)); } return dnsServerAddresses; @@ -145,17 +146,17 @@ public DnsQueryResult query(DnsMessage.Builder queryBuilder) throws IOException return dnsQueryResult; } - List dnsServerAddresses = getServerAddresses(); + List dnsServerAddresses = getServerAddresses(); List ioExceptions = new ArrayList<>(dnsServerAddresses.size()); - for (InetAddress dns : dnsServerAddresses) { - if (nonRaServers.contains(dns)) { + for (UpstreamDNSServer dns : dnsServerAddresses) { + if (nonRaServers.contains(dns.getServer())) { LOGGER.finer("Skipping " + dns + " because it was marked as \"recursion not available\""); continue; } try { - dnsQueryResult = query(q, dns); + dnsQueryResult = query(q, dns.getServer(), dns.getPort()); } catch (IOException ioe) { ioExceptions.add(ioe); continue; @@ -163,7 +164,7 @@ public DnsQueryResult query(DnsMessage.Builder queryBuilder) throws IOException DnsMessage responseMessage = dnsQueryResult.response; if (!responseMessage.recursionAvailable) { - boolean newRaServer = nonRaServers.add(dns); + boolean newRaServer = nonRaServers.add(dns.getServer()); if (newRaServer) { LOGGER.warning("The DNS server " + dns + " returned a response without the \"recursion available\" (RA) flag set. This likely indicates a misconfiguration because the server is not suitable for DNS resolution"); @@ -215,16 +216,16 @@ protected MiniDnsFuture queryAsync(DnsMessage.Build return MiniDnsFuture.from(responseMessage); } - final List dnsServerAddresses = getServerAddresses(); + final List dnsServerAddresses = getServerAddresses(); final InternalMiniDnsFuture future = new InternalMiniDnsFuture<>(); final List exceptions = Collections.synchronizedList(new ArrayList(dnsServerAddresses.size())); // Filter loop. - Iterator it = dnsServerAddresses.iterator(); + Iterator it = dnsServerAddresses.iterator(); while (it.hasNext()) { - InetAddress dns = it.next(); - if (nonRaServers.contains(dns)) { + UpstreamDNSServer dns = it.next(); + if (nonRaServers.contains(dns.getServer())) { it.remove(); LOGGER.finer("Skipping " + dns + " because it was marked as \"recursion not available\""); continue; @@ -233,7 +234,7 @@ protected MiniDnsFuture queryAsync(DnsMessage.Build List> futures = new ArrayList<>(dnsServerAddresses.size()); // "Main" loop. - for (InetAddress dns : dnsServerAddresses) { + for (UpstreamDNSServer dns : dnsServerAddresses) { if (future.isDone()) { for (MiniDnsFuture futureToCancel : futures) { futureToCancel.cancel(true); @@ -241,7 +242,7 @@ protected MiniDnsFuture queryAsync(DnsMessage.Build break; } - MiniDnsFuture f = queryAsync(q, dns); + MiniDnsFuture f = queryAsync(q, dns.getServer(), dns.getPort()); f.onSuccess(new SuccessCallback() { @Override public void onSuccess(DnsQueryResult result) { @@ -272,8 +273,8 @@ public void processException(IOException exception) { * * @return A list of DNS server IP addresses configured for this system. */ - public static List findDNS() { - List res = null; + public static List findDNS() { + List res = null; for (DnsServerLookupMechanism mechanism : LOOKUP_MECHANISMS) { res = mechanism.getDnsServerAddresses(); if (res == null) { @@ -289,14 +290,14 @@ public static List findDNS() { // especially a valid DNS name is returned, as this would cause the following String to InetAddress conversation using // getByName(String) to cause a DNS lookup, which would be performed outside of the realm of MiniDNS and therefore also outside // of its DNSSEC guarantees. - Iterator it = res.iterator(); + Iterator it = res.iterator(); while (it.hasNext()) { - String potentialDnsServer = it.next(); - if (!InetAddressUtil.isIpAddress(potentialDnsServer)) { + IPPortPair potentialDnsServer = it.next(); + if (!InetAddressUtil.isIpAddress(potentialDnsServer.getIp())) { LOGGER.warning("The DNS server lookup mechanism '" + mechanism.getName() + "' returned an invalid non-IP address result: '" + potentialDnsServer + "'"); it.remove(); - } else if (blacklistedDnsServers.contains(potentialDnsServer)) { + } else if (blacklistedDnsServers.contains(potentialDnsServer.getIp())) { LOGGER.fine("The DNS server lookup mechanism '" + mechanism.getName() + "' returned a blacklisted result: '" + potentialDnsServer + "'"); it.remove(); @@ -325,9 +326,9 @@ public static List findDNS() { * @return A list of DNS server addresses. * @see #findDNS() */ - public static List findDnsAddresses() { + public static List findDnsAddresses() { // The findDNS() method contract guarantees that only IP addresses will be returned. - List res = findDNS(); + List res = findDNS(); if (res == null) { return new ArrayList<>(); @@ -335,8 +336,8 @@ public static List findDnsAddresses() { final IpVersionSetting setting = DEFAULT_IP_VERSION_SETTING; - List ipv4DnsServer = null; - List ipv6DnsServer = null; + List ipv4DnsServer = null; + List ipv6DnsServer = null; if (setting.v4) { ipv4DnsServer = new ArrayList<>(res.size()); } @@ -344,17 +345,18 @@ public static List findDnsAddresses() { ipv6DnsServer = new ArrayList<>(res.size()); } - for (String dnsServerString : res) { + for (IPPortPair dnsServer : res) { // The following invariant must hold: "dnsServerString is a IP address". Therefore findDNS() must only return a List of Strings // representing IP addresses. Otherwise the following call of getByName(String) may perform a DNS lookup without MiniDNS being // involved. Something we want to avoid. - assert (InetAddressUtil.isIpAddress(dnsServerString)); + assert (InetAddressUtil.isIpAddress(dnsServer.getIp())); + assert (dnsServer.getPort() >= 1 && dnsServer.getPort() <= 65535); InetAddress dnsServerAddress; try { - dnsServerAddress = InetAddress.getByName(dnsServerString); + dnsServerAddress = InetAddress.getByName(dnsServer.getIp()); } catch (UnknownHostException e) { - LOGGER.log(Level.SEVERE, "Could not transform '" + dnsServerString + "' to InetAddress", e); + LOGGER.log(Level.SEVERE, "Could not transform '" + dnsServer + "' to InetAddress", e); continue; } if (dnsServerAddress instanceof Inet4Address) { @@ -362,19 +364,19 @@ public static List findDnsAddresses() { continue; } Inet4Address ipv4DnsServerAddress = (Inet4Address) dnsServerAddress; - ipv4DnsServer.add(ipv4DnsServerAddress); + ipv4DnsServer.add(new UpstreamDNSServer(ipv4DnsServerAddress, dnsServer.getPort())); } else if (dnsServerAddress instanceof Inet6Address) { if (!setting.v6) { continue; } Inet6Address ipv6DnsServerAddress = (Inet6Address) dnsServerAddress; - ipv6DnsServer.add(ipv6DnsServerAddress); + ipv6DnsServer.add(new UpstreamDNSServer(ipv6DnsServerAddress, dnsServer.getPort())); } else { throw new AssertionError("The address '" + dnsServerAddress + "' is neither of type Inet(4|6)Address"); } } - List dnsServers = new LinkedList<>(); + List dnsServers = new LinkedList<>(); switch (setting) { case v4v6: @@ -462,4 +464,22 @@ public InetAddress getRandomHardcodedIpv4DnsServer() { public InetAddress getRandomHarcodedIpv6DnsServer() { return CollectionsUtil.getRandomFrom(STATIC_IPV6_DNS_SERVERS, insecureRandom); } + + public static class UpstreamDNSServer { + private InetAddress server; + private int port; + + public UpstreamDNSServer(InetAddress server, int port) { + this.server = server; + this.port = port; + } + + public InetAddress getServer() { + return server; + } + + public int getPort() { + return port; + } + } } diff --git a/minidns-client/src/main/java/org/minidns/dnsserverlookup/AbstractDnsServerLookupMechanism.java b/minidns-client/src/main/java/org/minidns/dnsserverlookup/AbstractDnsServerLookupMechanism.java index 49920cbd..660c24c5 100644 --- a/minidns-client/src/main/java/org/minidns/dnsserverlookup/AbstractDnsServerLookupMechanism.java +++ b/minidns-client/src/main/java/org/minidns/dnsserverlookup/AbstractDnsServerLookupMechanism.java @@ -44,7 +44,7 @@ public final int compareTo(DnsServerLookupMechanism other) { } @Override - public abstract List getDnsServerAddresses(); + public abstract List getDnsServerAddresses(); protected static List toListOfStrings(Collection inetAddresses) { List result = new ArrayList<>(inetAddresses.size()); @@ -54,4 +54,21 @@ protected static List toListOfStrings(Collection } return result; } + + protected static List inetAddressCollectionToListOfIPPortPairs(Collection inetAddresses){ + List result = new ArrayList<>(inetAddresses.size()); + for (InetAddress inetAddress : inetAddresses) { + String address = inetAddress.getHostAddress(); + result.add(new IPPortPair(address, IPPortPair.DEFAULT_PORT)); + } + return result; + } + + protected static List stringCollectionToListOfIPPortPairs(Collection serverAddresses){ + List result = new ArrayList<>(serverAddresses.size()); + for (String address : serverAddresses) { + result.add(new IPPortPair(address, IPPortPair.DEFAULT_PORT)); + } + return result; + } } diff --git a/minidns-client/src/main/java/org/minidns/dnsserverlookup/AndroidUsingExec.java b/minidns-client/src/main/java/org/minidns/dnsserverlookup/AndroidUsingExec.java index 023226d3..dae4565a 100644 --- a/minidns-client/src/main/java/org/minidns/dnsserverlookup/AndroidUsingExec.java +++ b/minidns-client/src/main/java/org/minidns/dnsserverlookup/AndroidUsingExec.java @@ -38,7 +38,7 @@ private AndroidUsingExec() { } @Override - public List getDnsServerAddresses() { + public List getDnsServerAddresses() { try { Process process = Runtime.getRuntime().exec("getprop"); InputStream inputStream = process.getInputStream(); @@ -48,7 +48,7 @@ public List getDnsServerAddresses() { if (server.size() > 0) { List res = new ArrayList<>(server.size()); res.addAll(server); - return res; + return stringCollectionToListOfIPPortPairs(res); } } catch (IOException e) { LOGGER.log(Level.WARNING, "Exception in findDNSByExec", e); diff --git a/minidns-client/src/main/java/org/minidns/dnsserverlookup/AndroidUsingReflection.java b/minidns-client/src/main/java/org/minidns/dnsserverlookup/AndroidUsingReflection.java index b9822497..a9869ac6 100644 --- a/minidns-client/src/main/java/org/minidns/dnsserverlookup/AndroidUsingReflection.java +++ b/minidns-client/src/main/java/org/minidns/dnsserverlookup/AndroidUsingReflection.java @@ -31,7 +31,7 @@ protected AndroidUsingReflection() { } @Override - public List getDnsServerAddresses() { + public List getDnsServerAddresses() { try { Class SystemProperties = Class.forName("android.os.SystemProperties"); @@ -63,7 +63,7 @@ public List getDnsServerAddresses() { } if (servers.size() > 0) { - return servers; + return stringCollectionToListOfIPPortPairs(servers); } } catch (Exception e) { // we might trigger some problems this way diff --git a/minidns-client/src/main/java/org/minidns/dnsserverlookup/DnsServerLookupMechanism.java b/minidns-client/src/main/java/org/minidns/dnsserverlookup/DnsServerLookupMechanism.java index d26fd08b..67c76aac 100644 --- a/minidns-client/src/main/java/org/minidns/dnsserverlookup/DnsServerLookupMechanism.java +++ b/minidns-client/src/main/java/org/minidns/dnsserverlookup/DnsServerLookupMechanism.java @@ -27,8 +27,8 @@ public interface DnsServerLookupMechanism extends Comparable * - * @return a List of Strings presenting hopefully IP addresses. + * @return a List of IPPortPairs presenting hopefully IP addresses with their respective ports. */ - public List getDnsServerAddresses(); + public List getDnsServerAddresses(); } diff --git a/minidns-client/src/main/java/org/minidns/dnsserverlookup/IPPortPair.java b/minidns-client/src/main/java/org/minidns/dnsserverlookup/IPPortPair.java new file mode 100644 index 00000000..908a4fb8 --- /dev/null +++ b/minidns-client/src/main/java/org/minidns/dnsserverlookup/IPPortPair.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015-2018 the original author or authors + * + * This software is licensed under the Apache License, Version 2.0, + * the GNU Lesser General Public License version 2 or later ("LGPL") + * and the WTFPL. + * You may choose either license to govern your use of this software only + * upon the condition that you accept all of the terms of either + * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. + */ +package org.minidns.dnsserverlookup; + +import java.io.Serializable; + +public class IPPortPair implements Serializable { + private static final long serialVersionUID = 7354713072355023750L; + public static final int DEFAULT_PORT = 53; + private int port; + private String ip; + + public IPPortPair(String ip) { + this(ip, DEFAULT_PORT); + } + + public IPPortPair(String ip, int port) { + this.port = port; + this.ip = ip; + } + + public int getPort() { + return port; + } + + public String getIp() { + return ip; + } +} diff --git a/minidns-client/src/main/java/org/minidns/dnsserverlookup/UnixUsingEtcResolvConf.java b/minidns-client/src/main/java/org/minidns/dnsserverlookup/UnixUsingEtcResolvConf.java index 59fac40e..96a24c7c 100644 --- a/minidns-client/src/main/java/org/minidns/dnsserverlookup/UnixUsingEtcResolvConf.java +++ b/minidns-client/src/main/java/org/minidns/dnsserverlookup/UnixUsingEtcResolvConf.java @@ -34,7 +34,7 @@ public class UnixUsingEtcResolvConf extends AbstractDnsServerLookupMechanism { private static final String RESOLV_CONF_FILE = "/etc/resolv.conf"; private static final Pattern NAMESERVER_PATTERN = Pattern.compile("^nameserver\\s+(.*)$"); - private static List cached; + private static List cached; private static long lastModified; private UnixUsingEtcResolvConf() { @@ -42,7 +42,7 @@ private UnixUsingEtcResolvConf() { } @Override - public List getDnsServerAddresses() { + public List getDnsServerAddresses() { File file = new File(RESOLV_CONF_FILE); if (!file.exists()) { // Not very unixoid systems @@ -81,7 +81,7 @@ public List getDnsServerAddresses() { return null; } - cached = servers; + cached = stringCollectionToListOfIPPortPairs(servers); lastModified = currentLastModified; return cached; diff --git a/minidns-client/src/test/java/org/minidns/DnsClientTest.java b/minidns-client/src/test/java/org/minidns/DnsClientTest.java index 31c4fa7d..7664d5d5 100644 --- a/minidns-client/src/test/java/org/minidns/DnsClientTest.java +++ b/minidns-client/src/test/java/org/minidns/DnsClientTest.java @@ -18,6 +18,7 @@ import org.minidns.dnsserverlookup.AbstractDnsServerLookupMechanism; import org.minidns.dnsserverlookup.AndroidUsingExec; import org.minidns.dnsserverlookup.AndroidUsingReflection; +import org.minidns.dnsserverlookup.IPPortPair; import org.minidns.dnsserverlookup.DnsServerLookupMechanism; import org.minidns.record.A; import org.minidns.record.Record.TYPE; @@ -69,7 +70,7 @@ public boolean isAvailable() { return true; } @Override - public List getDnsServerAddresses() { + public List getDnsServerAddresses() { return null; } }