1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 // Original author: bcampen@mozilla.com
8
9 extern "C" {
10 #include "stun_msg.h" // for NR_STUN_MAX_MESSAGE_SIZE
11 #include "stun_util.h"
12 #include "nr_api.h"
13 #include "async_wait.h"
14 #include "nr_socket.h"
15 #include "nr_socket_local.h"
16 #include "stun_hint.h"
17 #include "local_addr.h"
18 #include "registry.h"
19 }
20
21 #include "test_nr_socket.h"
22
23 #include "nsCOMPtr.h"
24 #include "nsNetCID.h"
25 #include "nsServiceManagerUtils.h"
26 #include "runnable_utils.h"
27
28 #include <vector>
29
30 #define GTEST_HAS_RTTI 0
31 #include "gtest/gtest.h"
32 #include "gtest_utils.h"
33
34 #define DATA_BUF_SIZE 1024
35
36 namespace mozilla {
37
38 class TestNrSocketTest : public MtransportTest {
39 public:
TestNrSocketTest()40 TestNrSocketTest()
41 : MtransportTest(),
42 wait_done_for_main_(false),
43 sts_(),
44 public_addrs_(),
45 private_addrs_(),
46 nats_() {}
47
SetUp()48 void SetUp() override {
49 MtransportTest::SetUp();
50
51 // Get the transport service as a dispatch target
52 nsresult rv;
53 sts_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
54 EXPECT_TRUE(NS_SUCCEEDED(rv)) << "Failed to get STS: " << (int)rv;
55 }
56
TearDown()57 void TearDown() override {
58 sts_->Dispatch(WrapRunnable(this, &TestNrSocketTest::TearDown_s),
59 NS_DISPATCH_SYNC);
60
61 MtransportTest::TearDown();
62 }
63
TearDown_s()64 void TearDown_s() {
65 public_addrs_.clear();
66 private_addrs_.clear();
67 nats_.clear();
68 sts_ = nullptr;
69 }
70
CreateTestNrSocket_s(const char * ip_str,int proto,TestNat * nat)71 RefPtr<TestNrSocket> CreateTestNrSocket_s(const char* ip_str, int proto,
72 TestNat* nat) {
73 // If no nat is supplied, we create a default NAT which is disabled. This
74 // is how we simulate a non-natted socket.
75 RefPtr<TestNrSocket> sock(new TestNrSocket(nat ? nat : new TestNat));
76 nr_transport_addr address;
77 nr_str_port_to_transport_addr(ip_str, 0, proto, &address);
78 int r = sock->create(&address);
79 if (r) {
80 return nullptr;
81 }
82 return sock;
83 }
84
CreatePublicAddrs(size_t count,const char * ip_str="127.0.0.1",int proto=IPPROTO_UDP)85 void CreatePublicAddrs(size_t count, const char* ip_str = "127.0.0.1",
86 int proto = IPPROTO_UDP) {
87 sts_->Dispatch(WrapRunnable(this, &TestNrSocketTest::CreatePublicAddrs_s,
88 count, ip_str, proto),
89 NS_DISPATCH_SYNC);
90 }
91
CreatePublicAddrs_s(size_t count,const char * ip_str,int proto)92 void CreatePublicAddrs_s(size_t count, const char* ip_str, int proto) {
93 while (count--) {
94 auto sock = CreateTestNrSocket_s(ip_str, proto, nullptr);
95 ASSERT_TRUE(sock)
96 << "Failed to create socket";
97 public_addrs_.push_back(sock);
98 }
99 }
100
CreatePrivateAddrs(size_t size,const char * ip_str="127.0.0.1",int proto=IPPROTO_UDP)101 RefPtr<TestNat> CreatePrivateAddrs(size_t size,
102 const char* ip_str = "127.0.0.1",
103 int proto = IPPROTO_UDP) {
104 RefPtr<TestNat> result;
105 sts_->Dispatch(
106 WrapRunnableRet(&result, this, &TestNrSocketTest::CreatePrivateAddrs_s,
107 size, ip_str, proto),
108 NS_DISPATCH_SYNC);
109 return result;
110 }
111
CreatePrivateAddrs_s(size_t count,const char * ip_str,int proto)112 RefPtr<TestNat> CreatePrivateAddrs_s(size_t count, const char* ip_str,
113 int proto) {
114 RefPtr<TestNat> nat(new TestNat);
115 while (count--) {
116 auto sock = CreateTestNrSocket_s(ip_str, proto, nat);
117 if (!sock) {
118 EXPECT_TRUE(false) << "Failed to create socket";
119 break;
120 }
121 private_addrs_.push_back(sock);
122 }
123 nat->enabled_ = true;
124 nats_.push_back(nat);
125 return nat;
126 }
127
CheckConnectivityVia(TestNrSocket * from,TestNrSocket * to,const nr_transport_addr & via,nr_transport_addr * sender_external_address=nullptr)128 bool CheckConnectivityVia(
129 TestNrSocket* from, TestNrSocket* to, const nr_transport_addr& via,
130 nr_transport_addr* sender_external_address = nullptr) {
131 MOZ_ASSERT(from);
132
133 if (!WaitForWriteable(from)) {
134 return false;
135 }
136
137 int result = 0;
138 sts_->Dispatch(WrapRunnableRet(&result, this, &TestNrSocketTest::SendData_s,
139 from, via),
140 NS_DISPATCH_SYNC);
141 if (result) {
142 return false;
143 }
144
145 if (!WaitForReadable(to)) {
146 return false;
147 }
148
149 nr_transport_addr dummy_outparam;
150 if (!sender_external_address) {
151 sender_external_address = &dummy_outparam;
152 }
153
154 MOZ_ASSERT(to);
155 sts_->Dispatch(WrapRunnableRet(&result, this, &TestNrSocketTest::RecvData_s,
156 to, sender_external_address),
157 NS_DISPATCH_SYNC);
158
159 return !result;
160 }
161
CheckConnectivity(TestNrSocket * from,TestNrSocket * to,nr_transport_addr * sender_external_address=nullptr)162 bool CheckConnectivity(TestNrSocket* from, TestNrSocket* to,
163 nr_transport_addr* sender_external_address = nullptr) {
164 nr_transport_addr destination_address;
165 int r = GetAddress(to, &destination_address);
166 if (r) {
167 return false;
168 }
169
170 return CheckConnectivityVia(from, to, destination_address,
171 sender_external_address);
172 }
173
CheckTcpConnectivity(TestNrSocket * from,TestNrSocket * to)174 bool CheckTcpConnectivity(TestNrSocket* from, TestNrSocket* to) {
175 NrSocketBase* accepted_sock;
176 if (!Connect(from, to, &accepted_sock)) {
177 std::cerr << "Connect failed" << std::endl;
178 return false;
179 }
180
181 // write on |from|, recv on |accepted_sock|
182 if (!WaitForWriteable(from)) {
183 std::cerr << __LINE__ << "WaitForWriteable (1) failed" << std::endl;
184 return false;
185 }
186
187 int r;
188 sts_->Dispatch(
189 WrapRunnableRet(&r, this, &TestNrSocketTest::SendDataTcp_s, from),
190 NS_DISPATCH_SYNC);
191 if (r) {
192 std::cerr << "SendDataTcp_s (1) failed" << std::endl;
193 return false;
194 }
195
196 if (!WaitForReadable(accepted_sock)) {
197 std::cerr << __LINE__ << "WaitForReadable (1) failed" << std::endl;
198 return false;
199 }
200
201 sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::RecvDataTcp_s,
202 accepted_sock),
203 NS_DISPATCH_SYNC);
204 if (r) {
205 std::cerr << "RecvDataTcp_s (1) failed" << std::endl;
206 return false;
207 }
208
209 if (!WaitForWriteable(accepted_sock)) {
210 std::cerr << __LINE__ << "WaitForWriteable (2) failed" << std::endl;
211 return false;
212 }
213
214 sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::SendDataTcp_s,
215 accepted_sock),
216 NS_DISPATCH_SYNC);
217 if (r) {
218 std::cerr << "SendDataTcp_s (2) failed" << std::endl;
219 return false;
220 }
221
222 if (!WaitForReadable(from)) {
223 std::cerr << __LINE__ << "WaitForReadable (2) failed" << std::endl;
224 return false;
225 }
226
227 sts_->Dispatch(
228 WrapRunnableRet(&r, this, &TestNrSocketTest::RecvDataTcp_s, from),
229 NS_DISPATCH_SYNC);
230 if (r) {
231 std::cerr << "RecvDataTcp_s (2) failed" << std::endl;
232 return false;
233 }
234
235 return true;
236 }
237
GetAddress(TestNrSocket * sock,nr_transport_addr_ * address)238 int GetAddress(TestNrSocket* sock, nr_transport_addr_* address) {
239 MOZ_ASSERT(sock);
240 MOZ_ASSERT(address);
241 int r;
242 sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::GetAddress_s,
243 sock, address),
244 NS_DISPATCH_SYNC);
245 return r;
246 }
247
GetAddress_s(TestNrSocket * sock,nr_transport_addr * address)248 int GetAddress_s(TestNrSocket* sock, nr_transport_addr* address) {
249 return sock->getaddr(address);
250 }
251
SendData_s(TestNrSocket * from,const nr_transport_addr & to)252 int SendData_s(TestNrSocket* from, const nr_transport_addr& to) {
253 // It is up to caller to ensure that |from| is writeable.
254 const char buf[] = "foobajooba";
255 return from->sendto(buf, sizeof(buf), 0, &to);
256 }
257
SendDataTcp_s(NrSocketBase * from)258 int SendDataTcp_s(NrSocketBase* from) {
259 // It is up to caller to ensure that |from| is writeable.
260 const char buf[] = "foobajooba";
261 size_t written;
262 return from->write(buf, sizeof(buf), &written);
263 }
264
RecvData_s(TestNrSocket * to,nr_transport_addr * from)265 int RecvData_s(TestNrSocket* to, nr_transport_addr* from) {
266 // It is up to caller to ensure that |to| is readable
267 char buf[DATA_BUF_SIZE];
268 size_t len;
269 // Maybe check that data matches?
270 int r = to->recvfrom(buf, sizeof(buf), &len, 0, from);
271 if (!r && (len == 0)) {
272 r = R_INTERNAL;
273 }
274 return r;
275 }
276
RecvDataTcp_s(NrSocketBase * to)277 int RecvDataTcp_s(NrSocketBase* to) {
278 // It is up to caller to ensure that |to| is readable
279 char buf[DATA_BUF_SIZE];
280 size_t len;
281 // Maybe check that data matches?
282 int r = to->read(buf, sizeof(buf), &len);
283 if (!r && (len == 0)) {
284 r = R_INTERNAL;
285 }
286 return r;
287 }
288
Listen_s(TestNrSocket * to)289 int Listen_s(TestNrSocket* to) {
290 // listen on |to|
291 int r = to->listen(1);
292 if (r) {
293 return r;
294 }
295 return 0;
296 }
297
Connect_s(TestNrSocket * from,TestNrSocket * to)298 int Connect_s(TestNrSocket* from, TestNrSocket* to) {
299 // connect on |from|
300 nr_transport_addr destination_address;
301 int r = to->getaddr(&destination_address);
302 if (r) {
303 return r;
304 }
305
306 r = from->connect(&destination_address);
307 if (r) {
308 return r;
309 }
310
311 return 0;
312 }
313
Accept_s(TestNrSocket * to,NrSocketBase ** accepted_sock)314 int Accept_s(TestNrSocket* to, NrSocketBase** accepted_sock) {
315 nr_socket* sock;
316 nr_transport_addr source_address;
317 int r = to->accept(&source_address, &sock);
318 if (r) {
319 return r;
320 }
321
322 *accepted_sock = reinterpret_cast<NrSocketBase*>(sock->obj);
323 return 0;
324 }
325
Connect(TestNrSocket * from,TestNrSocket * to,NrSocketBase ** accepted_sock)326 bool Connect(TestNrSocket* from, TestNrSocket* to,
327 NrSocketBase** accepted_sock) {
328 int r;
329 sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::Listen_s, to),
330 NS_DISPATCH_SYNC);
331 if (r) {
332 std::cerr << "Listen_s failed: " << r << std::endl;
333 return false;
334 }
335
336 sts_->Dispatch(
337 WrapRunnableRet(&r, this, &TestNrSocketTest::Connect_s, from, to),
338 NS_DISPATCH_SYNC);
339 if (r && r != R_WOULDBLOCK) {
340 std::cerr << "Connect_s failed: " << r << std::endl;
341 return false;
342 }
343
344 if (!WaitForReadable(to)) {
345 std::cerr << "WaitForReadable failed" << std::endl;
346 return false;
347 }
348
349 sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::Accept_s, to,
350 accepted_sock),
351 NS_DISPATCH_SYNC);
352
353 if (r) {
354 std::cerr << "Accept_s failed: " << r << std::endl;
355 return false;
356 }
357 return true;
358 }
359
WaitForSocketState(NrSocketBase * sock,int state)360 bool WaitForSocketState(NrSocketBase* sock, int state) {
361 MOZ_ASSERT(sock);
362 sts_->Dispatch(WrapRunnable(this, &TestNrSocketTest::WaitForSocketState_s,
363 sock, state),
364 NS_DISPATCH_SYNC);
365
366 bool res;
367 WAIT_(wait_done_for_main_, 500, res);
368 wait_done_for_main_ = false;
369
370 if (!res) {
371 sts_->Dispatch(
372 WrapRunnable(this, &TestNrSocketTest::CancelWait_s, sock, state),
373 NS_DISPATCH_SYNC);
374 }
375
376 return res;
377 }
378
WaitForSocketState_s(NrSocketBase * sock,int state)379 void WaitForSocketState_s(NrSocketBase* sock, int state) {
380 NR_ASYNC_WAIT(sock, state, &WaitDone, this);
381 }
382
CancelWait_s(NrSocketBase * sock,int state)383 void CancelWait_s(NrSocketBase* sock, int state) { sock->cancel(state); }
384
WaitForReadable(NrSocketBase * sock)385 bool WaitForReadable(NrSocketBase* sock) {
386 return WaitForSocketState(sock, NR_ASYNC_WAIT_READ);
387 }
388
WaitForWriteable(NrSocketBase * sock)389 bool WaitForWriteable(NrSocketBase* sock) {
390 return WaitForSocketState(sock, NR_ASYNC_WAIT_WRITE);
391 }
392
WaitDone(void * sock,int how,void * test_fixture)393 static void WaitDone(void* sock, int how, void* test_fixture) {
394 TestNrSocketTest* test = static_cast<TestNrSocketTest*>(test_fixture);
395 test->wait_done_for_main_ = true;
396 }
397
398 // Simple busywait boolean for the test cases to spin on.
399 Atomic<bool> wait_done_for_main_;
400
401 nsCOMPtr<nsIEventTarget> sts_;
402 std::vector<RefPtr<TestNrSocket>> public_addrs_;
403 std::vector<RefPtr<TestNrSocket>> private_addrs_;
404 std::vector<RefPtr<TestNat>> nats_;
405 };
406
407 } // namespace mozilla
408
409 using mozilla::NrSocketBase;
410 using mozilla::TestNat;
411 using mozilla::TestNrSocketTest;
412
TEST_F(TestNrSocketTest,UnsafePortRejectedUDP)413 TEST_F(TestNrSocketTest, UnsafePortRejectedUDP) {
414 nr_transport_addr address;
415 ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
416 // ssh
417 22, IPPROTO_UDP, &address));
418 ASSERT_TRUE(NrSocketBase::IsForbiddenAddress(&address));
419 }
420
TEST_F(TestNrSocketTest,UnsafePortRejectedTCP)421 TEST_F(TestNrSocketTest, UnsafePortRejectedTCP) {
422 nr_transport_addr address;
423 ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
424 // ssh
425 22, IPPROTO_TCP, &address));
426 ASSERT_TRUE(NrSocketBase::IsForbiddenAddress(&address));
427 }
428
TEST_F(TestNrSocketTest,SafePortAcceptedUDP)429 TEST_F(TestNrSocketTest, SafePortAcceptedUDP) {
430 nr_transport_addr address;
431 ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
432 // stuns
433 5349, IPPROTO_UDP, &address));
434 ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
435 }
436
TEST_F(TestNrSocketTest,SafePortAcceptedTCP)437 TEST_F(TestNrSocketTest, SafePortAcceptedTCP) {
438 nr_transport_addr address;
439 ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
440 // turns
441 5349, IPPROTO_TCP, &address));
442 ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
443 }
444
TEST_F(TestNrSocketTest,PublicConnectivity)445 TEST_F(TestNrSocketTest, PublicConnectivity) {
446 CreatePublicAddrs(2);
447
448 ASSERT_TRUE(CheckConnectivity(public_addrs_[0], public_addrs_[1]));
449 ASSERT_TRUE(CheckConnectivity(public_addrs_[1], public_addrs_[0]));
450 ASSERT_TRUE(CheckConnectivity(public_addrs_[0], public_addrs_[0]));
451 ASSERT_TRUE(CheckConnectivity(public_addrs_[1], public_addrs_[1]));
452 }
453
TEST_F(TestNrSocketTest,PrivateConnectivity)454 TEST_F(TestNrSocketTest, PrivateConnectivity) {
455 RefPtr<TestNat> nat(CreatePrivateAddrs(2));
456 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
457 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
458
459 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
460 ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
461 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[0]));
462 ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[1]));
463 }
464
TEST_F(TestNrSocketTest,NoConnectivityWithoutPinhole)465 TEST_F(TestNrSocketTest, NoConnectivityWithoutPinhole) {
466 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
467 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
468 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
469 CreatePublicAddrs(1);
470
471 ASSERT_FALSE(CheckConnectivity(public_addrs_[0], private_addrs_[0]));
472 }
473
TEST_F(TestNrSocketTest,NoConnectivityBetweenSubnets)474 TEST_F(TestNrSocketTest, NoConnectivityBetweenSubnets) {
475 RefPtr<TestNat> nat1(CreatePrivateAddrs(1));
476 nat1->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
477 nat1->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
478 RefPtr<TestNat> nat2(CreatePrivateAddrs(1));
479 nat2->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
480 nat2->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
481
482 ASSERT_FALSE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
483 ASSERT_FALSE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
484 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[0]));
485 ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[1]));
486 }
487
TEST_F(TestNrSocketTest,FullConeAcceptIngress)488 TEST_F(TestNrSocketTest, FullConeAcceptIngress) {
489 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
490 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
491 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
492 CreatePublicAddrs(2);
493
494 nr_transport_addr sender_external_address;
495 // Open pinhole to public IP 0
496 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
497 &sender_external_address));
498
499 // Verify that return traffic works
500 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
501 sender_external_address));
502
503 // Verify that other public IP can use the pinhole
504 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
505 sender_external_address));
506 }
507
TEST_F(TestNrSocketTest,FullConeOnePinhole)508 TEST_F(TestNrSocketTest, FullConeOnePinhole) {
509 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
510 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
511 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
512 CreatePublicAddrs(2);
513
514 nr_transport_addr sender_external_address;
515 // Open pinhole to public IP 0
516 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
517 &sender_external_address));
518
519 // Verify that return traffic works
520 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
521 sender_external_address));
522
523 // Send traffic to other public IP, verify that it uses the same pinhole
524 nr_transport_addr sender_external_address2;
525 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
526 &sender_external_address2));
527 ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
528 &sender_external_address2,
529 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
530 << "addr1: " << sender_external_address.as_string
531 << " addr2: " << sender_external_address2.as_string;
532 }
533
534 // OS 10.6 doesn't seem to allow us to open ports on 127.0.0.2, and while linux
535 // does allow this, it has other behavior (see below) that prevents this test
536 // from working.
TEST_F(TestNrSocketTest,DISABLED_AddressRestrictedCone)537 TEST_F(TestNrSocketTest, DISABLED_AddressRestrictedCone) {
538 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
539 nat->filtering_type_ = TestNat::ADDRESS_DEPENDENT;
540 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
541 CreatePublicAddrs(2, "127.0.0.1");
542 CreatePublicAddrs(1, "127.0.0.2");
543
544 nr_transport_addr sender_external_address;
545 // Open pinhole to public IP 0
546 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
547 &sender_external_address));
548
549 // Verify that return traffic works
550 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
551 sender_external_address));
552
553 // Verify that another address on the same host can use the pinhole
554 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
555 sender_external_address));
556
557 // Linux has a tendency to monkey around with source addresses, doing
558 // stuff like substituting 127.0.0.1 for packets sent by 127.0.0.2, and even
559 // going as far as substituting localhost for a packet sent from a real IP
560 // address when the destination is localhost. The only way to make this test
561 // work on linux is to have two real IP addresses.
562 #ifndef __linux__
563 // Verify that an address on a different host can't use the pinhole
564 ASSERT_FALSE(CheckConnectivityVia(public_addrs_[2], private_addrs_[0],
565 sender_external_address));
566 #endif
567
568 // Send traffic to other public IP, verify that it uses the same pinhole
569 nr_transport_addr sender_external_address2;
570 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
571 &sender_external_address2));
572 ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
573 &sender_external_address2,
574 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
575 << "addr1: " << sender_external_address.as_string
576 << " addr2: " << sender_external_address2.as_string;
577
578 // Verify that the other public IP can now use the pinhole
579 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
580 sender_external_address2));
581
582 // Send traffic to other public IP, verify that it uses the same pinhole
583 nr_transport_addr sender_external_address3;
584 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[2],
585 &sender_external_address3));
586 ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
587 &sender_external_address3,
588 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
589 << "addr1: " << sender_external_address.as_string
590 << " addr2: " << sender_external_address3.as_string;
591
592 // Verify that the other public IP can now use the pinhole
593 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[2], private_addrs_[0],
594 sender_external_address3));
595 }
596
TEST_F(TestNrSocketTest,RestrictedCone)597 TEST_F(TestNrSocketTest, RestrictedCone) {
598 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
599 nat->filtering_type_ = TestNat::PORT_DEPENDENT;
600 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
601 CreatePublicAddrs(2);
602
603 nr_transport_addr sender_external_address;
604 // Open pinhole to public IP 0
605 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
606 &sender_external_address));
607
608 // Verify that return traffic works
609 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
610 sender_external_address));
611
612 // Verify that other public IP cannot use the pinhole
613 ASSERT_FALSE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
614 sender_external_address));
615
616 // Send traffic to other public IP, verify that it uses the same pinhole
617 nr_transport_addr sender_external_address2;
618 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
619 &sender_external_address2));
620 ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
621 &sender_external_address2,
622 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
623 << "addr1: " << sender_external_address.as_string
624 << " addr2: " << sender_external_address2.as_string;
625
626 // Verify that the other public IP can now use the pinhole
627 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
628 sender_external_address2));
629 }
630
TEST_F(TestNrSocketTest,PortDependentMappingFullCone)631 TEST_F(TestNrSocketTest, PortDependentMappingFullCone) {
632 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
633 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
634 nat->mapping_type_ = TestNat::PORT_DEPENDENT;
635 CreatePublicAddrs(2);
636
637 nr_transport_addr sender_external_address0;
638 // Open pinhole to public IP 0
639 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
640 &sender_external_address0));
641
642 // Verify that return traffic works
643 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
644 sender_external_address0));
645
646 // Verify that other public IP can use the pinhole
647 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
648 sender_external_address0));
649
650 // Send traffic to other public IP, verify that it uses a different pinhole
651 nr_transport_addr sender_external_address1;
652 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
653 &sender_external_address1));
654 ASSERT_TRUE(nr_transport_addr_cmp(&sender_external_address0,
655 &sender_external_address1,
656 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
657 << "addr1: " << sender_external_address0.as_string
658 << " addr2: " << sender_external_address1.as_string;
659
660 // Verify that return traffic works
661 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
662 sender_external_address1));
663
664 // Verify that other public IP can use the original pinhole
665 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
666 sender_external_address1));
667 }
668
TEST_F(TestNrSocketTest,Symmetric)669 TEST_F(TestNrSocketTest, Symmetric) {
670 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
671 nat->filtering_type_ = TestNat::PORT_DEPENDENT;
672 nat->mapping_type_ = TestNat::PORT_DEPENDENT;
673 CreatePublicAddrs(2);
674
675 nr_transport_addr sender_external_address;
676 // Open pinhole to public IP 0
677 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
678 &sender_external_address));
679
680 // Verify that return traffic works
681 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
682 sender_external_address));
683
684 // Verify that other public IP cannot use the pinhole
685 ASSERT_FALSE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
686 sender_external_address));
687
688 // Send traffic to other public IP, verify that it uses a new pinhole
689 nr_transport_addr sender_external_address2;
690 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
691 &sender_external_address2));
692 ASSERT_TRUE(nr_transport_addr_cmp(&sender_external_address,
693 &sender_external_address2,
694 NR_TRANSPORT_ADDR_CMP_MODE_ALL));
695
696 // Verify that the other public IP can use the new pinhole
697 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
698 sender_external_address2));
699 }
700
TEST_F(TestNrSocketTest,BlockUdp)701 TEST_F(TestNrSocketTest, BlockUdp) {
702 RefPtr<TestNat> nat(CreatePrivateAddrs(2));
703 nat->block_udp_ = true;
704 CreatePublicAddrs(1);
705
706 nr_transport_addr sender_external_address;
707 ASSERT_FALSE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
708 &sender_external_address));
709
710 // Make sure UDP behind the NAT still works
711 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
712 ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
713 }
714
TEST_F(TestNrSocketTest,DenyHairpinning)715 TEST_F(TestNrSocketTest, DenyHairpinning) {
716 RefPtr<TestNat> nat(CreatePrivateAddrs(2));
717 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
718 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
719 CreatePublicAddrs(1);
720
721 nr_transport_addr sender_external_address;
722 // Open pinhole to public IP 0
723 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
724 &sender_external_address));
725
726 // Verify that hairpinning is disallowed
727 ASSERT_FALSE(CheckConnectivityVia(private_addrs_[1], private_addrs_[0],
728 sender_external_address));
729 }
730
TEST_F(TestNrSocketTest,AllowHairpinning)731 TEST_F(TestNrSocketTest, AllowHairpinning) {
732 RefPtr<TestNat> nat(CreatePrivateAddrs(2));
733 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
734 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
735 nat->mapping_timeout_ = 30000;
736 nat->allow_hairpinning_ = true;
737 CreatePublicAddrs(1);
738
739 nr_transport_addr sender_external_address;
740 // Open pinhole to public IP 0, obtain external address
741 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
742 &sender_external_address));
743
744 // Verify that hairpinning is allowed
745 ASSERT_TRUE(CheckConnectivityVia(private_addrs_[1], private_addrs_[0],
746 sender_external_address));
747 }
748
TEST_F(TestNrSocketTest,FullConeTimeout)749 TEST_F(TestNrSocketTest, FullConeTimeout) {
750 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
751 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
752 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
753 nat->mapping_timeout_ = 200;
754 CreatePublicAddrs(2);
755
756 nr_transport_addr sender_external_address;
757 // Open pinhole to public IP 0
758 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
759 &sender_external_address));
760
761 // Verify that return traffic works
762 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
763 sender_external_address));
764
765 PR_Sleep(201);
766
767 // Verify that return traffic does not work
768 ASSERT_FALSE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
769 sender_external_address));
770 }
771
TEST_F(TestNrSocketTest,PublicConnectivityTcp)772 TEST_F(TestNrSocketTest, PublicConnectivityTcp) {
773 CreatePublicAddrs(2, "127.0.0.1", IPPROTO_TCP);
774
775 ASSERT_TRUE(CheckTcpConnectivity(public_addrs_[0], public_addrs_[1]));
776 }
777
TEST_F(TestNrSocketTest,PrivateConnectivityTcp)778 TEST_F(TestNrSocketTest, PrivateConnectivityTcp) {
779 RefPtr<TestNat> nat(CreatePrivateAddrs(2, "127.0.0.1", IPPROTO_TCP));
780 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
781 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
782
783 ASSERT_TRUE(CheckTcpConnectivity(private_addrs_[0], private_addrs_[1]));
784 }
785
TEST_F(TestNrSocketTest,PrivateToPublicConnectivityTcp)786 TEST_F(TestNrSocketTest, PrivateToPublicConnectivityTcp) {
787 RefPtr<TestNat> nat(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
788 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
789 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
790 CreatePublicAddrs(1, "127.0.0.1", IPPROTO_TCP);
791
792 ASSERT_TRUE(CheckTcpConnectivity(private_addrs_[0], public_addrs_[0]));
793 }
794
TEST_F(TestNrSocketTest,NoConnectivityBetweenSubnetsTcp)795 TEST_F(TestNrSocketTest, NoConnectivityBetweenSubnetsTcp) {
796 RefPtr<TestNat> nat1(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
797 nat1->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
798 nat1->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
799 RefPtr<TestNat> nat2(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
800 nat2->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
801 nat2->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
802
803 ASSERT_FALSE(CheckTcpConnectivity(private_addrs_[0], private_addrs_[1]));
804 }
805
TEST_F(TestNrSocketTest,NoConnectivityPublicToPrivateTcp)806 TEST_F(TestNrSocketTest, NoConnectivityPublicToPrivateTcp) {
807 RefPtr<TestNat> nat(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
808 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
809 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
810 CreatePublicAddrs(1, "127.0.0.1", IPPROTO_TCP);
811
812 ASSERT_FALSE(CheckTcpConnectivity(public_addrs_[0], private_addrs_[0]));
813 }
814