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