I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Unverified Commit 5ddb70ea authored by zzz's avatar zzz
Browse files

Util: Rewrite Addresses.getIPOnly() for 10x speedup

parent fd58472c
No related branches found
No related tags found
No related merge requests found
......@@ -483,6 +483,9 @@ public abstract class Addresses {
* Caches numeric addresses only.
* Will resolve but not cache DNS addresses.
*
* DEPRECATED for IPs in RouterAddresses, blocklists, etc.,
* use getI2POnly() which avoids getByName() in most cases.
*
* Unlike InetAddress.getByName(), we do NOT allow numeric IPs
* of the form d.d.d, d.d, or d, as these are almost certainly mistakes.
*
......@@ -512,7 +515,6 @@ public abstract class Addresses {
_negativeCache.remove(host);
}
}
//I2PAppContext.getGlobalContext().logManager().getLog(Addresses.class).error("lookup of " + host, new Exception("I did it"));
try {
rv = InetAddress.getByName(host).getAddress();
if (isIPAddress(host)) {
......@@ -535,6 +537,9 @@ public abstract class Addresses {
* Resolves literal IP addresses only, will not cause a DNS lookup.
* Will return null for hostnames.
*
* PREFERRED for IPs in RouterAddresses, blocklists, etc. over getI2P()
* because it avoids getByName() in most cases.
*
* Unlike InetAddress.getByName(), we do NOT allow numeric IPs
* of the form d.d.d, d.d, or d, as these are almost certainly mistakes.
*
......@@ -570,8 +575,6 @@ public abstract class Addresses {
_IPAddress.put(host, rv);
}
} catch (UnknownHostException uhe) {}
//} else {
// I2PAppContext.getGlobalContext().logManager().getLog(Addresses.class).warn("Not looking up " + host, new Exception("I did it"));
}
}
return rv;
......@@ -702,14 +705,8 @@ public abstract class Addresses {
return InetAddressUtils.isIPv4Address(host) || InetAddressUtils.isIPv6Address(host);
}
/**
* Because InetAddress.getByName() is slow, esp. on Windows
*
* @param host w.x.y.z only
* @return 4 bytes or null
* @since 0.9.50
*/
private static byte[] getIPv4(String host) {
/*
private static byte[] oldGetIPv4(String host) {
String[] s = DataHelper.split(host, "\\.", 4);
if (s.length != 4)
return null;
......@@ -727,14 +724,7 @@ public abstract class Addresses {
return rv;
}
/**
* Because InetAddress.getByName() is slow, esp. on Windows
*
* @param host full 0:1:2:3:4:5:6:7 only, no ::
* @return 16 bytes or null
* @since 0.9.50
*/
private static byte[] getIPv6(String host) {
private static byte[] oldGetIPv6(String host) {
String[] s = DataHelper.split(host, ":", 8);
if (s.length != 8)
return null;
......@@ -753,6 +743,83 @@ public abstract class Addresses {
}
return rv;
}
*/
/**
* Because InetAddress.getByName() is slow, esp. on Windows.
* Also avoids split(), Integer.parseInt(), and object churn.
*
* @param host w.x.y.z only
* @return 4 bytes or null
* @since 0.9.50
*/
private static byte[] getIPv4(String host) {
byte[] rv = new byte[4];
int b = 0;
int dots = 0;
int len = host.length();
for (int i = 0; i < len; i++) {
char c = host.charAt(i);
if (c == '.') {
if (i == 0 || i == len - 1 || dots == 3 || b > 255 || host.charAt(i - 1) == '.')
return null;
rv[dots++] = (byte) b;
b = 0;
} else if (c >= '0' && c <= '9') {
b *= 10;
b += c - '0';
} else {
return null;
}
}
if (dots != 3 || b > 255)
return null;
rv[3] = (byte) b;
return rv;
}
/**
* Because InetAddress.getByName() is slow, esp. on Windows.
* Also avoids split(), Integer.parseInt(), and object churn.
*
* @param host full 0:1:2:3:4:5:6:7 only, no ::
* @return 16 bytes or null
* @since 0.9.50
*/
private static byte[] getIPv6(String host) {
byte[] rv = new byte[16];
int b = 0;
int j = 0;
int colons = 0;
int len = host.length();
for (int i = 0; i < len; i++) {
char c = host.charAt(i);
if (c == ':') {
if (i == 0 || i == len - 1 || colons == 7 || b > 65535 || host.charAt(i - 1) == ':')
return null;
rv[j++] = (byte) (b >> 8);
rv[j++] = (byte) b;
colons++;
b = 0;
} else if (c >= '0' && c <= '9') {
b <<= 4;
b |= c - '0';
} else if (c >= 'a' && c <= 'f') {
b <<= 4;
b |= 10 + c - 'a';
} else if (c >= 'A' && c <= 'F') {
b <<= 4;
b |= 10 + c - 'A';
} else {
return null;
}
}
if (colons != 7 || b > 65535)
return null;
rv[14] = (byte) (b >> 8);
rv[15] = (byte) b;
return rv;
}
//////// IPv6 Cache Utils ///////
......@@ -938,6 +1005,7 @@ public abstract class Addresses {
* Print out the local addresses
*/
public static void main(String[] args) {
//test(); if (true) return;
System.out.println("Connected Address Types: " + getConnectedAddressTypes() + '\n');
System.out.println("External IPv4 Addresses:");
Set<String> a = getAddresses(false, false, false);
......@@ -1016,6 +1084,85 @@ public abstract class Addresses {
System.out.println("scan time: " + DataHelper.formatDuration(time));
}
/*
// test results (linux):
// new is about 10x faster than old
// InetAddress about the same as old for IPv4, about 4x slower for IPv6
private static void test() {
String[] tt = { "1.2.3.4", "0.0.0.0", "255.255.255.255", "", "a", "1", "1.2", "1.2.3",
".1.2.3", "1.2.3.", "266.1.2.3", "1.266.2.3", "1.2.3.266", "1.2.3.4.5" };
for (String t : tt) {
byte[] b = getIPv4(t);
System.out.println(t + " -> " + toString(b));
}
tt = new String[] { "a:B:c:D:e:f:1:2", "aaaa:bbbb:CCC:dd:e:f:111:2222", "a", "1", "1:2", "1::2:3:4:5:6:7:8",
":1:2:3:4:5:6:7", "2:3:4:5:6:7:8:", "x:2:3:4:5:6:7:8", "::1", "::", "",
"99999:2:3:4:5:6:7:8" };
for (String t : tt) {
byte[] b = getIPv6(t);
System.out.println(t + " -> " + toString(b));
}
int runs = 1000;
for (int i = 0; i < runs; i++) {
try {
InetAddress.getByName("192.168.142.117").getAddress();
InetAddress.getByName("aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222").getAddress();
} catch (Exception e) {}
oldGetIPv4("192.168.142.117");
oldGetIPv6("aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222");
getIPv4("192.168.142.117");
getIPv6("aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222");
}
runs = 10*1000*1000;
long start = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
oldGetIPv4("192.168.142.117");
}
long end = System.currentTimeMillis();
System.out.println("old ipv4 took " + (end - start));
start = end;
for (int i = 0; i < runs; i++) {
getIPv4("192.168.142.117");
}
end = System.currentTimeMillis();
System.out.println("new ipv4 took " + (end - start));
start = end;
for (int i = 0; i < runs; i++) {
try {
InetAddress.getByName("192.168.142.117").getAddress();
InetAddress.getByName("aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222").getAddress();
} catch (Exception e) {}
}
end = System.currentTimeMillis();
System.out.println("INA ipv4 took " + (end - start));
start = end;
for (int i = 0; i < runs; i++) {
oldGetIPv6("192.168.142.117");
}
end = System.currentTimeMillis();
System.out.println("old ipv6 took " + (end - start));
start = end;
for (int i = 0; i < runs; i++) {
getIPv6("192.168.142.117");
}
end = System.currentTimeMillis();
System.out.println("new ipv6 took " + (end - start));
for (int i = 0; i < runs; i++) {
try {
InetAddress.getByName("aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222").getAddress();
} catch (Exception e) {}
}
end = System.currentTimeMillis();
System.out.println("INA ipv6 took " + (end - start));
start = end;
}
*/
/** @since 0.9.34 */
private static void print(Set<String> a) {
if (a.isEmpty()) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment