[BUGFIX] Resolver: fallback for invalid SRV CNAME entries

This commit is contained in:
genofire 2020-02-10 00:57:58 +01:00
parent a1ab687f6e
commit 109d38e1b1
No known key found for this signature in database
GPG Key ID: 9D7D3C6BFF600C6A
1 changed files with 38 additions and 2 deletions

View File

@ -172,6 +172,9 @@ public class Resolver {
ResolverResult<SRV> result = resolveWithFallback(dnsName, SRV.class); ResolverResult<SRV> result = resolveWithFallback(dnsName, SRV.class);
final List<Result> results = new ArrayList<>(); final List<Result> results = new ArrayList<>();
final List<Thread> threads = new ArrayList<>(); final List<Thread> threads = new ArrayList<>();
final List<Result> fallbackResults = new ArrayList<>();
final List<Thread> fallbackThreads = new ArrayList<>();
for (SRV record : result.getAnswersOrEmptySet()) { for (SRV record : result.getAnswersOrEmptySet()) {
if (record.name.length() == 0) { if (record.name.length() == 0) {
continue; continue;
@ -188,6 +191,22 @@ public class Resolver {
results.addAll(ipv4s); results.addAll(ipv4s);
} }
})); }));
fallbackThreads.add(new Thread(() -> {
try {
for (CNAME cname : resolveWithFallback(record.name, CNAME.class, result.isAuthenticData()).getAnswersOrEmptySet()) {
final List<Result> ipv6s = resolveIp(record, cname.name, AAAA.class, result.isAuthenticData(), directTls);
synchronized (fallbackResults) {
fallbackResults.addAll(ipv6s);
}
final List<Result> 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) { for (Thread thread : threads) {
thread.start(); thread.start();
@ -199,13 +218,30 @@ public class Resolver {
return Collections.emptyList(); 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 <D extends InternetAddressRR> List<Result> resolveIp(SRV srv, Class<D> type, boolean authenticated, boolean directTls) { private static <D extends InternetAddressRR> List<Result> resolveIp(SRV srv, Class<D> type, boolean authenticated, boolean directTls) {
return resolveIp(srv, srv.name, type, authenticated, directTls);
}
private static <D extends InternetAddressRR> List<Result> resolveIp(SRV srv, DNSName hostname, Class<D> type, boolean authenticated, boolean directTls) {
List<Result> list = new ArrayList<>(); List<Result> list = new ArrayList<>();
try { try {
ResolverResult<D> results = resolveWithFallback(srv.name, type, authenticated); ResolverResult<D> results = resolveWithFallback(hostname, type, authenticated);
for (D record : results.getAnswersOrEmptySet()) { for (D record : results.getAnswersOrEmptySet()) {
Result resolverResult = Result.fromRecord(srv, directTls); Result resolverResult = Result.fromRecord(srv, directTls);
resolverResult.authenticated = results.isAuthenticData() && authenticated; resolverResult.authenticated = results.isAuthenticData() && authenticated;