reworked dns retry

This commit is contained in:
iNPUTmice 2014-10-27 21:48:25 +01:00
parent 915def24f9
commit 7dcce220cb
2 changed files with 51 additions and 66 deletions

View File

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

View File

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