From 7dcce220cbbac3a9cd23df825c2a81043fc2f68c Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 27 Oct 2014 21:48:25 +0100 Subject: [PATCH] reworked dns retry --- .../siacs/conversations/utils/DNSHelper.java | 50 +++++--------- .../conversations/xmpp/XmppConnection.java | 67 +++++++++---------- 2 files changed, 51 insertions(+), 66 deletions(-) diff --git a/src/eu/siacs/conversations/utils/DNSHelper.java b/src/eu/siacs/conversations/utils/DNSHelper.java index c51a75ac..f101e883 100644 --- a/src/eu/siacs/conversations/utils/DNSHelper.java +++ b/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 ip = ips4.get(resultName); - Collections.shuffle(ip, rnd); - namePort.putString("ipv4", ip.get(0)); - } - if (ips6.containsKey(resultName)) { - ArrayList ip = ips6.get(resultName); - Collections.shuffle(ip, rnd); - namePort.putString("ipv6", ip.get(0)); - } - - // add all other records - int i = 0; + ArrayList values = new ArrayList(); 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 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(); diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index 903dc59d..39dcb362 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/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 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()