From 526c9de0f5b562487e27b43b661b9ebf1f431972 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Tue, 2 Oct 2018 22:09:17 +0200 Subject: clean up connection code. unify domain = ip and extended connection settings into fake resolver --- .../java/de/pixart/messenger/utils/Resolver.java | 37 ++++++++-- .../de/pixart/messenger/xmpp/XmppConnection.java | 80 ++++++---------------- 2 files changed, 51 insertions(+), 66 deletions(-) diff --git a/src/main/java/de/pixart/messenger/utils/Resolver.java b/src/main/java/de/pixart/messenger/utils/Resolver.java index e159c3dd0..a1bd22d36 100644 --- a/src/main/java/de/pixart/messenger/utils/Resolver.java +++ b/src/main/java/de/pixart/messenger/utils/Resolver.java @@ -63,14 +63,26 @@ public class Resolver { final Field useHardcodedDnsServers = DNSClient.class.getDeclaredField("useHardcodedDnsServers"); useHardcodedDnsServers.setAccessible(true); useHardcodedDnsServers.setBoolean(dnsClient, false); - } catch (NoSuchFieldException e) { - Log.e(Config.LOGTAG, "Unable to disable hardcoded DNS servers", e); - } catch (IllegalAccessException e) { + } catch (NoSuchFieldException | IllegalAccessException e) { Log.e(Config.LOGTAG, "Unable to disable hardcoded DNS servers", e); } } + public static List fromHardCoded(String hostname, int port) { + Result result = new Result(); + result.hostname = DNSName.from(hostname); + result.port = port; + result.directTls = port == 443 || port == 5223; + result.authenticated = true; + return Collections.singletonList(result); + } + + public static List resolve(String domain) { + final List ipResults = fromIpAddress(domain); + if (ipResults.size() > 0) { + return ipResults; + } final List results = new ArrayList<>(); final List fallbackResults = new ArrayList<>(); Thread[] threads = new Thread[3]; @@ -125,9 +137,21 @@ public class Resolver { for (Thread thread : threads) { thread.interrupt(); } - synchronized (results) { - return new ArrayList<>(results); - } + return Collections.emptyList(); + } + } + + private static List fromIpAddress(String domain) { + if (!IP.matches(domain)) { + return Collections.emptyList(); + } + try { + Result result = new Result(); + result.ip = InetAddress.getByName(domain); + result.port = 5222; + return Collections.singletonList(result); + } catch (UnknownHostException e) { + return Collections.emptyList(); } } @@ -377,5 +401,4 @@ public class Resolver { return contentValues; } } - } \ No newline at end of file diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java index cd2a13bd4..57daed31f 100644 --- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java +++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java @@ -48,7 +48,6 @@ import java.util.regex.Matcher; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509KeyManager; @@ -77,7 +76,6 @@ import de.pixart.messenger.services.NotificationService; import de.pixart.messenger.services.XmppConnectionService; import de.pixart.messenger.ui.EditAccountActivity; import de.pixart.messenger.utils.CryptoHelper; -import de.pixart.messenger.utils.IP; import de.pixart.messenger.utils.Namespace; import de.pixart.messenger.utils.Patterns; import de.pixart.messenger.utils.Resolver; @@ -304,69 +302,32 @@ public class XmppConnection implements Runnable { } catch (Exception e) { throw new IOException(e.getMessage()); } - } else if (extended && !account.getHostname().isEmpty()) { - - this.verifiedHostname = account.getHostname(); - - try { - InetSocketAddress address = new InetSocketAddress(this.verifiedHostname, account.getPort()); - features.encryptionEnabled = address.getPort() == 5223; - if (features.encryptionEnabled) { - try { - final TlsFactoryVerifier tlsFactoryVerifier = getTlsFactoryVerifier(); - localSocket = tlsFactoryVerifier.factory.createSocket(); - localSocket.connect(address, Config.SOCKET_TIMEOUT * 1000); - final SSLSession session = ((SSLSocket) localSocket).getSession(); - final String domain = account.getJid().getDomain(); - if (!tlsFactoryVerifier.verifier.verify(domain, this.verifiedHostname, session)) { - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS certificate verification failed"); - throw new StateChangingException(Account.State.TLS_ERROR); - } - } catch (KeyManagementException e) { - throw new StateChangingException(Account.State.TLS_ERROR); - } - } else { - localSocket = new Socket(); - localSocket.connect(address, Config.SOCKET_TIMEOUT * 1000); - } - } catch (IOException | IllegalArgumentException e) { - throw new UnknownHostException(); + } else { + final String domain = account.getJid().getDomain(); + final List results; + final boolean hardcoded = extended && !account.getHostname().isEmpty(); + if (hardcoded) { + results = Resolver.fromHardCoded(account.getHostname(), account.getPort()); + } else { + results = Resolver.resolve(domain); } - try { - startXmpp(localSocket); - } catch (InterruptedException e) { - Log.d(Config.LOGTAG,account.getJid().asBareJid()+": thread was interrupted before beginning stream"); + if (Thread.currentThread().isInterrupted()) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": Thread was interrupted"); return; - } catch (Exception e) { - throw new IOException(e.getMessage()); - } - } else if (IP.matches(account.getServer())) { - localSocket = new Socket(); - try { - localSocket.connect(new InetSocketAddress(account.getServer(), 5222), Config.SOCKET_TIMEOUT * 1000); - } catch (IOException e) { - throw new UnknownHostException(); } - try { - startXmpp(localSocket); - } catch (InterruptedException e) { - Log.d(Config.LOGTAG,account.getJid().asBareJid()+": thread was interrupted before beginning stream"); + if (results.size() == 0) { + Log.e(Config.LOGTAG, account.getJid().asBareJid() + ": Resolver results were empty"); return; - } catch (Exception e) { - throw new IOException(e.getMessage()); } - } else { - final String domain = account.getJid().getDomain(); - List results = Resolver.resolve(account.getJid().getDomain()); - Resolver.Result storedBackupResult; - if (!Thread.currentThread().isInterrupted()) { + final Resolver.Result storedBackupResult; + if (hardcoded) { + storedBackupResult = null; + } else { storedBackupResult = mXmppConnectionService.databaseBackend.findResolverResult(domain); if (storedBackupResult != null && !results.contains(storedBackupResult)) { results.add(storedBackupResult); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": loaded backup resolver result from db: " + storedBackupResult); } - } else { - storedBackupResult = null; } for (Iterator iterator = results.iterator(); iterator.hasNext(); ) { final Resolver.Result result = iterator.next(); @@ -378,16 +339,17 @@ public class XmppConnection implements Runnable { // if tls is true, encryption is implied and must not be started 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 dns " + result.getHostname().toString() - + "/" + result.getIp().getHostAddress() + ":" + result.getPort() + " tls: " + features.encryptionEnabled); + + ": 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 dns " + + ": using values from resolver " + result.getHostname().toString() + ":" + result.getPort() + " tls: " + features.encryptionEnabled); } @@ -449,7 +411,7 @@ public class XmppConnection implements Runnable { this.changeStatus(Account.State.SERVER_NOT_FOUND); } catch (final SocksSocketFactory.SocksProxyNotFoundException e) { this.changeStatus(Account.State.TOR_NOT_AVAILABLE); - } catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) { + } catch (final IOException | XmlPullParserException e) { Log.d(Config.LOGTAG, account.getJid().asBareJid().toString() + ": " + e.getMessage()); this.changeStatus(Account.State.OFFLINE); this.attempt = Math.max(0, this.attempt - 1); -- cgit v1.2.3