From e4ac02af1cbc2da53f6802df4b30ba4e5ef3ce21 Mon Sep 17 00:00:00 2001 From: Richard Russo Date: Tue, 11 Jun 2024 12:00:40 -0700 Subject: [PATCH] Only attempt to relay connections to addresses that are globally unique --- p2p/base/turn_port.cc | 5 + rtc_base/ip_address.cc | 55 +++++++++++ rtc_base/ip_address.h | 3 + rtc_base/ip_address_unittest.cc | 165 ++++++++++++++++++++++++++++++++ 4 files changed, 228 insertions(+) diff --git a/p2p/base/turn_port.cc b/p2p/base/turn_port.cc index 5800ebb32d..5cbf885e66 100644 --- a/p2p/base/turn_port.cc +++ b/p2p/base/turn_port.cc @@ -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. diff --git a/rtc_base/ip_address.cc b/rtc_base/ip_address.cc index 9e436e3c78..160fd54ed1 100644 --- a/rtc_base/ip_address.cc +++ b/rtc_base/ip_address.cc @@ -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 diff --git a/rtc_base/ip_address.h b/rtc_base/ip_address.h index 897e165565..f1f70d1c75 100644 --- a/rtc_base/ip_address.h +++ b/rtc_base/ip_address.h @@ -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); diff --git a/rtc_base/ip_address_unittest.cc b/rtc_base/ip_address_unittest.cc index aee9b93dd9..60d9e9325d 100644 --- a/rtc_base/ip_address_unittest.cc +++ b/rtc_base/ip_address_unittest.cc @@ -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