tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }