provide extra 'network is unreachable' account state

This commit is contained in:
Daniel Gultsch 2017-08-02 18:58:51 +02:00
parent 4ff3c36ed9
commit 225cca4566
4 changed files with 37 additions and 5 deletions

View file

@ -132,7 +132,8 @@ public class Account extends AbstractEntity {
POLICY_VIOLATION(true), POLICY_VIOLATION(true),
REGISTRATION_PASSWORD_TOO_WEAK(true), REGISTRATION_PASSWORD_TOO_WEAK(true),
PAYMENT_REQUIRED(true), PAYMENT_REQUIRED(true),
MISSING_INTERNET_PERMISSION(true); MISSING_INTERNET_PERMISSION(true),
NETWORK_IS_UNREACHABLE(false);
private final boolean isError; private final boolean isError;
@ -200,6 +201,8 @@ public class Account extends AbstractEntity {
return R.string.payment_required; return R.string.payment_required;
case MISSING_INTERNET_PERMISSION: case MISSING_INTERNET_PERMISSION:
return R.string.missing_internet_permission; return R.string.missing_internet_permission;
case NETWORK_IS_UNREACHABLE:
return R.string.network_is_unreachable;
default: default:
return R.string.account_status_unknown; return R.string.account_status_unknown;
} }

View file

@ -9,6 +9,7 @@ import java.net.Inet4Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import de.measite.minidns.DNSClient; import de.measite.minidns.DNSClient;
@ -23,6 +24,7 @@ import de.measite.minidns.record.CNAME;
import de.measite.minidns.record.Data; import de.measite.minidns.record.Data;
import de.measite.minidns.record.InternetAddressRR; import de.measite.minidns.record.InternetAddressRR;
import de.measite.minidns.record.SRV; import de.measite.minidns.record.SRV;
import de.measite.minidns.util.MultipleIoException;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
@ -32,6 +34,8 @@ public class Resolver {
private static final String DIRECT_TLS_SERVICE = "_xmpps-client"; private static final String DIRECT_TLS_SERVICE = "_xmpps-client";
private static final String STARTTLS_SERICE = "_xmpp-client"; private static final String STARTTLS_SERICE = "_xmpp-client";
private static final String NETWORK_IS_UNREACHABLE = "Network is unreachable";
private static XmppConnectionService SERVICE = null; private static XmppConnectionService SERVICE = null;
@ -44,19 +48,27 @@ public class Resolver {
DNSClient.addDnsServerLookupMechanism(new AndroidUsingLinkProperties(context)); DNSClient.addDnsServerLookupMechanism(new AndroidUsingLinkProperties(context));
} }
public static List<Result> resolve(String domain) { public static List<Result> resolve(String domain) throws NetworkIsUnreachableException {
List<Result> results = new ArrayList<>(); List<Result> results = new ArrayList<>();
HashSet<String> messages = new HashSet<>();
try { try {
results.addAll(resolveSrv(domain,true)); results.addAll(resolveSrv(domain, true));
} catch (MultipleIoException e) {
messages.addAll(extractMessages(e));
} catch (Throwable throwable) { } catch (Throwable throwable) {
Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving SRV record (direct TLS)",throwable); Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving SRV record (direct TLS)",throwable);
} }
try { try {
results.addAll(resolveSrv(domain,false)); results.addAll(resolveSrv(domain, false));
} catch (MultipleIoException e) {
messages.addAll(extractMessages(e));
} catch (Throwable throwable) { } catch (Throwable throwable) {
Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving SRV record (STARTTLS)",throwable); Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving SRV record (STARTTLS)",throwable);
} }
if (results.size() == 0) { if (results.size() == 0) {
if (messages.size() == 1 && messages.contains(NETWORK_IS_UNREACHABLE)) {
throw new NetworkIsUnreachableException();
}
results.addAll(resolveNoSrvRecords(DNSName.from(domain),true)); results.addAll(resolveNoSrvRecords(DNSName.from(domain),true));
} }
Collections.sort(results); Collections.sort(results);
@ -64,6 +76,18 @@ public class Resolver {
return results; return results;
} }
private static HashSet<String> extractMessages(MultipleIoException e) {
HashSet<String> messages = new HashSet<>();
for(Exception inner : e.getExceptions()) {
if (inner instanceof MultipleIoException) {
messages.addAll(extractMessages((MultipleIoException) inner));
} else {
messages.add(inner.getMessage());
}
}
return messages;
}
private static List<Result> resolveSrv(String domain, final boolean directTls) throws IOException { private static List<Result> resolveSrv(String domain, final boolean directTls) throws IOException {
if (Thread.currentThread().isInterrupted()) { if (Thread.currentThread().isInterrupted()) {
return Collections.emptyList(); return Collections.emptyList();
@ -239,5 +263,8 @@ public class Resolver {
return createDefault(hostname,null); return createDefault(hostname,null);
} }
} }
public static class NetworkIsUnreachableException extends Exception {
}
} }

View file

@ -16,7 +16,6 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigInteger;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.IDN; import java.net.IDN;
import java.net.InetAddress; import java.net.InetAddress;
@ -420,6 +419,8 @@ public class XmppConnection implements Runnable {
this.changeStatus(Account.State.MISSING_INTERNET_PERMISSION); this.changeStatus(Account.State.MISSING_INTERNET_PERMISSION);
} catch(final StateChangingException e) { } catch(final StateChangingException e) {
this.changeStatus(e.state); this.changeStatus(e.state);
} catch (final Resolver.NetworkIsUnreachableException e) {
this.changeStatus(Account.State.NETWORK_IS_UNREACHABLE);
} catch (final UnknownHostException | ConnectException e) { } catch (final UnknownHostException | ConnectException e) {
this.changeStatus(Account.State.SERVER_NOT_FOUND); this.changeStatus(Account.State.SERVER_NOT_FOUND);
} catch (final SocksSocketFactory.SocksProxyNotFoundException e) { } catch (final SocksSocketFactory.SocksProxyNotFoundException e) {

View file

@ -759,4 +759,5 @@
<string name="yesterday">Yesterday</string> <string name="yesterday">Yesterday</string>
<string name="pref_validate_hostname">Validate hostname with DNSSEC</string> <string name="pref_validate_hostname">Validate hostname with DNSSEC</string>
<string name="pref_validate_hostname_summary">Server certificates that contain the validated hostname are considered verified</string> <string name="pref_validate_hostname_summary">Server certificates that contain the validated hostname are considered verified</string>
<string name="network_is_unreachable">Network is unreachable</string>
</resources> </resources>