From 225cca456643945732c73f8314760ae0f967154c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 2 Aug 2017 18:58:51 +0200 Subject: [PATCH] provide extra 'network is unreachable' account state --- .../siacs/conversations/entities/Account.java | 5 ++- .../siacs/conversations/utils/Resolver.java | 33 +++++++++++++++++-- .../conversations/xmpp/XmppConnection.java | 3 +- src/main/res/values/strings.xml | 1 + 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index c5c7762a2..fb06de7d0 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -132,7 +132,8 @@ public class Account extends AbstractEntity { POLICY_VIOLATION(true), REGISTRATION_PASSWORD_TOO_WEAK(true), PAYMENT_REQUIRED(true), - MISSING_INTERNET_PERMISSION(true); + MISSING_INTERNET_PERMISSION(true), + NETWORK_IS_UNREACHABLE(false); private final boolean isError; @@ -200,6 +201,8 @@ public class Account extends AbstractEntity { return R.string.payment_required; case MISSING_INTERNET_PERMISSION: return R.string.missing_internet_permission; + case NETWORK_IS_UNREACHABLE: + return R.string.network_is_unreachable; default: return R.string.account_status_unknown; } diff --git a/src/main/java/eu/siacs/conversations/utils/Resolver.java b/src/main/java/eu/siacs/conversations/utils/Resolver.java index 57c1a08d1..0298a6dfe 100644 --- a/src/main/java/eu/siacs/conversations/utils/Resolver.java +++ b/src/main/java/eu/siacs/conversations/utils/Resolver.java @@ -9,6 +9,7 @@ import java.net.Inet4Address; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; 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.InternetAddressRR; import de.measite.minidns.record.SRV; +import de.measite.minidns.util.MultipleIoException; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; 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 STARTTLS_SERICE = "_xmpp-client"; + private static final String NETWORK_IS_UNREACHABLE = "Network is unreachable"; + private static XmppConnectionService SERVICE = null; @@ -44,19 +48,27 @@ public class Resolver { DNSClient.addDnsServerLookupMechanism(new AndroidUsingLinkProperties(context)); } - public static List resolve(String domain) { + public static List resolve(String domain) throws NetworkIsUnreachableException { List results = new ArrayList<>(); + HashSet messages = new HashSet<>(); try { - results.addAll(resolveSrv(domain,true)); + results.addAll(resolveSrv(domain, true)); + } catch (MultipleIoException e) { + messages.addAll(extractMessages(e)); } catch (Throwable throwable) { Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving SRV record (direct TLS)",throwable); } try { - results.addAll(resolveSrv(domain,false)); + results.addAll(resolveSrv(domain, false)); + } catch (MultipleIoException e) { + messages.addAll(extractMessages(e)); } catch (Throwable throwable) { Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": error resolving SRV record (STARTTLS)",throwable); } if (results.size() == 0) { + if (messages.size() == 1 && messages.contains(NETWORK_IS_UNREACHABLE)) { + throw new NetworkIsUnreachableException(); + } results.addAll(resolveNoSrvRecords(DNSName.from(domain),true)); } Collections.sort(results); @@ -64,6 +76,18 @@ public class Resolver { return results; } + private static HashSet extractMessages(MultipleIoException e) { + HashSet 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 resolveSrv(String domain, final boolean directTls) throws IOException { if (Thread.currentThread().isInterrupted()) { return Collections.emptyList(); @@ -239,5 +263,8 @@ public class Resolver { return createDefault(hostname,null); } } + public static class NetworkIsUnreachableException extends Exception { + + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 49bddc61e..899a6b283 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -16,7 +16,6 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.math.BigInteger; import java.net.ConnectException; import java.net.IDN; import java.net.InetAddress; @@ -420,6 +419,8 @@ public class XmppConnection implements Runnable { this.changeStatus(Account.State.MISSING_INTERNET_PERMISSION); } catch(final StateChangingException e) { this.changeStatus(e.state); + } catch (final Resolver.NetworkIsUnreachableException e) { + this.changeStatus(Account.State.NETWORK_IS_UNREACHABLE); } catch (final UnknownHostException | ConnectException e) { this.changeStatus(Account.State.SERVER_NOT_FOUND); } catch (final SocksSocketFactory.SocksProxyNotFoundException e) { diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 8644c20b8..8bff972de 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -759,4 +759,5 @@ Yesterday Validate hostname with DNSSEC Server certificates that contain the validated hostname are considered verified + Network is unreachable