Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: webrtc/base/nat_unittest.cc

Issue 2877023002: Move webrtc/{base => rtc_base} (Closed)
Patch Set: update presubmit.py and DEPS include rules Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/mod_ops_unittest.cc ('k') | webrtc/base/natserver.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
11 #include <algorithm>
12 #include <memory>
13 #include <string>
14
15 #include "webrtc/base/asynctcpsocket.h"
16 #include "webrtc/base/gunit.h"
17 #include "webrtc/base/logging.h"
18 #include "webrtc/base/natserver.h"
19 #include "webrtc/base/natsocketfactory.h"
20 #include "webrtc/base/nethelpers.h"
21 #include "webrtc/base/network.h"
22 #include "webrtc/base/physicalsocketserver.h"
23 #include "webrtc/base/ptr_util.h"
24 #include "webrtc/base/testclient.h"
25 #include "webrtc/base/virtualsocketserver.h"
26
27 using namespace rtc;
28
29 bool CheckReceive(
30 TestClient* client, bool should_receive, const char* buf, size_t size) {
31 return (should_receive) ?
32 client->CheckNextPacket(buf, size, 0) :
33 client->CheckNoPacket();
34 }
35
36 TestClient* CreateTestClient(
37 SocketFactory* factory, const SocketAddress& local_addr) {
38 return new TestClient(
39 WrapUnique(AsyncUDPSocket::Create(factory, local_addr)));
40 }
41
42 TestClient* CreateTCPTestClient(AsyncSocket* socket) {
43 return new TestClient(MakeUnique<AsyncTCPSocket>(socket, false));
44 }
45
46 // Tests that when sending from internal_addr to external_addrs through the
47 // NAT type specified by nat_type, all external addrs receive the sent packet
48 // and, if exp_same is true, all use the same mapped-address on the NAT.
49 void TestSend(
50 SocketServer* internal, const SocketAddress& internal_addr,
51 SocketServer* external, const SocketAddress external_addrs[4],
52 NATType nat_type, bool exp_same) {
53 Thread th_int(internal);
54 Thread th_ext(external);
55
56 SocketAddress server_addr = internal_addr;
57 server_addr.SetPort(0); // Auto-select a port
58 NATServer* nat = new NATServer(nat_type, internal, server_addr, server_addr,
59 external, external_addrs[0]);
60 NATSocketFactory* natsf = new NATSocketFactory(internal,
61 nat->internal_udp_address(),
62 nat->internal_tcp_address());
63
64 TestClient* in = CreateTestClient(natsf, internal_addr);
65 TestClient* out[4];
66 for (int i = 0; i < 4; i++)
67 out[i] = CreateTestClient(external, external_addrs[i]);
68
69 th_int.Start();
70 th_ext.Start();
71
72 const char* buf = "filter_test";
73 size_t len = strlen(buf);
74
75 in->SendTo(buf, len, out[0]->address());
76 SocketAddress trans_addr;
77 EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
78
79 for (int i = 1; i < 4; i++) {
80 in->SendTo(buf, len, out[i]->address());
81 SocketAddress trans_addr2;
82 EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2));
83 bool are_same = (trans_addr == trans_addr2);
84 ASSERT_EQ(are_same, exp_same) << "same translated address";
85 ASSERT_NE(AF_UNSPEC, trans_addr.family());
86 ASSERT_NE(AF_UNSPEC, trans_addr2.family());
87 }
88
89 th_int.Stop();
90 th_ext.Stop();
91
92 delete nat;
93 delete natsf;
94 delete in;
95 for (int i = 0; i < 4; i++)
96 delete out[i];
97 }
98
99 // Tests that when sending from external_addrs to internal_addr, the packet
100 // is delivered according to the specified filter_ip and filter_port rules.
101 void TestRecv(
102 SocketServer* internal, const SocketAddress& internal_addr,
103 SocketServer* external, const SocketAddress external_addrs[4],
104 NATType nat_type, bool filter_ip, bool filter_port) {
105 Thread th_int(internal);
106 Thread th_ext(external);
107
108 SocketAddress server_addr = internal_addr;
109 server_addr.SetPort(0); // Auto-select a port
110 NATServer* nat = new NATServer(nat_type, internal, server_addr, server_addr,
111 external, external_addrs[0]);
112 NATSocketFactory* natsf = new NATSocketFactory(internal,
113 nat->internal_udp_address(),
114 nat->internal_tcp_address());
115
116 TestClient* in = CreateTestClient(natsf, internal_addr);
117 TestClient* out[4];
118 for (int i = 0; i < 4; i++)
119 out[i] = CreateTestClient(external, external_addrs[i]);
120
121 th_int.Start();
122 th_ext.Start();
123
124 const char* buf = "filter_test";
125 size_t len = strlen(buf);
126
127 in->SendTo(buf, len, out[0]->address());
128 SocketAddress trans_addr;
129 EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
130
131 out[1]->SendTo(buf, len, trans_addr);
132 EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len));
133
134 out[2]->SendTo(buf, len, trans_addr);
135 EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len));
136
137 out[3]->SendTo(buf, len, trans_addr);
138 EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len));
139
140 th_int.Stop();
141 th_ext.Stop();
142
143 delete nat;
144 delete natsf;
145 delete in;
146 for (int i = 0; i < 4; i++)
147 delete out[i];
148 }
149
150 // Tests that NATServer allocates bindings properly.
151 void TestBindings(
152 SocketServer* internal, const SocketAddress& internal_addr,
153 SocketServer* external, const SocketAddress external_addrs[4]) {
154 TestSend(internal, internal_addr, external, external_addrs,
155 NAT_OPEN_CONE, true);
156 TestSend(internal, internal_addr, external, external_addrs,
157 NAT_ADDR_RESTRICTED, true);
158 TestSend(internal, internal_addr, external, external_addrs,
159 NAT_PORT_RESTRICTED, true);
160 TestSend(internal, internal_addr, external, external_addrs,
161 NAT_SYMMETRIC, false);
162 }
163
164 // Tests that NATServer filters packets properly.
165 void TestFilters(
166 SocketServer* internal, const SocketAddress& internal_addr,
167 SocketServer* external, const SocketAddress external_addrs[4]) {
168 TestRecv(internal, internal_addr, external, external_addrs,
169 NAT_OPEN_CONE, false, false);
170 TestRecv(internal, internal_addr, external, external_addrs,
171 NAT_ADDR_RESTRICTED, true, false);
172 TestRecv(internal, internal_addr, external, external_addrs,
173 NAT_PORT_RESTRICTED, true, true);
174 TestRecv(internal, internal_addr, external, external_addrs,
175 NAT_SYMMETRIC, true, true);
176 }
177
178 bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) {
179 // The physical NAT tests require connectivity to the selected ip from the
180 // internal address used for the NAT. Things like firewalls can break that, so
181 // check to see if it's worth even trying with this ip.
182 std::unique_ptr<PhysicalSocketServer> pss(new PhysicalSocketServer());
183 std::unique_ptr<AsyncSocket> client(
184 pss->CreateAsyncSocket(src.family(), SOCK_DGRAM));
185 std::unique_ptr<AsyncSocket> server(
186 pss->CreateAsyncSocket(src.family(), SOCK_DGRAM));
187 if (client->Bind(SocketAddress(src.ipaddr(), 0)) != 0 ||
188 server->Bind(SocketAddress(dst, 0)) != 0) {
189 return false;
190 }
191 const char* buf = "hello other socket";
192 size_t len = strlen(buf);
193 int sent = client->SendTo(buf, len, server->GetLocalAddress());
194 SocketAddress addr;
195 const size_t kRecvBufSize = 64;
196 char recvbuf[kRecvBufSize];
197 Thread::Current()->SleepMs(100);
198 int received = server->RecvFrom(recvbuf, kRecvBufSize, &addr, nullptr);
199 return received == sent && ::memcmp(buf, recvbuf, len) == 0;
200 }
201
202 void TestPhysicalInternal(const SocketAddress& int_addr) {
203 BasicNetworkManager network_manager;
204 network_manager.set_ipv6_enabled(true);
205 network_manager.StartUpdating();
206 // Process pending messages so the network list is updated.
207 Thread::Current()->ProcessMessages(0);
208
209 std::vector<Network*> networks;
210 network_manager.GetNetworks(&networks);
211 networks.erase(std::remove_if(networks.begin(), networks.end(),
212 [](rtc::Network* network) {
213 return rtc::kDefaultNetworkIgnoreMask &
214 network->type();
215 }),
216 networks.end());
217 if (networks.empty()) {
218 LOG(LS_WARNING) << "Not enough network adapters for test.";
219 return;
220 }
221
222 SocketAddress ext_addr1(int_addr);
223 SocketAddress ext_addr2;
224 // Find an available IP with matching family. The test breaks if int_addr
225 // can't talk to ip, so check for connectivity as well.
226 for (std::vector<Network*>::iterator it = networks.begin();
227 it != networks.end(); ++it) {
228 const IPAddress& ip = (*it)->GetBestIP();
229 if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) {
230 ext_addr2.SetIP(ip);
231 break;
232 }
233 }
234 if (ext_addr2.IsNil()) {
235 LOG(LS_WARNING) << "No available IP of same family as " << int_addr;
236 return;
237 }
238
239 LOG(LS_INFO) << "selected ip " << ext_addr2.ipaddr();
240
241 SocketAddress ext_addrs[4] = {
242 SocketAddress(ext_addr1),
243 SocketAddress(ext_addr2),
244 SocketAddress(ext_addr1),
245 SocketAddress(ext_addr2)
246 };
247
248 std::unique_ptr<PhysicalSocketServer> int_pss(new PhysicalSocketServer());
249 std::unique_ptr<PhysicalSocketServer> ext_pss(new PhysicalSocketServer());
250
251 TestBindings(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
252 TestFilters(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
253 }
254
255 TEST(NatTest, TestPhysicalIPv4) {
256 TestPhysicalInternal(SocketAddress("127.0.0.1", 0));
257 }
258
259 TEST(NatTest, TestPhysicalIPv6) {
260 if (HasIPv6Enabled()) {
261 TestPhysicalInternal(SocketAddress("::1", 0));
262 } else {
263 LOG(LS_WARNING) << "No IPv6, skipping";
264 }
265 }
266
267 namespace {
268
269 class TestVirtualSocketServer : public VirtualSocketServer {
270 public:
271 // Expose this publicly
272 IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); }
273 };
274
275 } // namespace
276
277 void TestVirtualInternal(int family) {
278 std::unique_ptr<TestVirtualSocketServer> int_vss(
279 new TestVirtualSocketServer());
280 std::unique_ptr<TestVirtualSocketServer> ext_vss(
281 new TestVirtualSocketServer());
282
283 SocketAddress int_addr;
284 SocketAddress ext_addrs[4];
285 int_addr.SetIP(int_vss->GetNextIP(family));
286 ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.family()));
287 ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.family()));
288 ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
289 ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
290
291 TestBindings(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
292 TestFilters(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
293 }
294
295 TEST(NatTest, TestVirtualIPv4) {
296 TestVirtualInternal(AF_INET);
297 }
298
299 TEST(NatTest, TestVirtualIPv6) {
300 if (HasIPv6Enabled()) {
301 TestVirtualInternal(AF_INET6);
302 } else {
303 LOG(LS_WARNING) << "No IPv6, skipping";
304 }
305 }
306
307 class NatTcpTest : public testing::Test, public sigslot::has_slots<> {
308 public:
309 NatTcpTest()
310 : int_addr_("192.168.0.1", 0),
311 ext_addr_("10.0.0.1", 0),
312 connected_(false),
313 int_vss_(new TestVirtualSocketServer()),
314 ext_vss_(new TestVirtualSocketServer()),
315 int_thread_(new Thread(int_vss_.get())),
316 ext_thread_(new Thread(ext_vss_.get())),
317 nat_(new NATServer(NAT_OPEN_CONE,
318 int_vss_.get(),
319 int_addr_,
320 int_addr_,
321 ext_vss_.get(),
322 ext_addr_)),
323 natsf_(new NATSocketFactory(int_vss_.get(),
324 nat_->internal_udp_address(),
325 nat_->internal_tcp_address())) {
326 int_thread_->Start();
327 ext_thread_->Start();
328 }
329
330 void OnConnectEvent(AsyncSocket* socket) {
331 connected_ = true;
332 }
333
334 void OnAcceptEvent(AsyncSocket* socket) {
335 accepted_.reset(server_->Accept(nullptr));
336 }
337
338 void OnCloseEvent(AsyncSocket* socket, int error) {
339 }
340
341 void ConnectEvents() {
342 server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
343 client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
344 }
345
346 SocketAddress int_addr_;
347 SocketAddress ext_addr_;
348 bool connected_;
349 std::unique_ptr<TestVirtualSocketServer> int_vss_;
350 std::unique_ptr<TestVirtualSocketServer> ext_vss_;
351 std::unique_ptr<Thread> int_thread_;
352 std::unique_ptr<Thread> ext_thread_;
353 std::unique_ptr<NATServer> nat_;
354 std::unique_ptr<NATSocketFactory> natsf_;
355 std::unique_ptr<AsyncSocket> client_;
356 std::unique_ptr<AsyncSocket> server_;
357 std::unique_ptr<AsyncSocket> accepted_;
358 };
359
360 TEST_F(NatTcpTest, DISABLED_TestConnectOut) {
361 server_.reset(ext_vss_->CreateAsyncSocket(SOCK_STREAM));
362 server_->Bind(ext_addr_);
363 server_->Listen(5);
364
365 client_.reset(natsf_->CreateAsyncSocket(SOCK_STREAM));
366 EXPECT_GE(0, client_->Bind(int_addr_));
367 EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
368
369 ConnectEvents();
370
371 EXPECT_TRUE_WAIT(connected_, 1000);
372 EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
373 EXPECT_EQ(accepted_->GetRemoteAddress().ipaddr(), ext_addr_.ipaddr());
374
375 std::unique_ptr<rtc::TestClient> in(CreateTCPTestClient(client_.release()));
376 std::unique_ptr<rtc::TestClient> out(
377 CreateTCPTestClient(accepted_.release()));
378
379 const char* buf = "test_packet";
380 size_t len = strlen(buf);
381
382 in->Send(buf, len);
383 SocketAddress trans_addr;
384 EXPECT_TRUE(out->CheckNextPacket(buf, len, &trans_addr));
385
386 out->Send(buf, len);
387 EXPECT_TRUE(in->CheckNextPacket(buf, len, &trans_addr));
388 }
389 // #endif
OLDNEW
« no previous file with comments | « webrtc/base/mod_ops_unittest.cc ('k') | webrtc/base/natserver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698