Only attempt to relay connections to addresses that are globally unique

This commit is contained in:
Richard Russo 2024-06-11 12:00:40 -07:00
parent 758e8f0667
commit e4ac02af1c
4 changed files with 228 additions and 0 deletions

View file

@ -580,6 +580,11 @@ Connection* TurnPort::CreateConnection(const Candidate& remote_candidate,
return nullptr;
}
// RingRTC change to prevent attempting relay connections to addresses that are not globally unique
if (rtc::IPIsNotGloballyUnique(remote_candidate.address().ipaddr())) {
return nullptr;
}
// A TURN port will have two candidates, STUN and TURN. STUN may not
// present in all cases. If present stun candidate will be added first
// and TURN candidate later.

View file

@ -575,4 +575,59 @@ IPAddress GetAnyIP(int family) {
return rtc::IPAddress();
}
// RingRTC change to prevent attempting relay connections to addresses that are not globally unique
static const in6_addr ipv4ipv6TranslationPrefix = {{{0, 0x64, 0xFF, 0x9B}}}; // 64:ff9b::/96
// ietf assignments 2001::/23; IPIsHelper only does byte level prefixes
static const in6_addr ietfAssignmentsPrefix0 = {{{0x20, 0x01, 0}}}; // 2001::/24
static const in6_addr ietfAssignmentsPrefix1 = {{{0x20, 0x01, 0x01}}}; // 2001:0100:/24
static const in6_addr multicastPrefix = {{{0xFF}}}; // ff00::/8
bool IPIsNotGloballyUnique(const IPAddress& ip) {
if (ip.family() == AF_INET) {
if (IPIsPrivateNetworkV4(ip) || IPIsSharedNetworkV4(ip) || IPIsLoopbackV4(ip) ||
IPIsLinkLocalV4(ip) || IPIsAny(ip)) {
return true;
}
uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
// 192.0.0.0/24 IETF Protocol Assignments including DS-Lite (192.0.0.0/29)
if ((ip_in_host_order >> 8) == ((192 << 16) | (0 << 8) | 0)) {
return true;
}
// 192.88.99.0/24 6to4
if ((ip_in_host_order >> 8) == ((192 << 16) | (88 << 8) | 99)) {
return true;
}
// 224.0.0.0/4 Multicast
if (((ip_in_host_order >> 24) & 0xF0) == 0xE0) {
return true;
}
// 240.0.0.0/4 currently reserved "Class E"
if ((ip_in_host_order >> 24) >= 240) {
return true;
}
} else if (ip.family() == AF_INET6) {
if (IPIsLoopbackV6(ip) || IPIsV4Mapped(ip) || IPIsV4Compatibility(ip) ||
IPIs6To4(ip) || IPIsLinkLocalV6(ip) || IPIsSiteLocal(ip) ||
IPIsULA(ip) || IPIs6Bone(ip)) {
return true;
}
if (IPIsHelper(ip, ipv4ipv6TranslationPrefix, 96)) {
return true;
}
if (IPIsHelper(ip, ietfAssignmentsPrefix0, 24)) {
return true;
}
if (IPIsHelper(ip, ietfAssignmentsPrefix1, 24)) {
return true;
}
if (IPIsHelper(ip, multicastPrefix, 8)) {
return true;
}
} else {
return true;
}
return false;
}
} // namespace rtc

View file

@ -190,6 +190,9 @@ bool IPIsV4Mapped(const IPAddress& ip);
// Returns the precedence value for this IP as given in RFC3484.
int IPAddressPrecedence(const IPAddress& ip);
// RingRTC change to prevent attempting relay connections to addresses that are not globally unique
RTC_EXPORT bool IPIsNotGloballyUnique(const IPAddress& ip);
// Returns 'ip' truncated to be 'length' bits long.
RTC_EXPORT IPAddress TruncateIP(const IPAddress& ip, int length);

View file

@ -974,4 +974,169 @@ TEST(IPAddressTest, TestInterfaceAddress) {
EXPECT_NE(addr1, addr5);
}
// RingRTC change to prevent attempting relay connections to addresses that are not globally unique
TEST(IPAddressTest, TestIsNotGloballyUnique) {
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(INADDR_ANY)));
EXPECT_FALSE(IPIsNotGloballyUnique(IPAddress(kIPv4PublicAddr)));
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(in6addr_any)));
EXPECT_FALSE(IPIsNotGloballyUnique(IPAddress(kIPv6PublicAddr)));
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(kIPv4MappedAnyAddr)));
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(kIPv4MappedPublicAddr)));
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(kIPv4RFC1918Addr)));
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(kIPv4RFC6598Addr)));
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(INADDR_LOOPBACK)));
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(in6addr_loopback)));
EXPECT_TRUE(IPIsNotGloballyUnique(IPAddress(kIPv6LinkLocalAddr)));
// IPv4 compatibility address (::123.123.123.123)
IPAddress v4compat_addr;
IPFromString("::192.168.7.1", &v4compat_addr);
EXPECT_TRUE(IPIsNotGloballyUnique(v4compat_addr));
// 6Bone address (3FFE::/16)
IPAddress sixbone_addr;
IPFromString("3FFE:123:456::789:123", &sixbone_addr);
EXPECT_TRUE(IPIsNotGloballyUnique(sixbone_addr));
// Unique Local Address (FC::/7)
IPAddress ula_addr;
IPFromString("FC00:123:456::789:123", &ula_addr);
EXPECT_TRUE(IPIsNotGloballyUnique(ula_addr));
// 6To4 Address (2002::/16)
IPAddress sixtofour_addr;
IPFromString("2002:123:456::789:123", &sixtofour_addr);
EXPECT_TRUE(IPIsNotGloballyUnique(sixtofour_addr));
// Site Local address (FEC0::/10)
IPAddress sitelocal_addr;
IPFromString("FEC0:123:456::789:123", &sitelocal_addr);
EXPECT_TRUE(IPIsNotGloballyUnique(sitelocal_addr));
// Teredo Address (2001:0000::/32)
IPAddress teredo_addr;
IPFromString("2001:0000:123:456::789:123", &teredo_addr);
EXPECT_TRUE(IPIsNotGloballyUnique(teredo_addr));
IPAddress addr;
// 10.0.0.0/8 Private Use RFC 1918
IPFromString("9.255.255.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("10.0.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("10.255.255.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("11.0.0.0", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 100.64.0.0/10 Shared address space RFC 6598
IPFromString("100.63.255.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("100.64.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("100.127.255.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("100.128.0.0", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 127.0.0.0/8 loopback RFC 1122
IPFromString("126.255.255.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("127.0.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("127.255.255.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("128.0.0.0", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 169.254.0.0/16 Link Local RFC 3927
IPFromString("169.253.255.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("169.254.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("169.254.255.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("169.255.0.0", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 172.16.0.0/12 Private Use RFC 1918
IPFromString("172.15.255.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("172.16.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("172.31.255.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("172.32.0.0", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 192.0.0.0/24 IETF Protocol Assignments including DS-Lite (192.0.0.0/29)
IPFromString("191.255.255.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("192.0.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("192.0.0.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("192.0.1.0", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 192.88.99.0/24 6to4
IPFromString("192.88.98.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("192.88.99.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("192.88.99.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("192.88.100.0", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 192.168.0.0/16 Private Use RFC 1918
IPFromString("192.167.255.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("192.168.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("192.168.255.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("192.169.0.0", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 224.0.0.0/4 Multicast
IPFromString("223.255.255.255", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("224.0.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("239.255.255.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
// 240.0.0.0/4 currently reserved "Class E"
IPFromString("240.0.0.0", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("255.255.255.255", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
// 64:ff9b::/96 NAT64
IPFromString("64:ff9b::", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("64:ff9b::ffff:ffff", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
// ietf assignments 2001::/23
IPFromString("2001::", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("2001:200::", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// 2002::/16 6to4 RFC 3056
IPFromString("2001:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
IPFromString("2002::", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("2003::", &addr);
EXPECT_FALSE(IPIsNotGloballyUnique(addr));
// fc00::/7 Unique-Local RFC 8190
IPFromString("fc00::", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
// fe80::/10 Link-Local Unicast RFC 4291
IPFromString("fe80::", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
// ff00::/8 multicast
IPFromString("ff00::", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
IPFromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &addr);
EXPECT_TRUE(IPIsNotGloballyUnique(addr));
}
} // namespace rtc