don't perform dns lookups on domain parts that obviously look like ip addresses
This commit is contained in:
parent
58201b4408
commit
5a48afdd4d
|
@ -20,11 +20,19 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class DNSHelper {
|
public class DNSHelper {
|
||||||
|
|
||||||
|
public static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
|
||||||
|
public static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
|
||||||
|
public static final Pattern PATTERN_IPV6_6HEX4DEC = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
|
||||||
|
public static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z");
|
||||||
|
public static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z");
|
||||||
|
|
||||||
protected static Client client = new Client();
|
protected static Client client = new Client();
|
||||||
|
|
||||||
public static Bundle getSRVRecord(final Jid jid) throws IOException {
|
public static Bundle getSRVRecord(final Jid jid) throws IOException {
|
||||||
|
@ -160,15 +168,11 @@ public class DNSHelper {
|
||||||
return namePort;
|
return namePort;
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
|
public static boolean isIp(final String server) {
|
||||||
|
return PATTERN_IPV4.matcher(server).matches()
|
||||||
public static String bytesToHex(byte[] bytes) {
|
|| PATTERN_IPV6.matcher(server).matches()
|
||||||
char[] hexChars = new char[bytes.length * 2];
|
|| PATTERN_IPV6_6HEX4DEC.matcher(server).matches()
|
||||||
for (int j = 0; j < bytes.length; j++) {
|
|| PATTERN_IPV6_HEX4DECCOMPRESSED.matcher(server).matches()
|
||||||
int v = bytes[j] & 0xFF;
|
|| PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches();
|
||||||
hexChars[j * 2] = hexArray[v >>> 4];
|
|
||||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
|
||||||
}
|
|
||||||
return new String(hexChars);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.net.IDN;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.SocketAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
@ -155,53 +156,62 @@ public class XmppConnection implements Runnable {
|
||||||
tagWriter = new TagWriter();
|
tagWriter = new TagWriter();
|
||||||
packetCallbacks.clear();
|
packetCallbacks.clear();
|
||||||
this.changeStatus(Account.State.CONNECTING);
|
this.changeStatus(Account.State.CONNECTING);
|
||||||
final Bundle result = DNSHelper.getSRVRecord(account.getServer());
|
if (DNSHelper.isIp(account.getServer().toString())) {
|
||||||
final ArrayList<Parcelable> values = result.getParcelableArrayList("values");
|
socket = new Socket();
|
||||||
if ("timeout".equals(result.getString("error"))) {
|
try {
|
||||||
throw new IOException("timeout in dns");
|
socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000);
|
||||||
} else if (values != null) {
|
} catch (IOException e) {
|
||||||
int i = 0;
|
|
||||||
boolean socketError = true;
|
|
||||||
while (socketError && values.size() > i) {
|
|
||||||
final Bundle namePort = (Bundle) values.get(i);
|
|
||||||
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 UnknownHostException e) {
|
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
|
||||||
i++;
|
|
||||||
} catch (final IOException e) {
|
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (socketError) {
|
|
||||||
throw new UnknownHostException();
|
throw new UnknownHostException();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("unhandled exception in DNS resolver");
|
final Bundle result = DNSHelper.getSRVRecord(account.getServer());
|
||||||
|
final ArrayList<Parcelable> values = result.getParcelableArrayList("values");
|
||||||
|
if ("timeout".equals(result.getString("error"))) {
|
||||||
|
throw new IOException("timeout in dns");
|
||||||
|
} else if (values != null) {
|
||||||
|
int i = 0;
|
||||||
|
boolean socketError = true;
|
||||||
|
while (socketError && values.size() > i) {
|
||||||
|
final Bundle namePort = (Bundle) values.get(i);
|
||||||
|
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 UnknownHostException e) {
|
||||||
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
||||||
|
i++;
|
||||||
|
} catch (final IOException 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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final OutputStream out = socket.getOutputStream();
|
final OutputStream out = socket.getOutputStream();
|
||||||
tagWriter.setOutputStream(out);
|
tagWriter.setOutputStream(out);
|
||||||
|
|
Loading…
Reference in a new issue