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