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(
256 buf, sizeof(buf), 0,
257 // TODO(bug 1170299): Remove const_cast when no longer necessary
258 const_cast<nr_transport_addr*>(&to));
259 }
260
SendDataTcp_s(NrSocketBase * from)261 int SendDataTcp_s(NrSocketBase* from) {
262 // It is up to caller to ensure that |from| is writeable.
263 const char buf[] = "foobajooba";
264 size_t written;
265 return from->write(buf, sizeof(buf), &written);
266 }
267
RecvData_s(TestNrSocket * to,nr_transport_addr * from)268 int RecvData_s(TestNrSocket* to, nr_transport_addr* from) {
269 // It is up to caller to ensure that |to| is readable
270 char buf[DATA_BUF_SIZE];
271 size_t len;
272 // Maybe check that data matches?
273 int r = to->recvfrom(buf, sizeof(buf), &len, 0, from);
274 if (!r && (len == 0)) {
275 r = R_INTERNAL;
276 }
277 return r;
278 }
279
RecvDataTcp_s(NrSocketBase * to)280 int RecvDataTcp_s(NrSocketBase* to) {
281 // It is up to caller to ensure that |to| is readable
282 char buf[DATA_BUF_SIZE];
283 size_t len;
284 // Maybe check that data matches?
285 int r = to->read(buf, sizeof(buf), &len);
286 if (!r && (len == 0)) {
287 r = R_INTERNAL;
288 }
289 return r;
290 }
291
Listen_s(TestNrSocket * to)292 int Listen_s(TestNrSocket* to) {
293 // listen on |to|
294 int r = to->listen(1);
295 if (r) {
296 return r;
297 }
298 return 0;
299 }
300
Connect_s(TestNrSocket * from,TestNrSocket * to)301 int Connect_s(TestNrSocket* from, TestNrSocket* to) {
302 // connect on |from|
303 nr_transport_addr destination_address;
304 int r = to->getaddr(&destination_address);
305 if (r) {
306 return r;
307 }
308
309 r = from->connect(&destination_address);
310 if (r) {
311 return r;
312 }
313
314 return 0;
315 }
316
Accept_s(TestNrSocket * to,NrSocketBase ** accepted_sock)317 int Accept_s(TestNrSocket* to, NrSocketBase** accepted_sock) {
318 nr_socket* sock;
319 nr_transport_addr source_address;
320 int r = to->accept(&source_address, &sock);
321 if (r) {
322 return r;
323 }
324
325 *accepted_sock = reinterpret_cast<NrSocketBase*>(sock->obj);
326 return 0;
327 }
328
Connect(TestNrSocket * from,TestNrSocket * to,NrSocketBase ** accepted_sock)329 bool Connect(TestNrSocket* from, TestNrSocket* to,
330 NrSocketBase** accepted_sock) {
331 int r;
332 sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::Listen_s, to),
333 NS_DISPATCH_SYNC);
334 if (r) {
335 std::cerr << "Listen_s failed: " << r << std::endl;
336 return false;
337 }
338
339 sts_->Dispatch(
340 WrapRunnableRet(&r, this, &TestNrSocketTest::Connect_s, from, to),
341 NS_DISPATCH_SYNC);
342 if (r && r != R_WOULDBLOCK) {
343 std::cerr << "Connect_s failed: " << r << std::endl;
344 return false;
345 }
346
347 if (!WaitForReadable(to)) {
348 std::cerr << "WaitForReadable failed" << std::endl;
349 return false;
350 }
351
352 sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::Accept_s, to,
353 accepted_sock),
354 NS_DISPATCH_SYNC);
355
356 if (r) {
357 std::cerr << "Accept_s failed: " << r << std::endl;
358 return false;
359 }
360 return true;
361 }
362
WaitForSocketState(NrSocketBase * sock,int state)363 bool WaitForSocketState(NrSocketBase* sock, int state) {
364 MOZ_ASSERT(sock);
365 sts_->Dispatch(WrapRunnable(this, &TestNrSocketTest::WaitForSocketState_s,
366 sock, state),
367 NS_DISPATCH_SYNC);
368
369 bool res;
370 WAIT_(wait_done_for_main_, 500, res);
371 wait_done_for_main_ = false;
372
373 if (!res) {
374 sts_->Dispatch(
375 WrapRunnable(this, &TestNrSocketTest::CancelWait_s, sock, state),
376 NS_DISPATCH_SYNC);
377 }
378
379 return res;
380 }
381
WaitForSocketState_s(NrSocketBase * sock,int state)382 void WaitForSocketState_s(NrSocketBase* sock, int state) {
383 NR_ASYNC_WAIT(sock, state, &WaitDone, this);
384 }
385
CancelWait_s(NrSocketBase * sock,int state)386 void CancelWait_s(NrSocketBase* sock, int state) { sock->cancel(state); }
387
WaitForReadable(NrSocketBase * sock)388 bool WaitForReadable(NrSocketBase* sock) {
389 return WaitForSocketState(sock, NR_ASYNC_WAIT_READ);
390 }
391
WaitForWriteable(NrSocketBase * sock)392 bool WaitForWriteable(NrSocketBase* sock) {
393 return WaitForSocketState(sock, NR_ASYNC_WAIT_WRITE);
394 }
395
WaitDone(void * sock,int how,void * test_fixture)396 static void WaitDone(void* sock, int how, void* test_fixture) {
397 TestNrSocketTest* test = static_cast<TestNrSocketTest*>(test_fixture);
398 test->wait_done_for_main_ = true;
399 }
400
401 // Simple busywait boolean for the test cases to spin on.
402 Atomic<bool> wait_done_for_main_;
403
404 nsCOMPtr<nsIEventTarget> sts_;
405 std::vector<RefPtr<TestNrSocket>> public_addrs_;
406 std::vector<RefPtr<TestNrSocket>> private_addrs_;
407 std::vector<RefPtr<TestNat>> nats_;
408 };
409
410 } // namespace mozilla
411
412 using mozilla::NrSocketBase;
413 using mozilla::TestNat;
414 using mozilla::TestNrSocketTest;
415
TEST_F(TestNrSocketTest,UnsafePortRejectedUDP)416 TEST_F(TestNrSocketTest, UnsafePortRejectedUDP) {
417 nr_transport_addr address;
418 ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
419 // ssh
420 22, IPPROTO_UDP, &address));
421 ASSERT_TRUE(NrSocketBase::IsForbiddenAddress(&address));
422 }
423
TEST_F(TestNrSocketTest,UnsafePortRejectedTCP)424 TEST_F(TestNrSocketTest, UnsafePortRejectedTCP) {
425 nr_transport_addr address;
426 ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
427 // ssh
428 22, IPPROTO_TCP, &address));
429 ASSERT_TRUE(NrSocketBase::IsForbiddenAddress(&address));
430 }
431
TEST_F(TestNrSocketTest,SafePortAcceptedUDP)432 TEST_F(TestNrSocketTest, SafePortAcceptedUDP) {
433 nr_transport_addr address;
434 ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
435 // stuns
436 5349, IPPROTO_UDP, &address));
437 ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
438 }
439
TEST_F(TestNrSocketTest,SafePortAcceptedTCP)440 TEST_F(TestNrSocketTest, SafePortAcceptedTCP) {
441 nr_transport_addr address;
442 ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
443 // turns
444 5349, IPPROTO_TCP, &address));
445 ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
446 }
447
TEST_F(TestNrSocketTest,PublicConnectivity)448 TEST_F(TestNrSocketTest, PublicConnectivity) {
449 CreatePublicAddrs(2);
450
451 ASSERT_TRUE(CheckConnectivity(public_addrs_[0], public_addrs_[1]));
452 ASSERT_TRUE(CheckConnectivity(public_addrs_[1], public_addrs_[0]));
453 ASSERT_TRUE(CheckConnectivity(public_addrs_[0], public_addrs_[0]));
454 ASSERT_TRUE(CheckConnectivity(public_addrs_[1], public_addrs_[1]));
455 }
456
TEST_F(TestNrSocketTest,PrivateConnectivity)457 TEST_F(TestNrSocketTest, PrivateConnectivity) {
458 RefPtr<TestNat> nat(CreatePrivateAddrs(2));
459 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
460 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
461
462 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
463 ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
464 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[0]));
465 ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[1]));
466 }
467
TEST_F(TestNrSocketTest,NoConnectivityWithoutPinhole)468 TEST_F(TestNrSocketTest, NoConnectivityWithoutPinhole) {
469 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
470 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
471 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
472 CreatePublicAddrs(1);
473
474 ASSERT_FALSE(CheckConnectivity(public_addrs_[0], private_addrs_[0]));
475 }
476
TEST_F(TestNrSocketTest,NoConnectivityBetweenSubnets)477 TEST_F(TestNrSocketTest, NoConnectivityBetweenSubnets) {
478 RefPtr<TestNat> nat1(CreatePrivateAddrs(1));
479 nat1->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
480 nat1->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
481 RefPtr<TestNat> nat2(CreatePrivateAddrs(1));
482 nat2->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
483 nat2->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
484
485 ASSERT_FALSE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
486 ASSERT_FALSE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
487 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[0]));
488 ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[1]));
489 }
490
TEST_F(TestNrSocketTest,FullConeAcceptIngress)491 TEST_F(TestNrSocketTest, FullConeAcceptIngress) {
492 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
493 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
494 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
495 CreatePublicAddrs(2);
496
497 nr_transport_addr sender_external_address;
498 // Open pinhole to public IP 0
499 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
500 &sender_external_address));
501
502 // Verify that return traffic works
503 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
504 sender_external_address));
505
506 // Verify that other public IP can use the pinhole
507 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
508 sender_external_address));
509 }
510
TEST_F(TestNrSocketTest,FullConeOnePinhole)511 TEST_F(TestNrSocketTest, FullConeOnePinhole) {
512 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
513 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
514 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
515 CreatePublicAddrs(2);
516
517 nr_transport_addr sender_external_address;
518 // Open pinhole to public IP 0
519 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
520 &sender_external_address));
521
522 // Verify that return traffic works
523 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
524 sender_external_address));
525
526 // Send traffic to other public IP, verify that it uses the same pinhole
527 nr_transport_addr sender_external_address2;
528 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
529 &sender_external_address2));
530 ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
531 &sender_external_address2,
532 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
533 << "addr1: " << sender_external_address.as_string
534 << " addr2: " << sender_external_address2.as_string;
535 }
536
537 // OS 10.6 doesn't seem to allow us to open ports on 127.0.0.2, and while linux
538 // does allow this, it has other behavior (see below) that prevents this test
539 // from working.
TEST_F(TestNrSocketTest,DISABLED_AddressRestrictedCone)540 TEST_F(TestNrSocketTest, DISABLED_AddressRestrictedCone) {
541 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
542 nat->filtering_type_ = TestNat::ADDRESS_DEPENDENT;
543 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
544 CreatePublicAddrs(2, "127.0.0.1");
545 CreatePublicAddrs(1, "127.0.0.2");
546
547 nr_transport_addr sender_external_address;
548 // Open pinhole to public IP 0
549 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
550 &sender_external_address));
551
552 // Verify that return traffic works
553 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
554 sender_external_address));
555
556 // Verify that another address on the same host can use the pinhole
557 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
558 sender_external_address));
559
560 // Linux has a tendency to monkey around with source addresses, doing
561 // stuff like substituting 127.0.0.1 for packets sent by 127.0.0.2, and even
562 // going as far as substituting localhost for a packet sent from a real IP
563 // address when the destination is localhost. The only way to make this test
564 // work on linux is to have two real IP addresses.
565 #ifndef __linux__
566 // Verify that an address on a different host can't use the pinhole
567 ASSERT_FALSE(CheckConnectivityVia(public_addrs_[2], private_addrs_[0],
568 sender_external_address));
569 #endif
570
571 // Send traffic to other public IP, verify that it uses the same pinhole
572 nr_transport_addr sender_external_address2;
573 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
574 &sender_external_address2));
575 ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
576 &sender_external_address2,
577 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
578 << "addr1: " << sender_external_address.as_string
579 << " addr2: " << sender_external_address2.as_string;
580
581 // Verify that the other public IP can now use the pinhole
582 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
583 sender_external_address2));
584
585 // Send traffic to other public IP, verify that it uses the same pinhole
586 nr_transport_addr sender_external_address3;
587 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[2],
588 &sender_external_address3));
589 ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
590 &sender_external_address3,
591 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
592 << "addr1: " << sender_external_address.as_string
593 << " addr2: " << sender_external_address3.as_string;
594
595 // Verify that the other public IP can now use the pinhole
596 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[2], private_addrs_[0],
597 sender_external_address3));
598 }
599
TEST_F(TestNrSocketTest,RestrictedCone)600 TEST_F(TestNrSocketTest, RestrictedCone) {
601 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
602 nat->filtering_type_ = TestNat::PORT_DEPENDENT;
603 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
604 CreatePublicAddrs(2);
605
606 nr_transport_addr sender_external_address;
607 // Open pinhole to public IP 0
608 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
609 &sender_external_address));
610
611 // Verify that return traffic works
612 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
613 sender_external_address));
614
615 // Verify that other public IP cannot use the pinhole
616 ASSERT_FALSE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
617 sender_external_address));
618
619 // Send traffic to other public IP, verify that it uses the same pinhole
620 nr_transport_addr sender_external_address2;
621 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
622 &sender_external_address2));
623 ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
624 &sender_external_address2,
625 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
626 << "addr1: " << sender_external_address.as_string
627 << " addr2: " << sender_external_address2.as_string;
628
629 // Verify that the other public IP can now use the pinhole
630 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
631 sender_external_address2));
632 }
633
TEST_F(TestNrSocketTest,PortDependentMappingFullCone)634 TEST_F(TestNrSocketTest, PortDependentMappingFullCone) {
635 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
636 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
637 nat->mapping_type_ = TestNat::PORT_DEPENDENT;
638 CreatePublicAddrs(2);
639
640 nr_transport_addr sender_external_address0;
641 // Open pinhole to public IP 0
642 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
643 &sender_external_address0));
644
645 // Verify that return traffic works
646 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
647 sender_external_address0));
648
649 // Verify that other public IP can use the pinhole
650 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
651 sender_external_address0));
652
653 // Send traffic to other public IP, verify that it uses a different pinhole
654 nr_transport_addr sender_external_address1;
655 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
656 &sender_external_address1));
657 ASSERT_TRUE(nr_transport_addr_cmp(&sender_external_address0,
658 &sender_external_address1,
659 NR_TRANSPORT_ADDR_CMP_MODE_ALL))
660 << "addr1: " << sender_external_address0.as_string
661 << " addr2: " << sender_external_address1.as_string;
662
663 // Verify that return traffic works
664 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
665 sender_external_address1));
666
667 // Verify that other public IP can use the original pinhole
668 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
669 sender_external_address1));
670 }
671
TEST_F(TestNrSocketTest,Symmetric)672 TEST_F(TestNrSocketTest, Symmetric) {
673 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
674 nat->filtering_type_ = TestNat::PORT_DEPENDENT;
675 nat->mapping_type_ = TestNat::PORT_DEPENDENT;
676 CreatePublicAddrs(2);
677
678 nr_transport_addr sender_external_address;
679 // Open pinhole to public IP 0
680 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
681 &sender_external_address));
682
683 // Verify that return traffic works
684 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
685 sender_external_address));
686
687 // Verify that other public IP cannot use the pinhole
688 ASSERT_FALSE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
689 sender_external_address));
690
691 // Send traffic to other public IP, verify that it uses a new pinhole
692 nr_transport_addr sender_external_address2;
693 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
694 &sender_external_address2));
695 ASSERT_TRUE(nr_transport_addr_cmp(&sender_external_address,
696 &sender_external_address2,
697 NR_TRANSPORT_ADDR_CMP_MODE_ALL));
698
699 // Verify that the other public IP can use the new pinhole
700 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
701 sender_external_address2));
702 }
703
TEST_F(TestNrSocketTest,BlockUdp)704 TEST_F(TestNrSocketTest, BlockUdp) {
705 RefPtr<TestNat> nat(CreatePrivateAddrs(2));
706 nat->block_udp_ = true;
707 CreatePublicAddrs(1);
708
709 nr_transport_addr sender_external_address;
710 ASSERT_FALSE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
711 &sender_external_address));
712
713 // Make sure UDP behind the NAT still works
714 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
715 ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
716 }
717
TEST_F(TestNrSocketTest,DenyHairpinning)718 TEST_F(TestNrSocketTest, DenyHairpinning) {
719 RefPtr<TestNat> nat(CreatePrivateAddrs(2));
720 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
721 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
722 CreatePublicAddrs(1);
723
724 nr_transport_addr sender_external_address;
725 // Open pinhole to public IP 0
726 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
727 &sender_external_address));
728
729 // Verify that hairpinning is disallowed
730 ASSERT_FALSE(CheckConnectivityVia(private_addrs_[1], private_addrs_[0],
731 sender_external_address));
732 }
733
TEST_F(TestNrSocketTest,AllowHairpinning)734 TEST_F(TestNrSocketTest, AllowHairpinning) {
735 RefPtr<TestNat> nat(CreatePrivateAddrs(2));
736 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
737 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
738 nat->mapping_timeout_ = 30000;
739 nat->allow_hairpinning_ = true;
740 CreatePublicAddrs(1);
741
742 nr_transport_addr sender_external_address;
743 // Open pinhole to public IP 0, obtain external address
744 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
745 &sender_external_address));
746
747 // Verify that hairpinning is allowed
748 ASSERT_TRUE(CheckConnectivityVia(private_addrs_[1], private_addrs_[0],
749 sender_external_address));
750 }
751
TEST_F(TestNrSocketTest,FullConeTimeout)752 TEST_F(TestNrSocketTest, FullConeTimeout) {
753 RefPtr<TestNat> nat(CreatePrivateAddrs(1));
754 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
755 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
756 nat->mapping_timeout_ = 200;
757 CreatePublicAddrs(2);
758
759 nr_transport_addr sender_external_address;
760 // Open pinhole to public IP 0
761 ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
762 &sender_external_address));
763
764 // Verify that return traffic works
765 ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
766 sender_external_address));
767
768 PR_Sleep(201);
769
770 // Verify that return traffic does not work
771 ASSERT_FALSE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
772 sender_external_address));
773 }
774
TEST_F(TestNrSocketTest,PublicConnectivityTcp)775 TEST_F(TestNrSocketTest, PublicConnectivityTcp) {
776 CreatePublicAddrs(2, "127.0.0.1", IPPROTO_TCP);
777
778 ASSERT_TRUE(CheckTcpConnectivity(public_addrs_[0], public_addrs_[1]));
779 }
780
TEST_F(TestNrSocketTest,PrivateConnectivityTcp)781 TEST_F(TestNrSocketTest, PrivateConnectivityTcp) {
782 RefPtr<TestNat> nat(CreatePrivateAddrs(2, "127.0.0.1", IPPROTO_TCP));
783 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
784 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
785
786 ASSERT_TRUE(CheckTcpConnectivity(private_addrs_[0], private_addrs_[1]));
787 }
788
TEST_F(TestNrSocketTest,PrivateToPublicConnectivityTcp)789 TEST_F(TestNrSocketTest, PrivateToPublicConnectivityTcp) {
790 RefPtr<TestNat> nat(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
791 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
792 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
793 CreatePublicAddrs(1, "127.0.0.1", IPPROTO_TCP);
794
795 ASSERT_TRUE(CheckTcpConnectivity(private_addrs_[0], public_addrs_[0]));
796 }
797
TEST_F(TestNrSocketTest,NoConnectivityBetweenSubnetsTcp)798 TEST_F(TestNrSocketTest, NoConnectivityBetweenSubnetsTcp) {
799 RefPtr<TestNat> nat1(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
800 nat1->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
801 nat1->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
802 RefPtr<TestNat> nat2(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
803 nat2->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
804 nat2->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
805
806 ASSERT_FALSE(CheckTcpConnectivity(private_addrs_[0], private_addrs_[1]));
807 }
808
TEST_F(TestNrSocketTest,NoConnectivityPublicToPrivateTcp)809 TEST_F(TestNrSocketTest, NoConnectivityPublicToPrivateTcp) {
810 RefPtr<TestNat> nat(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
811 nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
812 nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
813 CreatePublicAddrs(1, "127.0.0.1", IPPROTO_TCP);
814
815 ASSERT_FALSE(CheckTcpConnectivity(public_addrs_[0], private_addrs_[0]));
816 }
817