Merge branch 'ipv6-fix' into 'develop'

Search for best connection (FIX IPv6)

See merge request sum7/Conversations!2
This commit is contained in:
Martin/Geno 2018-11-11 01:37:03 +01:00
commit 720f4d3253
1 changed files with 45 additions and 22 deletions

View File

@ -7,8 +7,9 @@ import android.util.Log;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
@ -38,7 +39,7 @@ import eu.siacs.conversations.services.XmppConnectionService;
public class Resolver {
private static final String DIRECT_TLS_SERVICE = "_xmpps-client";
private static final String STARTTLS_SERICE = "_xmpp-client";
private static final String STARTTLS_SERVICE = "_xmpp-client";
private static XmppConnectionService SERVICE = null;
@ -156,7 +157,7 @@ public class Resolver {
}
private static List<Result> resolveSrv(String domain, final boolean directTls) throws IOException {
DNSName dnsName = DNSName.from((directTls ? DIRECT_TLS_SERVICE : STARTTLS_SERICE) + "._tcp." + domain);
DNSName dnsName = DNSName.from((directTls ? DIRECT_TLS_SERVICE : STARTTLS_SERVICE) + "._tcp." + domain);
ResolverResult<SRV> result = resolveWithFallback(dnsName, SRV.class);
final List<Result> results = new ArrayList<>();
final List<Thread> threads = new ArrayList<>();
@ -164,24 +165,19 @@ public class Resolver {
if (record.name.length() == 0 && record.priority == 0) {
continue;
}
threads.add(new Thread(() -> {
final List<Result> ipv4s = resolveIp(record, A.class, result.isAuthenticData(), directTls);
if (ipv4s.size() == 0) {
Result resolverResult = Result.fromRecord(record, directTls);
resolverResult.authenticated = resolverResult.isAuthenticated();
ipv4s.add(resolverResult);
}
synchronized (results) {
results.addAll(ipv4s);
}
}));
threads.add(new Thread(() -> {
final List<Result> ipv6s = resolveIp(record, AAAA.class, result.isAuthenticData(), directTls);
synchronized (results) {
results.addAll(ipv6s);
}
}));
threads.add(new Thread(() -> {
final List<Result> ipv4s = resolveIp(record, A.class, result.isAuthenticData(), directTls);
synchronized (results) {
results.addAll(ipv4s);
}
}));
}
for (Thread thread : threads) {
thread.start();
@ -189,6 +185,16 @@ public class Resolver {
for (Thread thread : threads) {
try {
thread.join();
if (results.size() == 0) {
for (SRV record : result.getAnswersOrEmptySet()) {
if (record.name.length() == 0 && record.priority == 0) {
continue;
}
Result resolverResult = Result.fromRecord(record, directTls);
resolverResult.authenticated = resolverResult.isAuthenticated();
results.add(resolverResult);
}
}
} catch (InterruptedException e) {
return Collections.emptyList();
}
@ -204,6 +210,7 @@ public class Resolver {
Result resolverResult = Result.fromRecord(srv, directTls);
resolverResult.authenticated = results.isAuthenticData() && authenticated;
resolverResult.ip = record.getInetAddress();
resolverResult.rtt = rttTo(resolverResult.ip,resolverResult.port);
list.add(resolverResult);
}
} catch (Throwable t) {
@ -215,12 +222,12 @@ public class Resolver {
private static List<Result> resolveNoSrvRecords(DNSName dnsName, boolean withCnames) {
List<Result> results = new ArrayList<>();
try {
for (A a : resolveWithFallback(dnsName, A.class, false).getAnswersOrEmptySet()) {
results.add(Result.createDefault(dnsName, a.getInetAddress()));
}
for (AAAA aaaa : resolveWithFallback(dnsName, AAAA.class, false).getAnswersOrEmptySet()) {
results.add(Result.createDefault(dnsName, aaaa.getInetAddress()));
}
for (A a : resolveWithFallback(dnsName, A.class, false).getAnswersOrEmptySet()) {
results.add(Result.createDefault(dnsName, a.getInetAddress()));
}
if (results.size() == 0 && withCnames) {
for (CNAME cname : resolveWithFallback(dnsName, CNAME.class, false).getAnswersOrEmptySet()) {
results.addAll(resolveNoSrvRecords(cname.name, false));
@ -254,6 +261,18 @@ public class Resolver {
return ResolverApi.INSTANCE.resolve(question);
}
private static long rttTo(InetAddress ip, int port){
long time = System.currentTimeMillis();
try (Socket s = new Socket()) {
s.connect(new InetSocketAddress(ip, port), 200);
s.close();
return System.currentTimeMillis() - time;
}catch (Exception e){
Log.e(Config.LOGTAG, Resolver.class.getSimpleName() + ": error testing connection to " + (ip == null ? null : ip.getHostAddress()) + ":" + port);
return -1;
}
}
private static boolean validateHostname() {
return SERVICE != null && SERVICE.getBooleanPreference("validate_hostname", R.bool.validate_hostname);
}
@ -272,6 +291,7 @@ public class Resolver {
private boolean directTls = false;
private boolean authenticated = false;
private int priority;
private long rtt = -1;
static Result fromRecord(SRV srv, boolean directTls) {
Result result = new Result();
@ -287,6 +307,9 @@ public class Resolver {
result.port = 5222;
result.hostname = hostname;
result.ip = ip;
if (ip != null) {
result.rtt = rttTo(result.ip, result.port);
}
return result;
}
@ -365,6 +388,7 @@ public class Resolver {
", directTls=" + directTls +
", authenticated=" + authenticated +
", priority=" + priority +
", rtt=" + rtt +
'}';
}
@ -375,11 +399,10 @@ public class Resolver {
if (ip == null && result.ip == null) {
return 0;
} else if (ip != null && result.ip != null) {
if (ip instanceof Inet4Address && result.ip instanceof Inet4Address) {
return 0;
} else {
return ip instanceof Inet4Address ? -1 : 1;
if (rtt == -1 || result.rtt == -1) {
Log.e(Config.LOGTAG, Resolver.class.getSimpleName() + ": unable to read round trip time servers on compare between "+toString()+ " and "+result.toString());
}
return rtt < result.rtt ? -1 : 1;
} else {
return ip != null ? -1 : 1;
}