clean up connection code. unify domain = ip and extended connection settings into fake resolver
This commit is contained in:
parent
f162458323
commit
526c9de0f5
2 changed files with 54 additions and 69 deletions
|
@ -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<Result> 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<Result> resolve(String domain) {
|
||||
final List<Result> ipResults = fromIpAddress(domain);
|
||||
if (ipResults.size() > 0) {
|
||||
return ipResults;
|
||||
}
|
||||
final List<Result> results = new ArrayList<>();
|
||||
final List<Result> 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<Result> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
try {
|
||||
startXmpp(localSocket);
|
||||
} catch (InterruptedException e) {
|
||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": thread was interrupted before beginning stream");
|
||||
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");
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
final String domain = account.getJid().getDomain();
|
||||
List<Resolver.Result> results = Resolver.resolve(account.getJid().getDomain());
|
||||
Resolver.Result storedBackupResult;
|
||||
if (!Thread.currentThread().isInterrupted()) {
|
||||
final List<Resolver.Result> results;
|
||||
final boolean hardcoded = extended && !account.getHostname().isEmpty();
|
||||
if (hardcoded) {
|
||||
results = Resolver.fromHardCoded(account.getHostname(), account.getPort());
|
||||
} else {
|
||||
results = Resolver.resolve(domain);
|
||||
}
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": Thread was interrupted");
|
||||
return;
|
||||
}
|
||||
if (results.size() == 0) {
|
||||
Log.e(Config.LOGTAG, account.getJid().asBareJid() + ": Resolver results were empty");
|
||||
return;
|
||||
}
|
||||
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<Resolver.Result> 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);
|
||||
|
|
Reference in a new issue