let DnsHelper provide a fallback solution

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/utils/DNSHelper.java     |  9 
src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 75 ++--
2 files changed, 41 insertions(+), 43 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/utils/DNSHelper.java 🔗

@@ -7,6 +7,7 @@ import android.net.LinkProperties;
 import android.net.Network;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Parcelable;
 import android.util.Log;
 
 import java.io.IOException;
@@ -46,13 +47,19 @@ public class DNSHelper {
 	public static Bundle getSRVRecord(final Jid jid, Context context) throws IOException {
         final String host = jid.getDomainpart();
 		final List<InetAddress> servers = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDnsServers(context) : getDnsServersPreLollipop();
-		Bundle b = null;
+		Bundle b = new Bundle();
 		for(InetAddress server : servers) {
 			b = queryDNS(host, server);
 			if (b.containsKey("values")) {
 				return b;
 			}
 		}
+		if (!b.containsKey("values")) {
+			Log.d(Config.LOGTAG,"all dns queries failed. provide fallback A record");
+			ArrayList<Parcelable> values = new ArrayList<>();
+			values.add(createNamePortBundle(host,5222));
+			b.putParcelableArrayList("values",values);
+		}
 		return b;
 	}
 

src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java 🔗

@@ -160,52 +160,43 @@ public class XmppConnection implements Runnable {
 				}
 			} else {
 				final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService);
-				if (result == null) {
-					throw new IOException("unhandled exception in DNS resolver");
-				}
 				final ArrayList<Parcelable> values = result.getParcelableArrayList("values");
-				if ("timeout".equals(result.getString("error"))) {
-					throw new DnsTimeoutException();
-				} else if (values != null) {
-					int i = 0;
-					boolean socketError = true;
-					while (socketError && values.size() > i) {
-						final Bundle namePort = (Bundle) values.get(i);
+				int i = 0;
+				boolean socketError = true;
+				while (socketError && values.size() > i) {
+					final Bundle namePort = (Bundle) values.get(i);
+					try {
+						String srvRecordServer;
 						try {
-							String srvRecordServer;
-							try {
-								srvRecordServer = IDN.toASCII(namePort.getString("name"));
-							} catch (final IllegalArgumentException e) {
-								// TODO: Handle me?`
-								srvRecordServer = "";
-							}
-							final int srvRecordPort = namePort.getInt("port");
-							final String srvIpServer = namePort.getString("ip");
-							final InetSocketAddress addr;
-							if (srvIpServer != null) {
-								addr = new InetSocketAddress(srvIpServer, srvRecordPort);
-								Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
-										+ ": using values from dns " + srvRecordServer
-										+ "[" + srvIpServer + "]:" + srvRecordPort);
-							} else {
-								addr = new InetSocketAddress(srvRecordServer, srvRecordPort);
-								Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
-										+ ": using values from dns "
-										+ srvRecordServer + ":" + srvRecordPort);
-							}
-							socket = new Socket();
-							socket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
-							socketError = false;
-						} catch (final Throwable e) {
-							Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
-							i++;
+							srvRecordServer = IDN.toASCII(namePort.getString("name"));
+						} catch (final IllegalArgumentException e) {
+							// TODO: Handle me?`
+							srvRecordServer = "";
 						}
+						final int srvRecordPort = namePort.getInt("port");
+						final String srvIpServer = namePort.getString("ip");
+						final InetSocketAddress addr;
+						if (srvIpServer != null) {
+							addr = new InetSocketAddress(srvIpServer, srvRecordPort);
+							Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+									+ ": using values from dns " + srvRecordServer
+									+ "[" + srvIpServer + "]:" + srvRecordPort);
+						} else {
+							addr = new InetSocketAddress(srvRecordServer, srvRecordPort);
+							Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+									+ ": using values from dns "
+									+ srvRecordServer + ":" + srvRecordPort);
+						}
+						socket = new Socket();
+						socket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
+						socketError = false;
+					} catch (final Throwable e) {
+						Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
+						i++;
 					}
-					if (socketError) {
-						throw new UnknownHostException();
-					}
-				} else {
-					throw new IOException("unhandled exception in DNS resolver");
+				}
+				if (socketError) {
+					throw new UnknownHostException();
 				}
 			}
 			final OutputStream out = socket.getOutputStream();