mirror of
https://github.com/moparisthebest/Conversations
synced 2024-11-24 17:52:17 -05:00
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.Random;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
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();
|
||||
|
||||
public static Bundle getSRVRecord(final Jid jid) throws IOException {
|
||||
@ -160,15 +168,11 @@ public class DNSHelper {
|
||||
return namePort;
|
||||
}
|
||||
|
||||
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
int v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v >>> 4];
|
||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||
}
|
||||
return new String(hexChars);
|
||||
public static boolean isIp(final String server) {
|
||||
return PATTERN_IPV4.matcher(server).matches()
|
||||
|| PATTERN_IPV6.matcher(server).matches()
|
||||
|| PATTERN_IPV6_6HEX4DEC.matcher(server).matches()
|
||||
|| PATTERN_IPV6_HEX4DECCOMPRESSED.matcher(server).matches()
|
||||
|| PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches();
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.net.IDN;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -155,53 +156,62 @@ public class XmppConnection implements Runnable {
|
||||
tagWriter = new TagWriter();
|
||||
packetCallbacks.clear();
|
||||
this.changeStatus(Account.State.CONNECTING);
|
||||
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) {
|
||||
if (DNSHelper.isIp(account.getServer().toString())) {
|
||||
socket = new Socket();
|
||||
try {
|
||||
socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000);
|
||||
} catch (IOException e) {
|
||||
throw new UnknownHostException();
|
||||
}
|
||||
} 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();
|
||||
tagWriter.setOutputStream(out);
|
||||
|
Loading…
Reference in New Issue
Block a user