diff --git a/src/main/java/eu/siacs/conversations/utils/Resolver.java b/src/main/java/eu/siacs/conversations/utils/Resolver.java index d35a7ae2f..2c71afe4c 100644 --- a/src/main/java/eu/siacs/conversations/utils/Resolver.java +++ b/src/main/java/eu/siacs/conversations/utils/Resolver.java @@ -172,6 +172,9 @@ public class Resolver { ResolverResult result = resolveWithFallback(dnsName, SRV.class); final List results = new ArrayList<>(); final List threads = new ArrayList<>(); + + final List fallbackResults = new ArrayList<>(); + final List fallbackThreads = new ArrayList<>(); for (SRV record : result.getAnswersOrEmptySet()) { if (record.name.length() == 0) { continue; @@ -188,6 +191,22 @@ public class Resolver { results.addAll(ipv4s); } })); + fallbackThreads.add(new Thread(() -> { + try { + for (CNAME cname : resolveWithFallback(record.name, CNAME.class, result.isAuthenticData()).getAnswersOrEmptySet()) { + final List ipv6s = resolveIp(record, cname.name, AAAA.class, result.isAuthenticData(), directTls); + synchronized (fallbackResults) { + fallbackResults.addAll(ipv6s); + } + final List ipv4s = resolveIp(record, cname.name, A.class, result.isAuthenticData(), directTls); + synchronized (results) { + fallbackResults.addAll(ipv4s); + } + } + } catch (Throwable throwable) { + Log.d(Config.LOGTAG, Resolver.class.getSimpleName() + "error resolving srv cname-fallback records", throwable); + } + })); } for (Thread thread : threads) { thread.start(); @@ -199,13 +218,30 @@ public class Resolver { return Collections.emptyList(); } } - return results; + if (results.size() > 0) { + return results; + } + + for (Thread thread : fallbackThreads) { + thread.start(); + } + for (Thread thread : fallbackThreads) { + try { + thread.join(); + } catch (InterruptedException e) { + return Collections.emptyList(); + } + } + return fallbackResults; } private static List resolveIp(SRV srv, Class type, boolean authenticated, boolean directTls) { + return resolveIp(srv, srv.name, type, authenticated, directTls); + } + private static List resolveIp(SRV srv, DNSName hostname, Class type, boolean authenticated, boolean directTls) { List list = new ArrayList<>(); try { - ResolverResult results = resolveWithFallback(srv.name, type, authenticated); + ResolverResult results = resolveWithFallback(hostname, type, authenticated); for (D record : results.getAnswersOrEmptySet()) { Result resolverResult = Result.fromRecord(srv, directTls); resolverResult.authenticated = results.isAuthenticData() && authenticated;