reworked dns retry

iNPUTmice created

Change summary

src/eu/siacs/conversations/utils/DNSHelper.java     | 50 ++++-------
src/eu/siacs/conversations/xmpp/XmppConnection.java | 67 +++++++-------
2 files changed, 51 insertions(+), 66 deletions(-)

Detailed changes

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

@@ -33,7 +33,7 @@ public class DNSHelper {
 			for (String dnsserver : dns) {
 				InetAddress ip = InetAddress.getByName(dnsserver);
 				Bundle b = queryDNS(host, ip);
-				if (b.containsKey("name")) {
+				if (b.containsKey("values")) {
 					return b;
 				} else if (b.containsKey("error")
 						&& "nosrv".equals(b.getString("error", null))) {
@@ -45,7 +45,7 @@ public class DNSHelper {
 	}
 
 	public static Bundle queryDNS(String host, InetAddress dnsServer) {
-		Bundle namePort = new Bundle();
+		Bundle bundle = new Bundle();
 		try {
 			String qname = "_xmpp-client._tcp." + host;
 			Log.d(Config.LOGTAG,
@@ -133,42 +133,28 @@ public class DNSHelper {
 			}
 
 			if (result.size() == 0) {
-				namePort.putString("error", "nosrv");
-				return namePort;
+				bundle.putString("error", "nosrv");
+				return bundle;
 			}
-			// we now have a list of servers to try :-)
-
-			// classic name/port pair
-			String resultName = result.get(0).getName();
-			namePort.putString("name", resultName);
-			namePort.putInt("port", result.get(0).getPort());
-
-			if (ips4.containsKey(resultName)) {
-				// we have an ip!
-				ArrayList<String> ip = ips4.get(resultName);
-				Collections.shuffle(ip, rnd);
-				namePort.putString("ipv4", ip.get(0));
-			}
-			if (ips6.containsKey(resultName)) {
-				ArrayList<String> ip = ips6.get(resultName);
-				Collections.shuffle(ip, rnd);
-				namePort.putString("ipv6", ip.get(0));
-			}
-
-			// add all other records
-			int i = 0;
+			ArrayList<Bundle> values = new ArrayList<Bundle>();
 			for (SRV srv : result) {
-				namePort.putString("name" + i, srv.getName());
-				namePort.putInt("port" + i, srv.getPort());
-				i++;
+				Bundle namePort = new Bundle();
+				namePort.putString("name", srv.getName());
+				namePort.putInt("port", srv.getPort());
+				if (ips4.containsKey(srv.getName())) {
+					ArrayList<String> ip = ips4.get(srv.getName());
+					Collections.shuffle(ip, rnd);
+					namePort.putString("ipv4", ip.get(0));
+				}
+				values.add(namePort);
 			}
-
+			bundle.putParcelableArrayList("values", values);
 		} catch (SocketTimeoutException e) {
-			namePort.putString("error", "timeout");
+			bundle.putString("error", "timeout");
 		} catch (Exception e) {
-			namePort.putString("error", "unhandled");
+			bundle.putString("error", "unhandled");
 		}
-		return namePort;
+		return bundle;
 	}
 
 	final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

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

@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.math.BigInteger;
+import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.UnknownHostException;
 import java.security.KeyManagementException;
@@ -32,6 +33,7 @@ import de.duenndns.ssl.MemorizingTrustManager;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.os.Parcelable;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.SystemClock;
@@ -155,50 +157,47 @@ public class XmppConnection implements Runnable {
 			tagWriter = new TagWriter();
 			packetCallbacks.clear();
 			this.changeStatus(Account.STATUS_CONNECTING);
-			Bundle namePort = DNSHelper.getSRVRecord(account.getServer());
-			if ("timeout".equals(namePort.getString("error"))) {
+			Bundle result = DNSHelper.getSRVRecord(account.getServer());
+			ArrayList<Parcelable> values = result.getParcelableArrayList("values");
+			if ("timeout".equals(result.getString("error"))) {
 				Log.d(Config.LOGTAG, account.getJid() + ": dns timeout");
 				this.changeStatus(Account.STATUS_OFFLINE);
 				return;
-			}
-			String srvRecordServer = namePort.getString("name");
-			String srvIpServer = namePort.getString("ipv4");
-			int srvRecordPort = namePort.getInt("port");
-			if (srvRecordServer != null) {
-				if (srvIpServer != null) {
-					Log.d(Config.LOGTAG, account.getJid()
-							+ ": using values from dns " + srvRecordServer
-							+ "[" + srvIpServer + "]:" + srvRecordPort);
-					socket = new Socket(srvIpServer, srvRecordPort);
-				} else {
+			} else if (values != null) {
+					int i = 0;
 					boolean socketError = true;
-					int srvIndex = 0;
-					while (socketError
-							&& namePort.containsKey("name" + srvIndex)) {
+					while (socketError && values.size() > i) {
+						Bundle namePort = (Bundle) values.get(i);
 						try {
-							srvRecordServer = namePort.getString("name"
-									+ srvIndex);
-							srvRecordPort = namePort.getInt("port" + srvIndex);
-							Log.d(Config.LOGTAG, account.getJid()
-									+ ": using values from dns "
-									+ srvRecordServer + ":" + srvRecordPort);
-							socket = new Socket(srvRecordServer, srvRecordPort);
+							String srvRecordServer = namePort.getString("name");
+							int srvRecordPort = namePort.getInt("port");
+							String srvIpServer = namePort.getString("ipv4");
+							InetSocketAddress addr;
+							if (srvIpServer!=null) {
+								addr = new InetSocketAddress(srvIpServer, srvRecordPort);
+								Log.d(Config.LOGTAG, account.getJid()
+										+ ": using values from dns " + srvRecordServer
+										+ "[" + srvIpServer + "]:" + srvRecordPort);
+							} else {
+								addr = new InetSocketAddress(srvRecordServer, srvRecordPort);
+								Log.d(Config.LOGTAG, account.getJid()
+										+ ": using values from dns "
+										+ srvRecordServer + ":" + srvRecordPort);
+							}
+							socket = new Socket();
+							socket.connect(addr, 20000);
 							socketError = false;
 						} catch (UnknownHostException e) {
-							srvIndex++;
-							if (!namePort.containsKey("name" + srvIndex)) {
-								throw e;
-							}
+							i++;
 						} catch (IOException e) {
-							srvIndex++;
-							if (!namePort.containsKey("name" + srvIndex)) {
-								throw e;
-							}
+							i++;
 						}
 					}
-				}
-			} else if (namePort.containsKey("error")
-					&& "nosrv".equals(namePort.getString("error", null))) {
+					if (socketError) {
+						throw new IOException();
+					}
+			} else if (result.containsKey("error")
+					&& "nosrv".equals(result.getString("error", null))) {
 				socket = new Socket(account.getServer(), 5222);
 			} else {
 				Log.d(Config.LOGTAG, account.getJid()