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