diff --git a/arc-core/src/arc/Application.java b/arc-core/src/arc/Application.java index 5d9f519c3..e9c7b4c64 100644 --- a/arc-core/src/arc/Application.java +++ b/arc-core/src/arc/Application.java @@ -3,6 +3,8 @@ import arc.struct.*; import arc.util.*; +import java.net.*; + public interface Application extends Disposable{ /** Returns a list of all the application listeners used. */ @@ -96,6 +98,8 @@ default boolean openURI(String URI){ return false; } + default void getDnsServers(Seq out){} + /** Posts a runnable on the main loop thread.*/ void post(Runnable runnable); diff --git a/backends/backend-android/src/arc/backend/android/AndroidApplication.java b/backends/backend-android/src/arc/backend/android/AndroidApplication.java index 739a43fda..7ff9b1839 100644 --- a/backends/backend-android/src/arc/backend/android/AndroidApplication.java +++ b/backends/backend-android/src/arc/backend/android/AndroidApplication.java @@ -16,6 +16,8 @@ import arc.struct.*; import arc.util.*; +import java.net.*; + /** * An implementation of the {@link Application} interface for Android. Create an {@link Activity} that derives from this class. In * the {@link Activity#onCreate(Bundle)} method call the {@link #initialize(ApplicationListener)} method specifying the @@ -166,6 +168,31 @@ protected void hideStatusBar(boolean hide){ getWindow().getDecorView().setSystemUiVisibility(0x1); } + @Override + public void getDnsServers(Seq out){ + if(getVersion() < 21) return; //needs API level 21 + + try{ + ConnectivityManager cm = getSystemService(ConnectivityManager.class); + Network network = cm.getActiveNetwork(); + if(network == null){ + // if the device is offline, there's no active network + return; + } + + LinkProperties lp = cm.getLinkProperties(network); + if(lp == null){ + // can be null for an unknown network, which may happen if networks change + return; + } + + for(InetAddress address : lp.getDnsServers()){ + out.add(new InetSocketAddress(address, 53)); + } + }catch(Throwable ignored){ + } + } + @Override public void onWindowFocusChanged(boolean hasFocus){ super.onWindowFocusChanged(hasFocus); diff --git a/extensions/arcnet/src/arc/net/dns/AbstractNameserverProvider.java b/extensions/arcnet/src/arc/net/dns/AbstractNameserverProvider.java deleted file mode 100644 index 8bda067d8..000000000 --- a/extensions/arcnet/src/arc/net/dns/AbstractNameserverProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is a modified class of dnsjava, an implementation of the dns protocol in java. - * Licensed under the BSD-3-Clause. - */ -package arc.net.dns; - -import arc.struct.*; -import arc.util.*; - -import java.net.*; - -/** - * Simple abstract class for name server resolvers. - */ -public abstract class AbstractNameserverProvider implements NameserverProvider{ - - private final Seq nameservers = new Seq<>(3); - - @Override - public Seq getNameservers(){ - return nameservers.copy(); - } - - protected final void reset(){ - nameservers.clear(); - } - - protected void addNameServer(InetSocketAddress server){ - if(!nameservers.contains(server)){ - nameservers.add(server); - Log.debug("[DNS] Added @ to nameservers", server); - } - } -} diff --git a/extensions/arcnet/src/arc/net/dns/ArcDns.java b/extensions/arcnet/src/arc/net/dns/ArcDns.java index 7447b6d13..8d2f5bc72 100644 --- a/extensions/arcnet/src/arc/net/dns/ArcDns.java +++ b/extensions/arcnet/src/arc/net/dns/ArcDns.java @@ -1,5 +1,6 @@ package arc.net.dns; +import arc.*; import arc.math.*; import arc.struct.*; import arc.util.*; @@ -7,7 +8,6 @@ import java.io.*; import java.net.*; -import java.nio.charset.*; public final class ArcDns{ @@ -26,7 +26,7 @@ public final class ArcDns{ } public static Seq getNameserverProviders(){ - return nameserverProviders.copy(); + return nameserverProviders; } /** Set a new ordered list of resolver config providers. */ @@ -38,25 +38,32 @@ public static void setNameserverProviders(Seq providers){ /** Returns all located servers */ public static Seq getNameservers(){ - return nameservers.copy(); + return nameservers; } public static void refreshNameservers(){ nameservers.clear(); + if(Core.app != null){ + Core.app.getDnsServers(nameservers); + } + for(NameserverProvider provider : nameserverProviders){ if(provider.isEnabled()){ try{ - provider.initialize(); nameservers.addAll(provider.getNameservers()); // Stop when a name server is found if(!nameservers.isEmpty()) return; - }catch(InitializationException e){ + }catch(Exception e){ Log.warn("[DNS] Failed to initialize provider: @", e); } } } + for(InetSocketAddress server : nameservers){ + Log.debug("[DNS] Added @ to nameservers", server); + } + // Add localhost as nameserver if no suitable nameserver provider found nameservers.add(new InetSocketAddress(InetAddress.getLoopbackAddress(), dnsResolverPort)); } @@ -101,7 +108,7 @@ public static Seq getSrvRecords(String domain, InetSocketAddress name // Domain for(String part : domain.split("\\.")){ out.writeByte(part.length()); - out.write(part.getBytes(StandardCharsets.UTF_8)); + out.write(part.getBytes(Strings.utf8)); } out.writeByte(0); diff --git a/extensions/arcnet/src/arc/net/dns/InitializationException.java b/extensions/arcnet/src/arc/net/dns/InitializationException.java deleted file mode 100644 index c817422ba..000000000 --- a/extensions/arcnet/src/arc/net/dns/InitializationException.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * This file is a modified class of dnsjava, an implementation of the dns protocol in java. - * Licensed under the BSD-3-Clause. - */ -package arc.net.dns; - -public class InitializationException extends Exception{ - InitializationException(String message){ - super(message); - } -} diff --git a/extensions/arcnet/src/arc/net/dns/JndiContextNameserverProvider.java b/extensions/arcnet/src/arc/net/dns/JndiContextNameserverProvider.java index bfb25b433..c59279eec 100644 --- a/extensions/arcnet/src/arc/net/dns/JndiContextNameserverProvider.java +++ b/extensions/arcnet/src/arc/net/dns/JndiContextNameserverProvider.java @@ -19,41 +19,12 @@ * JNDI DNS Service Provider. */ public final class JndiContextNameserverProvider implements NameserverProvider{ - private InnerJndiContextNameserverProvider inner; - - public JndiContextNameserverProvider(){ - if(!OS.isAndroid){ - try{ - inner = new InnerJndiContextNameserverProvider(); - }catch(Throwable e){ - Log.debug("[DNS] JNDI DNS not available"); - } - } - } - - @Override - public void initialize(){ - inner.initialize(); - } @Override public Seq getNameservers(){ - return inner.getNameservers(); - } - - @Override - public boolean isEnabled(){ - return inner != null; - } - - private static final class InnerJndiContextNameserverProvider extends AbstractNameserverProvider{ - static{ - Log.debug("[DNS] JNDI class: @", DirContext.class.getName()); - } + try{ + Seq result = new Seq<>(); - @Override - public void initialize(){ - reset(); Hashtable env = new Hashtable<>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); // http://mail.openjdk.java.net/pipermail/net-dev/2017-March/010695.html @@ -84,12 +55,21 @@ public void initialize(){ port = dnsResolverPort; } - addNameServer(new InetSocketAddress(host, port)); + result.add(new InetSocketAddress(host, port)); }catch(URISyntaxException e){ Log.debug("[DNS] Could not parse @ as a dns server, ignoring: @", server, e); } } } + + return result; + }catch(Throwable t){ + return new Seq<>(); } } + + @Override + public boolean isEnabled(){ + return !OS.isAndroid && !OS.isIos; + } } diff --git a/extensions/arcnet/src/arc/net/dns/NameserverProvider.java b/extensions/arcnet/src/arc/net/dns/NameserverProvider.java index bdbe40077..66f93bcde 100644 --- a/extensions/arcnet/src/arc/net/dns/NameserverProvider.java +++ b/extensions/arcnet/src/arc/net/dns/NameserverProvider.java @@ -9,9 +9,6 @@ import java.net.*; public interface NameserverProvider{ - /** Initializes the servers. */ - void initialize() throws InitializationException; - /** Returns all located servers, which may be empty. */ Seq getNameservers(); diff --git a/extensions/arcnet/src/arc/net/dns/ResolvConfNameserverProvider.java b/extensions/arcnet/src/arc/net/dns/ResolvConfNameserverProvider.java index fafa18339..69a55eb8a 100644 --- a/extensions/arcnet/src/arc/net/dns/ResolvConfNameserverProvider.java +++ b/extensions/arcnet/src/arc/net/dns/ResolvConfNameserverProvider.java @@ -5,27 +5,29 @@ package arc.net.dns; import arc.files.*; +import arc.struct.*; import arc.util.*; import java.io.*; import java.net.*; import java.util.*; -import static arc.net.dns.ArcDns.dnsResolverPort; +import static arc.net.dns.ArcDns.*; -public final class ResolvConfNameserverProvider extends AbstractNameserverProvider{ +public final class ResolvConfNameserverProvider implements NameserverProvider{ @Override - public void initialize(){ - reset(); + public Seq getNameservers(){ + Seq out = new Seq<>(); // first try the default unix config path - if(!tryParseResolveConf("/etc/resolv.conf")){ + if(!tryParseResolveConf("/etc/resolv.conf", out)){ // then fallback to netware - tryParseResolveConf("sys:/etc/resolv.cfg"); + tryParseResolveConf("sys:/etc/resolv.cfg", out); } + return out; } - private boolean tryParseResolveConf(String path){ + private boolean tryParseResolveConf(String path, Seq out){ Fi conf = new Fi(path); if(conf.exists()){ @@ -36,11 +38,11 @@ private boolean tryParseResolveConf(String path){ if(!tokenizer.hasMoreTokens()) continue; if(tokenizer.nextToken().equals("nameserver")){ - addNameServer(new InetSocketAddress(tokenizer.nextToken(), dnsResolverPort)); + out.add(new InetSocketAddress(tokenizer.nextToken(), dnsResolverPort)); } } return true; - }catch(IOException ignored){ + }catch(Exception ignored){ } } diff --git a/extensions/arcnet/src/arc/net/dns/SRVRecord.java b/extensions/arcnet/src/arc/net/dns/SRVRecord.java index 01e205c42..afa1eb54c 100644 --- a/extensions/arcnet/src/arc/net/dns/SRVRecord.java +++ b/extensions/arcnet/src/arc/net/dns/SRVRecord.java @@ -15,6 +15,17 @@ public SRVRecord(long ttl, int priority, int weight, int port, String target){ this.target = target; } + @Override + public String toString(){ + return "SRVRecord{" + + "ttl=" + ttl + + ", priority=" + priority + + ", weight=" + weight + + ", port=" + port + + ", target='" + target + '\'' + + '}'; + } + @Override public int compareTo(SRVRecord o){ if(this.priority != o.priority){ diff --git a/extensions/arcnet/src/arc/net/dns/WellKnownNameserverProvider.java b/extensions/arcnet/src/arc/net/dns/WellKnownNameserverProvider.java index e00f43146..8d8ded414 100644 --- a/extensions/arcnet/src/arc/net/dns/WellKnownNameserverProvider.java +++ b/extensions/arcnet/src/arc/net/dns/WellKnownNameserverProvider.java @@ -7,18 +7,13 @@ import static arc.net.dns.ArcDns.dnsResolverPort; public final class WellKnownNameserverProvider implements NameserverProvider{ - private final Seq nameservers = Seq.with( new InetSocketAddress("1.1.1.1", dnsResolverPort), // Cloudflare new InetSocketAddress("8.8.8.8", dnsResolverPort) // Google ); - @Override - public void initialize(){ - } - @Override public Seq getNameservers(){ - return nameservers.copy(); + return nameservers; } }