From 7cbef529aed19515391056a1dc81f16760e036b9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 10 Jul 2017 08:49:22 +0200 Subject: [PATCH] resolve non-srv domains in resolver class as well this allows us to prefer ipv4 --- .../siacs/conversations/utils/Resolver.java | 58 +++++++++++++++---- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/Resolver.java b/src/main/java/eu/siacs/conversations/utils/Resolver.java index 3a1ac8259..075447be6 100644 --- a/src/main/java/eu/siacs/conversations/utils/Resolver.java +++ b/src/main/java/eu/siacs/conversations/utils/Resolver.java @@ -19,6 +19,7 @@ import de.measite.minidns.hla.ResolverApi; import de.measite.minidns.hla.ResolverResult; import de.measite.minidns.record.A; import de.measite.minidns.record.AAAA; +import de.measite.minidns.record.CNAME; import de.measite.minidns.record.Data; import de.measite.minidns.record.InternetAddressRR; import de.measite.minidns.record.SRV; @@ -47,7 +48,7 @@ public class Resolver { Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": "+e.getMessage()); } if (results.size() == 0) { - results.add(Result.createDefault(domain)); + results.addAll(resolveFallback(DNSName.from(domain))); } Collections.sort(results); Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": "+results.toString()); @@ -55,7 +56,7 @@ public class Resolver { } private static List resolveSrv(String domain, final boolean directTls) throws IOException { - if (Thread.interrupted()) { + if (Thread.currentThread().isInterrupted()) { return Collections.emptyList(); } DNSName dnsName = DNSName.from((directTls ? DIRECT_TLS_SERVICE : STARTTLS_SERICE)+"._tcp."+domain); @@ -64,7 +65,7 @@ public class Resolver { for(SRV record : result.getAnswersOrEmptySet()) { final boolean addedIPv4 = results.addAll(resolveIp(record,A.class,result.isAuthenticData(),directTls)); results.addAll(resolveIp(record,AAAA.class,result.isAuthenticData(),directTls)); - if (!addedIPv4 && !Thread.interrupted()) { + if (!addedIPv4 && !Thread.currentThread().isInterrupted()) { Result resolverResult = Result.fromRecord(record, directTls); resolverResult.authenticated = resolverResult.isAuthenticated(); results.add(resolverResult); @@ -74,12 +75,12 @@ public class Resolver { } private static List resolveIp(SRV srv, Class type, boolean authenticated, boolean directTls) { - if (Thread.interrupted()) { + if (Thread.currentThread().isInterrupted()) { return Collections.emptyList(); } List list = new ArrayList<>(); try { - ResolverResult results = resolveWithFallback(srv.name,type); + ResolverResult results = resolveWithFallback(srv.name,type, !authenticated); for (D record : results.getAnswersOrEmptySet()) { Result resolverResult = Result.fromRecord(srv, directTls); resolverResult.authenticated = results.isAuthenticData() && authenticated; @@ -92,22 +93,52 @@ public class Resolver { return list; } + private static List resolveFallback(DNSName dnsName) { + List results = new ArrayList<>(); + try { + for(A a : resolveWithFallback(dnsName,A.class,true).getAnswersOrEmptySet()) { + results.add(Result.createDefault(dnsName,a.getInetAddress())); + } + for(AAAA aaaa : resolveWithFallback(dnsName,AAAA.class,true).getAnswersOrEmptySet()) { + results.add(Result.createDefault(dnsName,aaaa.getInetAddress())); + } + if (results.size() == 0) { + for (CNAME cname : resolveWithFallback(dnsName, CNAME.class, true).getAnswersOrEmptySet()) { + results.addAll(resolveFallback(cname.name)); + } + } + } catch (IOException e) { + Log.d(Config.LOGTAG,"error resolving fallback records "+e); + } + if (results.size() == 0) { + results.add(Result.createDefault(dnsName)); + } + return results; + } + private static ResolverResult resolveWithFallback(DNSName dnsName, Class type) throws IOException { + return resolveWithFallback(dnsName,type,false); + } + + private static ResolverResult resolveWithFallback(DNSName dnsName, Class type, boolean skipDnssec) throws IOException { + if (skipDnssec) { + return ResolverApi.INSTANCE.resolve(dnsName, type); + } try { final ResolverResult r = DnssecResolverApi.INSTANCE.resolveDnssecReliable(dnsName, type); if (r.wasSuccessful()) { if (r.getAnswers().isEmpty() && type.equals(SRV.class)) { - Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": resolving SRV records of "+dnsName.toString()+" with DNSSEC yielded empty result"); + Log.d(Config.LOGTAG, Resolver.class.getSimpleName() + ": resolving SRV records of " + dnsName.toString() + " with DNSSEC yielded empty result"); } return r; } - Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving "+type.getSimpleName()+" with DNSSEC. Trying DNS instead.",r.getResolutionUnsuccessfulException()); + Log.d(Config.LOGTAG, Resolver.class.getSimpleName() + ": error resolving " + type.getSimpleName() + " with DNSSEC. Trying DNS instead.", r.getResolutionUnsuccessfulException()); } catch (DNSSECResultNotAuthenticException e) { - Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving "+type.getSimpleName()+" with DNSSEC. Trying DNS instead.",e); + Log.d(Config.LOGTAG, Resolver.class.getSimpleName() + ": error resolving " + type.getSimpleName() + " with DNSSEC. Trying DNS instead.", e); } catch (IOException e) { throw e; } catch (Throwable throwable) { - Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving "+type.getSimpleName()+" with DNSSEC. Trying DNS instead.",throwable); + Log.d(Config.LOGTAG, Resolver.class.getSimpleName() + ": error resolving " + type.getSimpleName() + " with DNSSEC. Trying DNS instead.", throwable); } return ResolverApi.INSTANCE.resolve(dnsName, type); } @@ -184,12 +215,17 @@ public class Resolver { return result; } - public static Result createDefault(String domain) { + public static Result createDefault(DNSName hostname, InetAddress ip) { Result result = new Result(); result.port = 5222; - result.hostname = DNSName.from(domain); + result.hostname = hostname; + result.ip = ip; return result; } + + public static Result createDefault(DNSName hostname) { + return createDefault(hostname,null); + } } }