let DnsHelper provide a fallback solution

This commit is contained in:
Daniel Gultsch 2015-09-19 17:31:24 +02:00
parent 069ddddbc1
commit a954e32b16
2 changed files with 41 additions and 43 deletions

View file

@ -7,6 +7,7 @@ import android.net.LinkProperties;
import android.net.Network; import android.net.Network;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log; import android.util.Log;
import java.io.IOException; import java.io.IOException;
@ -46,13 +47,19 @@ public class DNSHelper {
public static Bundle getSRVRecord(final Jid jid, Context context) throws IOException { public static Bundle getSRVRecord(final Jid jid, Context context) throws IOException {
final String host = jid.getDomainpart(); final String host = jid.getDomainpart();
final List<InetAddress> servers = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDnsServers(context) : getDnsServersPreLollipop(); 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) { for(InetAddress server : servers) {
b = queryDNS(host, server); b = queryDNS(host, server);
if (b.containsKey("values")) { if (b.containsKey("values")) {
return b; 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; return b;
} }

View file

@ -160,52 +160,43 @@ public class XmppConnection implements Runnable {
} }
} else { } else {
final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService); 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"); final ArrayList<Parcelable> values = result.getParcelableArrayList("values");
if ("timeout".equals(result.getString("error"))) { int i = 0;
throw new DnsTimeoutException(); boolean socketError = true;
} else if (values != null) { while (socketError && values.size() > i) {
int i = 0; final Bundle namePort = (Bundle) values.get(i);
boolean socketError = true; try {
while (socketError && values.size() > i) { String srvRecordServer;
final Bundle namePort = (Bundle) values.get(i);
try { try {
String srvRecordServer; srvRecordServer = IDN.toASCII(namePort.getString("name"));
try { } catch (final IllegalArgumentException e) {
srvRecordServer = IDN.toASCII(namePort.getString("name")); // TODO: Handle me?`
} catch (final IllegalArgumentException e) { srvRecordServer = "";
// 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++;
} }
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(); if (socketError) {
} throw new UnknownHostException();
} else {
throw new IOException("unhandled exception in DNS resolver");
} }
} }
final OutputStream out = socket.getOutputStream(); final OutputStream out = socket.getOutputStream();