From e140ab713ee7270b9e53f9e69f858af796cd3892 Mon Sep 17 00:00:00 2001 From: Martin/Geno Date: Sat, 10 Nov 2018 23:56:09 +0100 Subject: [PATCH] Networkstack - let OS decide IPv4 or IPv6 --- .../persistance/DatabaseBackend.java | 1 - .../siacs/conversations/utils/Resolver.java | 118 +++--------------- .../conversations/xmpp/XmppConnection.java | 16 +-- 3 files changed, 20 insertions(+), 115 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 34758fe3e..8bac9e341 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -156,7 +156,6 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static String CREATE_RESOLVER_RESULTS_TABLE = "create table " + RESOLVER_RESULTS_TABLENAME + "(" + Resolver.Result.DOMAIN + " TEXT," + Resolver.Result.HOSTNAME + " TEXT," - + Resolver.Result.IP + " BLOB," + Resolver.Result.PRIORITY + " NUMBER," + Resolver.Result.DIRECT_TLS + " NUMBER," + Resolver.Result.AUTHENTICATED + " NUMBER," diff --git a/src/main/java/eu/siacs/conversations/utils/Resolver.java b/src/main/java/eu/siacs/conversations/utils/Resolver.java index 96ce63c90..5a63a97b4 100644 --- a/src/main/java/eu/siacs/conversations/utils/Resolver.java +++ b/src/main/java/eu/siacs/conversations/utils/Resolver.java @@ -7,9 +7,6 @@ import android.util.Log; import java.io.IOException; import java.lang.reflect.Field; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -25,11 +22,8 @@ import de.measite.minidns.hla.DnssecResolverApi; import de.measite.minidns.hla.ResolverApi; import de.measite.minidns.hla.ResolverResult; import de.measite.minidns.iterative.ReliableDNSClient; -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; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; @@ -40,7 +34,7 @@ public class Resolver { public static final int DEFAULT_PORT_XMPP = 5222; 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; @@ -83,7 +77,7 @@ public class Resolver { public static List resolve(String domain) { - final List ipResults = fromIpAddress(domain); + final List ipResults = fromIpAddress(domain); if (ipResults.size() > 0) { return ipResults; } @@ -149,91 +143,41 @@ public class Resolver { if (!IP.matches(domain)) { return Collections.emptyList(); } - try { - Result result = new Result(); - result.ip = InetAddress.getByName(domain); - result.port = DEFAULT_PORT_XMPP; - return Collections.singletonList(result); - } catch (UnknownHostException e) { - return Collections.emptyList(); - } + return Collections.singletonList(Result.createDefault(DNSName.from(domain))); } private static List 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 result = resolveWithFallback(dnsName, SRV.class); final List results = new ArrayList<>(); - final List threads = new ArrayList<>(); for (SRV record : result.getAnswersOrEmptySet()) { if (record.name.length() == 0 && record.priority == 0) { continue; } - threads.add(new Thread(() -> { - final List 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); - } + Result resolverResult = Result.fromRecord(record, directTls); + resolverResult.authenticated = result.isAuthenticData(); + results.add(resolverResult); + } - })); - threads.add(new Thread(() -> { - final List ipv6s = resolveIp(record, AAAA.class, result.isAuthenticData(), directTls); - synchronized (results) { - results.addAll(ipv6s); - } - })); - } - for (Thread thread : threads) { - thread.start(); - } - for (Thread thread : threads) { - try { - thread.join(); - } catch (InterruptedException e) { - return Collections.emptyList(); - } - } return results; } - private static List resolveIp(SRV srv, Class type, boolean authenticated, boolean directTls) { - List list = new ArrayList<>(); - try { - ResolverResult results = resolveWithFallback(srv.name, type, authenticated); - for (D record : results.getAnswersOrEmptySet()) { - Result resolverResult = Result.fromRecord(srv, directTls); - resolverResult.authenticated = results.isAuthenticData() && authenticated; - resolverResult.ip = record.getInetAddress(); - list.add(resolverResult); - } - } catch (Throwable t) { - Log.d(Config.LOGTAG, Resolver.class.getSimpleName() + ": error resolving " + type.getSimpleName() + " " + t.getMessage()); - } - return list; - } - private static List resolveNoSrvRecords(DNSName dnsName, boolean withCnames) { List results = new ArrayList<>(); + Boolean resolveCNAME = false; 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())); - } - if (results.size() == 0 && withCnames) { + if (withCnames) { for (CNAME cname : resolveWithFallback(dnsName, CNAME.class, false).getAnswersOrEmptySet()) { results.addAll(resolveNoSrvRecords(cname.name, false)); + resolveCNAME = true; } } } catch (Throwable throwable) { Log.d(Config.LOGTAG, Resolver.class.getSimpleName() + "error resolving fallback records", throwable); } - results.add(Result.createDefault(dnsName)); + if(!resolveCNAME) { + results.add(Result.createDefault(dnsName)); + } return results; } @@ -264,13 +208,11 @@ public class Resolver { public static class Result implements Comparable { public static final String DOMAIN = "domain"; - public static final String IP = "ip"; public static final String HOSTNAME = "hostname"; public static final String PORT = "port"; public static final String PRIORITY = "priority"; public static final String DIRECT_TLS = "directTls"; public static final String AUTHENTICATED = "authenticated"; - private InetAddress ip; private DNSName hostname; private int port = DEFAULT_PORT_XMPP; private boolean directTls = false; @@ -286,25 +228,15 @@ public class Resolver { return result; } - static Result createDefault(DNSName hostname, InetAddress ip) { + static Result createDefault(DNSName hostname) { Result result = new Result(); result.port = DEFAULT_PORT_XMPP; result.hostname = hostname; - result.ip = ip; return result; } - static Result createDefault(DNSName hostname) { - return createDefault(hostname, null); - } - public static Result fromCursor(Cursor cursor) { final Result result = new Result(); - try { - result.ip = InetAddress.getByAddress(cursor.getBlob(cursor.getColumnIndex(IP))); - } catch (UnknownHostException e) { - result.ip = null; - } final String hostname = cursor.getString(cursor.getColumnIndex(HOSTNAME)); result.hostname = hostname == null ? null : DNSName.from(hostname); result.port = cursor.getInt(cursor.getColumnIndex(PORT)); @@ -325,14 +257,12 @@ public class Resolver { if (directTls != result.directTls) return false; if (authenticated != result.authenticated) return false; if (priority != result.priority) return false; - if (ip != null ? !ip.equals(result.ip) : result.ip != null) return false; return hostname != null ? hostname.equals(result.hostname) : result.hostname == null; } @Override public int hashCode() { - int result = ip != null ? ip.hashCode() : 0; - result = 31 * result + (hostname != null ? hostname.hashCode() : 0); + int result = hostname != null ? hostname.hashCode() : 0; result = 31 * result + port; result = 31 * result + (directTls ? 1 : 0); result = 31 * result + (authenticated ? 1 : 0); @@ -340,10 +270,6 @@ public class Resolver { return result; } - public InetAddress getIp() { - return ip; - } - public int getPort() { return port; } @@ -363,7 +289,6 @@ public class Resolver { @Override public String toString() { return "Result{" + - "ip='" + (ip == null ? null : ip.getHostAddress()) + '\'' + ", hostame='" + hostname.toString() + '\'' + ", port=" + port + ", directTls=" + directTls + @@ -376,17 +301,7 @@ public class Resolver { public int compareTo(@NonNull Result result) { if (result.priority == priority) { if (directTls == result.directTls) { - 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; - } - } else { - return ip != null ? -1 : 1; - } } else { return directTls ? -1 : 1; } @@ -397,7 +312,6 @@ public class Resolver { public ContentValues toContentValues() { final ContentValues contentValues = new ContentValues(); - contentValues.put(IP, ip == null ? null : ip.getAddress()); contentValues.put(HOSTNAME, hostname == null ? null : hostname.toString()); contentValues.put(PORT, port); contentValues.put(PRIORITY, priority); diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 1cb046495..74be956e2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -314,18 +314,10 @@ public class XmppConnection implements Runnable { features.encryptionEnabled = result.isDirectTls(); verifiedHostname = result.isAuthenticated() ? result.getHostname().toString() : null; Log.d(Config.LOGTAG,"verified hostname "+verifiedHostname); - final InetSocketAddress addr; - if (result.getIp() != null) { - addr = new InetSocketAddress(result.getIp(), result.getPort()); - Log.d(Config.LOGTAG, account.getJid().asBareJid().toString() - + ": using values from resolver " + (result.getHostname() == null ? "" : result.getHostname().toString() - + "/") + result.getIp().getHostAddress() + ":" + result.getPort() + " tls: " + features.encryptionEnabled); - } else { - addr = new InetSocketAddress(IDN.toASCII(result.getHostname().toString()), result.getPort()); - Log.d(Config.LOGTAG, account.getJid().asBareJid().toString() - + ": using values from resolver " - + result.getHostname().toString() + ":" + result.getPort() + " tls: " + features.encryptionEnabled); - } + final InetSocketAddress addr = new InetSocketAddress(IDN.toASCII(result.getHostname().toString()), result.getPort()); + Log.d(Config.LOGTAG, account.getJid().asBareJid().toString() + + ": using values from resolver " + + result.getHostname().toString() + ":" + result.getPort() + " tls: " + features.encryptionEnabled); if (!features.encryptionEnabled) { localSocket = new Socket();