mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 05:39:53 +01:00
Add support for IPv4 link-local addresses.
This commit is contained in:
@@ -158,36 +158,41 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
// Package access for testing
|
// Package access for testing
|
||||||
boolean addressesAreOnSameLan(byte[] localIp, byte[] remoteIp) {
|
boolean addressesAreOnSameLan(byte[] localIp, byte[] remoteIp) {
|
||||||
// 10.0.0.0/8
|
// 10.0.0.0/8
|
||||||
if (isPrefix10(localIp)) return isPrefix10(remoteIp);
|
if (isSlash8SiteLocal(localIp)) return isSlash8SiteLocal(remoteIp);
|
||||||
// 172.16.0.0/12
|
// 172.16.0.0/12
|
||||||
if (isPrefix172(localIp)) return isPrefix172(remoteIp);
|
if (isSlash12SiteLocal(localIp)) return isSlash12SiteLocal(remoteIp);
|
||||||
// 192.168.0.0/16
|
// 192.168.0.0/16
|
||||||
if (isPrefix192(localIp)) return isPrefix192(remoteIp);
|
if (isSlash16SiteLocal(localIp)) return isSlash16SiteLocal(remoteIp);
|
||||||
// Unrecognised prefix - may be compatible
|
// 169.254.0.0/16
|
||||||
return true;
|
if (isSlash16LinkLocal(localIp)) return isSlash16LinkLocal(remoteIp);
|
||||||
|
// Unrecognised prefix
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPrefix10(byte[] ipv4) {
|
private static boolean isSlash8SiteLocal(byte[] ipv4) {
|
||||||
return ipv4[0] == 10;
|
return ipv4[0] == 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPrefix172(byte[] ipv4) {
|
private static boolean isSlash12SiteLocal(byte[] ipv4) {
|
||||||
return ipv4[0] == (byte) 172 && (ipv4[1] & 0xF0) == 16;
|
return ipv4[0] == (byte) 172 && (ipv4[1] & 0xF0) == 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPrefix192(byte[] ipv4) {
|
private static boolean isSlash16SiteLocal(byte[] ipv4) {
|
||||||
return ipv4[0] == (byte) 192 && ipv4[1] == (byte) 168;
|
return ipv4[0] == (byte) 192 && ipv4[1] == (byte) 168;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the prefix length for an RFC 1918 address, or 0 for any other
|
private static boolean isSlash16LinkLocal(byte[] ipv4) {
|
||||||
// address
|
return ipv4[0] == (byte) 169 && ipv4[1] == (byte) 254;
|
||||||
private static int getRfc1918PrefixLength(InetAddress addr) {
|
}
|
||||||
|
|
||||||
|
// Returns the prefix length for a link-local or site-local address, or 0
|
||||||
|
// for any other address
|
||||||
|
private static int getPrefixLengthIfKnown(InetAddress addr) {
|
||||||
if (!(addr instanceof Inet4Address)) return 0;
|
if (!(addr instanceof Inet4Address)) return 0;
|
||||||
if (!addr.isSiteLocalAddress()) return 0;
|
|
||||||
byte[] ipv4 = addr.getAddress();
|
byte[] ipv4 = addr.getAddress();
|
||||||
if (isPrefix10(ipv4)) return 8;
|
if (isSlash8SiteLocal(ipv4)) return 8;
|
||||||
if (isPrefix172(ipv4)) return 12;
|
if (isSlash12SiteLocal(ipv4)) return 12;
|
||||||
if (isPrefix192(ipv4)) return 16;
|
if (isSlash16SiteLocal(ipv4) || isSlash16LinkLocal(ipv4)) return 16;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,9 +313,9 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
int aPort = a.getPort(), bPort = b.getPort();
|
int aPort = a.getPort(), bPort = b.getPort();
|
||||||
if (aPort > 0 && bPort == 0) return -1;
|
if (aPort > 0 && bPort == 0) return -1;
|
||||||
if (aPort == 0 && bPort > 0) return 1;
|
if (aPort == 0 && bPort > 0) return 1;
|
||||||
// Prefer addresses with longer RFC 1918 prefixes
|
// Prefer addresses with longer prefixes
|
||||||
int aPrefix = getRfc1918PrefixLength(a.getAddress());
|
int aPrefix = getPrefixLengthIfKnown(a.getAddress());
|
||||||
int bPrefix = getRfc1918PrefixLength(b.getAddress());
|
int bPrefix = getPrefixLengthIfKnown(b.getAddress());
|
||||||
return bPrefix - aPrefix;
|
return bPrefix - aPrefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
|||||||
makeAddress(10, 255, 255, 255)));
|
makeAddress(10, 255, 255, 255)));
|
||||||
assertFalse(plugin.addressesAreOnSameLan(makeAddress(192, 168, 0, 0),
|
assertFalse(plugin.addressesAreOnSameLan(makeAddress(192, 168, 0, 0),
|
||||||
makeAddress(172, 31, 255, 255)));
|
makeAddress(172, 31, 255, 255)));
|
||||||
|
assertFalse(plugin.addressesAreOnSameLan(makeAddress(169, 254, 0, 0),
|
||||||
|
makeAddress(192, 168, 255, 255)));
|
||||||
// Remote prefix unrecognised should return false
|
// Remote prefix unrecognised should return false
|
||||||
assertFalse(plugin.addressesAreOnSameLan(makeAddress(10, 0, 0, 0),
|
assertFalse(plugin.addressesAreOnSameLan(makeAddress(10, 0, 0, 0),
|
||||||
makeAddress(1, 2, 3, 4)));
|
makeAddress(1, 2, 3, 4)));
|
||||||
@@ -80,8 +82,8 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
|||||||
makeAddress(1, 2, 3, 4)));
|
makeAddress(1, 2, 3, 4)));
|
||||||
assertFalse(plugin.addressesAreOnSameLan(makeAddress(192, 168, 0, 0),
|
assertFalse(plugin.addressesAreOnSameLan(makeAddress(192, 168, 0, 0),
|
||||||
makeAddress(1, 2, 3, 4)));
|
makeAddress(1, 2, 3, 4)));
|
||||||
// Both prefixes unrecognised should return true (could be link-local)
|
// Both prefixes unrecognised should return false
|
||||||
assertTrue(plugin.addressesAreOnSameLan(makeAddress(1, 2, 3, 4),
|
assertFalse(plugin.addressesAreOnSameLan(makeAddress(1, 2, 3, 4),
|
||||||
makeAddress(5, 6, 7, 8)));
|
makeAddress(5, 6, 7, 8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,41 +294,33 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testComparatorPrefersLongerPrefixes() {
|
public void testComparatorPrefersLongerPrefixes() {
|
||||||
Comparator<InetSocketAddress> comparator = new LanAddressComparator();
|
Comparator<InetSocketAddress> comparator = new LanAddressComparator();
|
||||||
|
InetSocketAddress prefix169 = new InetSocketAddress("169.254.0.1", 0);
|
||||||
InetSocketAddress prefix192 = new InetSocketAddress("192.168.0.1", 0);
|
InetSocketAddress prefix192 = new InetSocketAddress("192.168.0.1", 0);
|
||||||
InetSocketAddress prefix172 = new InetSocketAddress("172.16.0.1", 0);
|
InetSocketAddress prefix172 = new InetSocketAddress("172.16.0.1", 0);
|
||||||
InetSocketAddress prefix10 = new InetSocketAddress("10.0.0.1", 0);
|
InetSocketAddress prefix10 = new InetSocketAddress("10.0.0.1", 0);
|
||||||
|
|
||||||
|
assertEquals(0, comparator.compare(prefix169, prefix169));
|
||||||
|
assertEquals(0, comparator.compare(prefix169, prefix192));
|
||||||
|
assertTrue(comparator.compare(prefix169, prefix172) < 0);
|
||||||
|
assertTrue(comparator.compare(prefix169, prefix10) < 0);
|
||||||
|
|
||||||
assertEquals(0, comparator.compare(prefix192, prefix192));
|
assertEquals(0, comparator.compare(prefix192, prefix192));
|
||||||
|
assertEquals(0, comparator.compare(prefix192, prefix169));
|
||||||
assertTrue(comparator.compare(prefix192, prefix172) < 0);
|
assertTrue(comparator.compare(prefix192, prefix172) < 0);
|
||||||
assertTrue(comparator.compare(prefix192, prefix10) < 0);
|
assertTrue(comparator.compare(prefix192, prefix10) < 0);
|
||||||
|
|
||||||
|
assertTrue(comparator.compare(prefix172, prefix169) > 0);
|
||||||
assertTrue(comparator.compare(prefix172, prefix192) > 0);
|
assertTrue(comparator.compare(prefix172, prefix192) > 0);
|
||||||
assertEquals(0, comparator.compare(prefix172, prefix172));
|
assertEquals(0, comparator.compare(prefix172, prefix172));
|
||||||
assertTrue(comparator.compare(prefix172, prefix10) < 0);
|
assertTrue(comparator.compare(prefix172, prefix10) < 0);
|
||||||
|
|
||||||
|
assertTrue(comparator.compare(prefix10, prefix169) > 0);
|
||||||
assertTrue(comparator.compare(prefix10, prefix192) > 0);
|
assertTrue(comparator.compare(prefix10, prefix192) > 0);
|
||||||
assertTrue(comparator.compare(prefix10, prefix172) > 0);
|
assertTrue(comparator.compare(prefix10, prefix172) > 0);
|
||||||
assertEquals(0, comparator.compare(prefix10, prefix10));
|
assertEquals(0, comparator.compare(prefix10, prefix10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||||
public void testComparatorPrefersSiteLocalToLinkLocal() {
|
|
||||||
Comparator<InetSocketAddress> comparator = new LanAddressComparator();
|
|
||||||
InetSocketAddress prefix192 = new InetSocketAddress("192.168.0.1", 0);
|
|
||||||
InetSocketAddress prefix172 = new InetSocketAddress("172.16.0.1", 0);
|
|
||||||
InetSocketAddress prefix10 = new InetSocketAddress("10.0.0.1", 0);
|
|
||||||
InetSocketAddress linkLocal = new InetSocketAddress("169.254.0.1", 0);
|
|
||||||
|
|
||||||
assertTrue(comparator.compare(prefix192, linkLocal) < 0);
|
|
||||||
assertTrue(comparator.compare(prefix172, linkLocal) < 0);
|
|
||||||
assertTrue(comparator.compare(prefix10, linkLocal) < 0);
|
|
||||||
|
|
||||||
assertTrue(comparator.compare(linkLocal, prefix192) > 0);
|
|
||||||
assertTrue(comparator.compare(linkLocal, prefix172) > 0);
|
|
||||||
assertTrue(comparator.compare(linkLocal, prefix10) > 0);
|
|
||||||
assertEquals(0, comparator.compare(linkLocal, linkLocal));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean systemHasLocalIpv4Address() throws Exception {
|
private boolean systemHasLocalIpv4Address() throws Exception {
|
||||||
for (NetworkInterface i : list(getNetworkInterfaces())) {
|
for (NetworkInterface i : list(getNetworkInterfaces())) {
|
||||||
for (InetAddress a : list(i.getInetAddresses())) {
|
for (InetAddress a : list(i.getInetAddresses())) {
|
||||||
|
|||||||
Reference in New Issue
Block a user