henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 11 | #include <string.h> |
Jonas Olsson | a4d8737 | 2019-07-05 17:08:33 | [diff] [blame] | 12 | |
Taylor Brandstetter | 0c7e9f5 | 2015-12-29 22:14:52 | [diff] [blame] | 13 | #include <algorithm> |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 14 | #include <cstddef> |
jbauch | 555604a | 2016-04-26 10:13:22 | [diff] [blame] | 15 | #include <memory> |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 16 | #include <string> |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 17 | #include <vector> |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 18 | |
Karl Wiberg | 918f50c | 2018-07-05 09:40:33 | [diff] [blame] | 19 | #include "absl/memory/memory.h" |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 20 | #include "api/units/time_delta.h" |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 21 | #include "rtc_base/async_packet_socket.h" |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 22 | #include "rtc_base/async_tcp_socket.h" |
| 23 | #include "rtc_base/async_udp_socket.h" |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 24 | #include "rtc_base/event.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 25 | #include "rtc_base/gunit.h" |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 26 | #include "rtc_base/ip_address.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 27 | #include "rtc_base/logging.h" |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 28 | #include "rtc_base/nat_server.h" |
| 29 | #include "rtc_base/nat_socket_factory.h" |
| 30 | #include "rtc_base/nat_types.h" |
| 31 | #include "rtc_base/net_helpers.h" |
Mirko Bonadei | 0d8b79e | 2023-07-27 06:55:49 | [diff] [blame] | 32 | #include "rtc_base/net_test_helpers.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 33 | #include "rtc_base/network.h" |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 34 | #include "rtc_base/physical_socket_server.h" |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 35 | #include "rtc_base/socket.h" |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 36 | #include "rtc_base/socket_address.h" |
| 37 | #include "rtc_base/socket_factory.h" |
| 38 | #include "rtc_base/socket_server.h" |
| 39 | #include "rtc_base/test_client.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 40 | #include "rtc_base/third_party/sigslot/sigslot.h" |
| 41 | #include "rtc_base/thread.h" |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 42 | #include "rtc_base/virtual_socket_server.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 43 | #include "test/gtest.h" |
Jonas Oreland | c06fe8b | 2022-03-28 12:58:26 | [diff] [blame] | 44 | #include "test/scoped_key_value_config.h" |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 45 | |
Mirko Bonadei | e10b163 | 2018-12-11 17:43:40 | [diff] [blame] | 46 | namespace rtc { |
| 47 | namespace { |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 48 | |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 49 | bool CheckReceive(TestClient* client, |
| 50 | bool should_receive, |
| 51 | const char* buf, |
| 52 | size_t size) { |
| 53 | return (should_receive) ? client->CheckNextPacket(buf, size, 0) |
| 54 | : client->CheckNoPacket(); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 55 | } |
| 56 | |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 57 | TestClient* CreateTestClient(SocketFactory* factory, |
| 58 | const SocketAddress& local_addr) { |
nisse | 32f2505 | 2017-05-08 08:57:18 | [diff] [blame] | 59 | return new TestClient( |
Karl Wiberg | 918f50c | 2018-07-05 09:40:33 | [diff] [blame] | 60 | absl::WrapUnique(AsyncUDPSocket::Create(factory, local_addr))); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 61 | } |
| 62 | |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 63 | TestClient* CreateTCPTestClient(Socket* socket) { |
Niels Möller | d30ece1 | 2021-10-19 08:11:02 | [diff] [blame] | 64 | return new TestClient(std::make_unique<AsyncTCPSocket>(socket)); |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 65 | } |
| 66 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 67 | // Tests that when sending from internal_addr to external_addrs through the |
| 68 | // NAT type specified by nat_type, all external addrs receive the sent packet |
| 69 | // and, if exp_same is true, all use the same mapped-address on the NAT. |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 70 | void TestSend(SocketServer* internal, |
| 71 | const SocketAddress& internal_addr, |
| 72 | SocketServer* external, |
| 73 | const SocketAddress external_addrs[4], |
| 74 | NATType nat_type, |
| 75 | bool exp_same) { |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 76 | Thread th_int(internal); |
| 77 | Thread th_ext(external); |
| 78 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 79 | th_int.Start(); |
| 80 | th_ext.Start(); |
| 81 | |
Per K | a8cd2ba | 2023-12-13 07:10:06 | [diff] [blame] | 82 | SocketAddress server_addr = internal_addr; |
| 83 | server_addr.SetPort(0); // Auto-select a port |
| 84 | NATServer* nat = |
| 85 | new NATServer(nat_type, th_int, internal, server_addr, server_addr, |
| 86 | th_ext, external, external_addrs[0]); |
| 87 | NATSocketFactory* natsf = new NATSocketFactory( |
| 88 | internal, nat->internal_udp_address(), nat->internal_tcp_address()); |
| 89 | |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 90 | TestClient* in; |
| 91 | th_int.BlockingCall([&] { in = CreateTestClient(natsf, internal_addr); }); |
| 92 | |
| 93 | TestClient* out[4]; |
| 94 | th_ext.BlockingCall([&] { |
| 95 | for (int i = 0; i < 4; i++) |
| 96 | out[i] = CreateTestClient(external, external_addrs[i]); |
| 97 | }); |
| 98 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 99 | const char* buf = "filter_test"; |
| 100 | size_t len = strlen(buf); |
| 101 | |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 102 | th_int.BlockingCall([&] { in->SendTo(buf, len, out[0]->address()); }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 103 | SocketAddress trans_addr; |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 104 | th_ext.BlockingCall( |
| 105 | [&] { EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 106 | |
| 107 | for (int i = 1; i < 4; i++) { |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 108 | th_int.BlockingCall([&] { in->SendTo(buf, len, out[i]->address()); }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 109 | SocketAddress trans_addr2; |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 110 | th_ext.BlockingCall([&] { |
| 111 | EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2)); |
| 112 | bool are_same = (trans_addr == trans_addr2); |
| 113 | ASSERT_EQ(are_same, exp_same) << "same translated address"; |
| 114 | ASSERT_NE(AF_UNSPEC, trans_addr.family()); |
| 115 | ASSERT_NE(AF_UNSPEC, trans_addr2.family()); |
| 116 | }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | th_int.Stop(); |
| 120 | th_ext.Stop(); |
| 121 | |
| 122 | delete nat; |
| 123 | delete natsf; |
| 124 | delete in; |
| 125 | for (int i = 0; i < 4; i++) |
| 126 | delete out[i]; |
| 127 | } |
| 128 | |
| 129 | // Tests that when sending from external_addrs to internal_addr, the packet |
| 130 | // is delivered according to the specified filter_ip and filter_port rules. |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 131 | void TestRecv(SocketServer* internal, |
| 132 | const SocketAddress& internal_addr, |
| 133 | SocketServer* external, |
| 134 | const SocketAddress external_addrs[4], |
| 135 | NATType nat_type, |
| 136 | bool filter_ip, |
| 137 | bool filter_port) { |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 138 | Thread th_int(internal); |
| 139 | Thread th_ext(external); |
| 140 | |
| 141 | SocketAddress server_addr = internal_addr; |
| 142 | server_addr.SetPort(0); // Auto-select a port |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 143 | th_int.Start(); |
| 144 | th_ext.Start(); |
Per K | a8cd2ba | 2023-12-13 07:10:06 | [diff] [blame] | 145 | NATServer* nat = |
| 146 | new NATServer(nat_type, th_int, internal, server_addr, server_addr, |
| 147 | th_ext, external, external_addrs[0]); |
| 148 | NATSocketFactory* natsf = new NATSocketFactory( |
| 149 | internal, nat->internal_udp_address(), nat->internal_tcp_address()); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 150 | |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 151 | TestClient* in = nullptr; |
| 152 | th_int.BlockingCall([&] { in = CreateTestClient(natsf, internal_addr); }); |
| 153 | |
| 154 | TestClient* out[4]; |
| 155 | th_ext.BlockingCall([&] { |
| 156 | for (int i = 0; i < 4; i++) |
| 157 | out[i] = CreateTestClient(external, external_addrs[i]); |
| 158 | }); |
| 159 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 160 | const char* buf = "filter_test"; |
| 161 | size_t len = strlen(buf); |
| 162 | |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 163 | th_int.BlockingCall([&] { in->SendTo(buf, len, out[0]->address()); }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 164 | SocketAddress trans_addr; |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 165 | th_ext.BlockingCall( |
| 166 | [&] { EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 167 | |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 168 | th_ext.BlockingCall([&] { out[1]->SendTo(buf, len, trans_addr); }); |
| 169 | th_int.BlockingCall( |
| 170 | [&] { EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len)); }); |
| 171 | th_ext.BlockingCall([&] { out[2]->SendTo(buf, len, trans_addr); }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 172 | |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 173 | th_int.BlockingCall( |
| 174 | [&] { EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len)); }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 175 | |
Per K | d07900c | 2023-11-17 09:18:25 | [diff] [blame] | 176 | th_ext.BlockingCall([&] { out[3]->SendTo(buf, len, trans_addr); }); |
| 177 | |
| 178 | th_int.BlockingCall([&] { |
| 179 | EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len)); |
| 180 | }); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 181 | |
| 182 | th_int.Stop(); |
| 183 | th_ext.Stop(); |
| 184 | |
| 185 | delete nat; |
| 186 | delete natsf; |
| 187 | delete in; |
| 188 | for (int i = 0; i < 4; i++) |
| 189 | delete out[i]; |
| 190 | } |
| 191 | |
| 192 | // Tests that NATServer allocates bindings properly. |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 193 | void TestBindings(SocketServer* internal, |
| 194 | const SocketAddress& internal_addr, |
| 195 | SocketServer* external, |
| 196 | const SocketAddress external_addrs[4]) { |
| 197 | TestSend(internal, internal_addr, external, external_addrs, NAT_OPEN_CONE, |
| 198 | true); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 199 | TestSend(internal, internal_addr, external, external_addrs, |
| 200 | NAT_ADDR_RESTRICTED, true); |
| 201 | TestSend(internal, internal_addr, external, external_addrs, |
| 202 | NAT_PORT_RESTRICTED, true); |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 203 | TestSend(internal, internal_addr, external, external_addrs, NAT_SYMMETRIC, |
| 204 | false); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 205 | } |
| 206 | |
| 207 | // Tests that NATServer filters packets properly. |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 208 | void TestFilters(SocketServer* internal, |
| 209 | const SocketAddress& internal_addr, |
| 210 | SocketServer* external, |
| 211 | const SocketAddress external_addrs[4]) { |
| 212 | TestRecv(internal, internal_addr, external, external_addrs, NAT_OPEN_CONE, |
| 213 | false, false); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 214 | TestRecv(internal, internal_addr, external, external_addrs, |
| 215 | NAT_ADDR_RESTRICTED, true, false); |
| 216 | TestRecv(internal, internal_addr, external, external_addrs, |
| 217 | NAT_PORT_RESTRICTED, true, true); |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 218 | TestRecv(internal, internal_addr, external, external_addrs, NAT_SYMMETRIC, |
| 219 | true, true); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 220 | } |
| 221 | |
| 222 | bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) { |
| 223 | // The physical NAT tests require connectivity to the selected ip from the |
| 224 | // internal address used for the NAT. Things like firewalls can break that, so |
| 225 | // check to see if it's worth even trying with this ip. |
jbauch | 555604a | 2016-04-26 10:13:22 | [diff] [blame] | 226 | std::unique_ptr<PhysicalSocketServer> pss(new PhysicalSocketServer()); |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 227 | std::unique_ptr<Socket> client(pss->CreateSocket(src.family(), SOCK_DGRAM)); |
| 228 | std::unique_ptr<Socket> server(pss->CreateSocket(src.family(), SOCK_DGRAM)); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 229 | if (client->Bind(SocketAddress(src.ipaddr(), 0)) != 0 || |
| 230 | server->Bind(SocketAddress(dst, 0)) != 0) { |
| 231 | return false; |
| 232 | } |
| 233 | const char* buf = "hello other socket"; |
| 234 | size_t len = strlen(buf); |
| 235 | int sent = client->SendTo(buf, len, server->GetLocalAddress()); |
Per K | 056782c | 2024-01-30 11:32:05 | [diff] [blame] | 236 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 237 | Thread::Current()->SleepMs(100); |
Per K | 056782c | 2024-01-30 11:32:05 | [diff] [blame] | 238 | rtc::Buffer payload; |
| 239 | Socket::ReceiveBuffer receive_buffer(payload); |
| 240 | int received = server->RecvFrom(receive_buffer); |
| 241 | return received == sent && ::memcmp(buf, payload.data(), len) == 0; |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 242 | } |
| 243 | |
| 244 | void TestPhysicalInternal(const SocketAddress& int_addr) { |
Jonas Oreland | c06fe8b | 2022-03-28 12:58:26 | [diff] [blame] | 245 | webrtc::test::ScopedKeyValueConfig field_trials; |
Niels Möller | 83830f3 | 2022-05-20 07:12:57 | [diff] [blame] | 246 | rtc::AutoThread main_thread; |
Niels Möller | aa37316 | 2021-09-28 14:09:07 | [diff] [blame] | 247 | PhysicalSocketServer socket_server; |
Jonas Oreland | c06fe8b | 2022-03-28 12:58:26 | [diff] [blame] | 248 | BasicNetworkManager network_manager(nullptr, &socket_server, &field_trials); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 249 | network_manager.StartUpdating(); |
| 250 | // Process pending messages so the network list is updated. |
| 251 | Thread::Current()->ProcessMessages(0); |
| 252 | |
Niels Möller | 2221144 | 2022-04-07 09:43:28 | [diff] [blame] | 253 | std::vector<const Network*> networks = network_manager.GetNetworks(); |
Taylor Brandstetter | 0c7e9f5 | 2015-12-29 22:14:52 | [diff] [blame] | 254 | networks.erase(std::remove_if(networks.begin(), networks.end(), |
Niels Möller | e0c6bdf | 2022-03-24 14:18:02 | [diff] [blame] | 255 | [](const rtc::Network* network) { |
Taylor Brandstetter | 0c7e9f5 | 2015-12-29 22:14:52 | [diff] [blame] | 256 | return rtc::kDefaultNetworkIgnoreMask & |
| 257 | network->type(); |
| 258 | }), |
| 259 | networks.end()); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 260 | if (networks.empty()) { |
Mirko Bonadei | 675513b | 2017-11-09 10:09:25 | [diff] [blame] | 261 | RTC_LOG(LS_WARNING) << "Not enough network adapters for test."; |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 262 | return; |
| 263 | } |
| 264 | |
| 265 | SocketAddress ext_addr1(int_addr); |
| 266 | SocketAddress ext_addr2; |
| 267 | // Find an available IP with matching family. The test breaks if int_addr |
| 268 | // can't talk to ip, so check for connectivity as well. |
Niels Möller | d959f3a | 2022-04-19 09:29:19 | [diff] [blame] | 269 | for (const Network* const network : networks) { |
| 270 | const IPAddress& ip = network->GetBestIP(); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 271 | if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) { |
| 272 | ext_addr2.SetIP(ip); |
| 273 | break; |
| 274 | } |
| 275 | } |
| 276 | if (ext_addr2.IsNil()) { |
Jonas Olsson | abbe841 | 2018-04-03 11:40:05 | [diff] [blame] | 277 | RTC_LOG(LS_WARNING) << "No available IP of same family as " |
| 278 | << int_addr.ToString(); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 279 | return; |
| 280 | } |
| 281 | |
Jonas Olsson | abbe841 | 2018-04-03 11:40:05 | [diff] [blame] | 282 | RTC_LOG(LS_INFO) << "selected ip " << ext_addr2.ipaddr().ToString(); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 283 | |
| 284 | SocketAddress ext_addrs[4] = { |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 285 | SocketAddress(ext_addr1), SocketAddress(ext_addr2), |
| 286 | SocketAddress(ext_addr1), SocketAddress(ext_addr2)}; |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 287 | |
jbauch | 555604a | 2016-04-26 10:13:22 | [diff] [blame] | 288 | std::unique_ptr<PhysicalSocketServer> int_pss(new PhysicalSocketServer()); |
| 289 | std::unique_ptr<PhysicalSocketServer> ext_pss(new PhysicalSocketServer()); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 290 | |
| 291 | TestBindings(int_pss.get(), int_addr, ext_pss.get(), ext_addrs); |
| 292 | TestFilters(int_pss.get(), int_addr, ext_pss.get(), ext_addrs); |
| 293 | } |
| 294 | |
henrike@webrtc.org | c732a3e | 2014-10-09 22:08:15 | [diff] [blame] | 295 | TEST(NatTest, TestPhysicalIPv4) { |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 296 | TestPhysicalInternal(SocketAddress("127.0.0.1", 0)); |
| 297 | } |
| 298 | |
henrike@webrtc.org | c732a3e | 2014-10-09 22:08:15 | [diff] [blame] | 299 | TEST(NatTest, TestPhysicalIPv6) { |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 300 | if (HasIPv6Enabled()) { |
| 301 | TestPhysicalInternal(SocketAddress("::1", 0)); |
| 302 | } else { |
Mirko Bonadei | 675513b | 2017-11-09 10:09:25 | [diff] [blame] | 303 | RTC_LOG(LS_WARNING) << "No IPv6, skipping"; |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 304 | } |
| 305 | } |
| 306 | |
Guo-wei Shieh | be508a1 | 2015-04-06 19:48:47 | [diff] [blame] | 307 | namespace { |
| 308 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 309 | class TestVirtualSocketServer : public VirtualSocketServer { |
| 310 | public: |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 311 | // Expose this publicly |
| 312 | IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); } |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 313 | }; |
| 314 | |
Guo-wei Shieh | be508a1 | 2015-04-06 19:48:47 | [diff] [blame] | 315 | } // namespace |
| 316 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 317 | void TestVirtualInternal(int family) { |
Niels Möller | 83830f3 | 2022-05-20 07:12:57 | [diff] [blame] | 318 | rtc::AutoThread main_thread; |
jbauch | 555604a | 2016-04-26 10:13:22 | [diff] [blame] | 319 | std::unique_ptr<TestVirtualSocketServer> int_vss( |
deadbeef | 98e186c | 2017-05-17 01:00:06 | [diff] [blame] | 320 | new TestVirtualSocketServer()); |
jbauch | 555604a | 2016-04-26 10:13:22 | [diff] [blame] | 321 | std::unique_ptr<TestVirtualSocketServer> ext_vss( |
deadbeef | 98e186c | 2017-05-17 01:00:06 | [diff] [blame] | 322 | new TestVirtualSocketServer()); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 323 | |
| 324 | SocketAddress int_addr; |
| 325 | SocketAddress ext_addrs[4]; |
| 326 | int_addr.SetIP(int_vss->GetNextIP(family)); |
| 327 | ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.family())); |
| 328 | ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.family())); |
| 329 | ext_addrs[2].SetIP(ext_addrs[0].ipaddr()); |
| 330 | ext_addrs[3].SetIP(ext_addrs[1].ipaddr()); |
| 331 | |
| 332 | TestBindings(int_vss.get(), int_addr, ext_vss.get(), ext_addrs); |
| 333 | TestFilters(int_vss.get(), int_addr, ext_vss.get(), ext_addrs); |
| 334 | } |
| 335 | |
henrike@webrtc.org | c732a3e | 2014-10-09 22:08:15 | [diff] [blame] | 336 | TEST(NatTest, TestVirtualIPv4) { |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 337 | TestVirtualInternal(AF_INET); |
| 338 | } |
| 339 | |
henrike@webrtc.org | c732a3e | 2014-10-09 22:08:15 | [diff] [blame] | 340 | TEST(NatTest, TestVirtualIPv6) { |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 341 | if (HasIPv6Enabled()) { |
| 342 | TestVirtualInternal(AF_INET6); |
| 343 | } else { |
Mirko Bonadei | 675513b | 2017-11-09 10:09:25 | [diff] [blame] | 344 | RTC_LOG(LS_WARNING) << "No IPv6, skipping"; |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 345 | } |
| 346 | } |
| 347 | |
Mirko Bonadei | 6a489f2 | 2019-04-09 13:11:12 | [diff] [blame] | 348 | class NatTcpTest : public ::testing::Test, public sigslot::has_slots<> { |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 349 | public: |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 350 | NatTcpTest() |
| 351 | : int_addr_("192.168.0.1", 0), |
| 352 | ext_addr_("10.0.0.1", 0), |
| 353 | connected_(false), |
deadbeef | 98e186c | 2017-05-17 01:00:06 | [diff] [blame] | 354 | int_vss_(new TestVirtualSocketServer()), |
| 355 | ext_vss_(new TestVirtualSocketServer()), |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 356 | int_thread_(new Thread(int_vss_.get())), |
| 357 | ext_thread_(new Thread(ext_vss_.get())), |
deadbeef | 98e186c | 2017-05-17 01:00:06 | [diff] [blame] | 358 | nat_(new NATServer(NAT_OPEN_CONE, |
Per K | a8cd2ba | 2023-12-13 07:10:06 | [diff] [blame] | 359 | *int_thread_, |
deadbeef | 98e186c | 2017-05-17 01:00:06 | [diff] [blame] | 360 | int_vss_.get(), |
| 361 | int_addr_, |
| 362 | int_addr_, |
Per K | a8cd2ba | 2023-12-13 07:10:06 | [diff] [blame] | 363 | *ext_thread_, |
deadbeef | 98e186c | 2017-05-17 01:00:06 | [diff] [blame] | 364 | ext_vss_.get(), |
| 365 | ext_addr_)), |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 366 | natsf_(new NATSocketFactory(int_vss_.get(), |
| 367 | nat_->internal_udp_address(), |
| 368 | nat_->internal_tcp_address())) { |
| 369 | int_thread_->Start(); |
| 370 | ext_thread_->Start(); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 371 | } |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 372 | |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 373 | void OnConnectEvent(Socket* socket) { connected_ = true; } |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 374 | |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 375 | void OnAcceptEvent(Socket* socket) { |
deadbeef | 37f5ecf | 2017-02-27 22:06:41 | [diff] [blame] | 376 | accepted_.reset(server_->Accept(nullptr)); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 377 | } |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 378 | |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 379 | void OnCloseEvent(Socket* socket, int error) {} |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 380 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 381 | void ConnectEvents() { |
| 382 | server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent); |
| 383 | client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent); |
| 384 | } |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 385 | |
| 386 | SocketAddress int_addr_; |
| 387 | SocketAddress ext_addr_; |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 388 | bool connected_; |
jbauch | 555604a | 2016-04-26 10:13:22 | [diff] [blame] | 389 | std::unique_ptr<TestVirtualSocketServer> int_vss_; |
| 390 | std::unique_ptr<TestVirtualSocketServer> ext_vss_; |
| 391 | std::unique_ptr<Thread> int_thread_; |
| 392 | std::unique_ptr<Thread> ext_thread_; |
| 393 | std::unique_ptr<NATServer> nat_; |
| 394 | std::unique_ptr<NATSocketFactory> natsf_; |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 395 | std::unique_ptr<Socket> client_; |
| 396 | std::unique_ptr<Socket> server_; |
| 397 | std::unique_ptr<Socket> accepted_; |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 398 | }; |
| 399 | |
magjed | 65eb1c3 | 2015-07-22 13:28:26 | [diff] [blame] | 400 | TEST_F(NatTcpTest, DISABLED_TestConnectOut) { |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 401 | server_.reset(ext_vss_->CreateSocket(AF_INET, SOCK_STREAM)); |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 402 | server_->Bind(ext_addr_); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 403 | server_->Listen(5); |
| 404 | |
Niels Möller | d0b8879 | 2021-08-12 08:32:30 | [diff] [blame] | 405 | client_.reset(natsf_->CreateSocket(AF_INET, SOCK_STREAM)); |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 406 | EXPECT_GE(0, client_->Bind(int_addr_)); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 407 | EXPECT_GE(0, client_->Connect(server_->GetLocalAddress())); |
| 408 | |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 409 | ConnectEvents(); |
| 410 | |
| 411 | EXPECT_TRUE_WAIT(connected_, 1000); |
| 412 | EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress()); |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 413 | EXPECT_EQ(accepted_->GetRemoteAddress().ipaddr(), ext_addr_.ipaddr()); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 414 | |
jbauch | 555604a | 2016-04-26 10:13:22 | [diff] [blame] | 415 | std::unique_ptr<rtc::TestClient> in(CreateTCPTestClient(client_.release())); |
| 416 | std::unique_ptr<rtc::TestClient> out( |
deadbeef | c5d0d95 | 2015-07-16 17:22:21 | [diff] [blame] | 417 | CreateTCPTestClient(accepted_.release())); |
| 418 | |
| 419 | const char* buf = "test_packet"; |
| 420 | size_t len = strlen(buf); |
| 421 | |
| 422 | in->Send(buf, len); |
| 423 | SocketAddress trans_addr; |
| 424 | EXPECT_TRUE(out->CheckNextPacket(buf, len, &trans_addr)); |
| 425 | |
| 426 | out->Send(buf, len); |
| 427 | EXPECT_TRUE(in->CheckNextPacket(buf, len, &trans_addr)); |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 428 | } |
Mirko Bonadei | e10b163 | 2018-12-11 17:43:40 | [diff] [blame] | 429 | |
| 430 | } // namespace |
| 431 | } // namespace rtc |