tor-browser

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

buffered_stun_socket_unittest.cpp (7228B)


      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: ekr@rtfm.com
      8 
      9 extern "C" {
     10 #include "nr_api.h"
     11 #include "nr_socket.h"
     12 #include "nr_socket_buffered_stun.h"
     13 #include "transport_addr.h"
     14 }
     15 
     16 #include "dummysocket.h"
     17 #include "nr_socket_prsock.h"
     18 #include "stun_msg.h"
     19 
     20 #define GTEST_HAS_RTTI 0
     21 #include "gtest/gtest.h"
     22 #include "gtest_utils.h"
     23 
     24 using namespace mozilla;
     25 
     26 static uint8_t kStunMessage[] = {0x00, 0x01, 0x00, 0x08, 0x21, 0x12, 0xa4,
     27                                 0x42, 0x9b, 0x90, 0xbe, 0x2c, 0xae, 0x1a,
     28                                 0x0c, 0xa8, 0xa0, 0xd6, 0x8b, 0x08, 0x80,
     29                                 0x28, 0x00, 0x04, 0xdb, 0x35, 0x5f, 0xaa};
     30 static size_t kStunMessageLen = sizeof(kStunMessage);
     31 
     32 class BufferedStunSocketTest : public MtransportTest {
     33 public:
     34  BufferedStunSocketTest() : dummy_(nullptr), test_socket_(nullptr) {}
     35 
     36  ~BufferedStunSocketTest() { nr_socket_destroy(&test_socket_); }
     37 
     38  void SetUp() override {
     39    MtransportTest::SetUp();
     40 
     41    RefPtr<DummySocket> dummy(new DummySocket());
     42 
     43    int r =
     44        nr_socket_buffered_stun_create(dummy->get_nr_socket(), kStunMessageLen,
     45                                       TURN_TCP_FRAMING, &test_socket_);
     46    ASSERT_EQ(0, r);
     47    dummy_ = std::move(dummy);  // Now owned by test_socket_.
     48 
     49    r = nr_str_port_to_transport_addr((char*)"192.0.2.133", 3333, IPPROTO_TCP,
     50                                      &remote_addr_);
     51    ASSERT_EQ(0, r);
     52 
     53    r = nr_socket_connect(test_socket_, &remote_addr_);
     54    ASSERT_EQ(0, r);
     55  }
     56 
     57  nr_socket* socket() { return test_socket_; }
     58 
     59 protected:
     60  RefPtr<DummySocket> dummy_;
     61  nr_socket* test_socket_;
     62  nr_transport_addr remote_addr_;
     63 };
     64 
     65 TEST_F(BufferedStunSocketTest, TestCreate) {}
     66 
     67 TEST_F(BufferedStunSocketTest, TestSendTo) {
     68  int r = nr_socket_sendto(test_socket_, kStunMessage, kStunMessageLen, 0,
     69                           &remote_addr_);
     70  ASSERT_EQ(0, r);
     71 
     72  dummy_->CheckWriteBuffer(kStunMessage, kStunMessageLen);
     73 }
     74 
     75 TEST_F(BufferedStunSocketTest, TestSendToBuffered) {
     76  dummy_->SetWritable(0);
     77 
     78  int r = nr_socket_sendto(test_socket_, kStunMessage, kStunMessageLen, 0,
     79                           &remote_addr_);
     80  ASSERT_EQ(0, r);
     81 
     82  dummy_->CheckWriteBuffer(nullptr, 0);
     83 
     84  dummy_->SetWritable(kStunMessageLen);
     85  dummy_->FireWritableCb();
     86  dummy_->CheckWriteBuffer(kStunMessage, kStunMessageLen);
     87 }
     88 
     89 TEST_F(BufferedStunSocketTest, TestSendFullThenDrain) {
     90  dummy_->SetWritable(0);
     91 
     92  for (;;) {
     93    int r = nr_socket_sendto(test_socket_, kStunMessage, kStunMessageLen, 0,
     94                             &remote_addr_);
     95    if (r == R_WOULDBLOCK) break;
     96 
     97    ASSERT_EQ(0, r);
     98  }
     99 
    100  // Nothing was written.
    101  dummy_->CheckWriteBuffer(nullptr, 0);
    102 
    103  // Now flush.
    104  dummy_->SetWritable(kStunMessageLen);
    105  dummy_->FireWritableCb();
    106  dummy_->ClearWriteBuffer();
    107 
    108  // Verify we can write something.
    109  int r = nr_socket_sendto(test_socket_, kStunMessage, kStunMessageLen, 0,
    110                           &remote_addr_);
    111  ASSERT_EQ(0, r);
    112 
    113  // And that it appears.
    114  dummy_->CheckWriteBuffer(kStunMessage, kStunMessageLen);
    115 }
    116 
    117 TEST_F(BufferedStunSocketTest, TestSendToPartialBuffered) {
    118  dummy_->SetWritable(10);
    119 
    120  int r = nr_socket_sendto(test_socket_, kStunMessage, kStunMessageLen, 0,
    121                           &remote_addr_);
    122  ASSERT_EQ(0, r);
    123 
    124  dummy_->CheckWriteBuffer(kStunMessage, 10);
    125  dummy_->ClearWriteBuffer();
    126 
    127  dummy_->SetWritable(kStunMessageLen);
    128  dummy_->FireWritableCb();
    129  dummy_->CheckWriteBuffer(kStunMessage + 10, kStunMessageLen - 10);
    130 }
    131 
    132 TEST_F(BufferedStunSocketTest, TestSendToReject) {
    133  dummy_->SetWritable(0);
    134 
    135  int r = nr_socket_sendto(test_socket_, kStunMessage, kStunMessageLen, 0,
    136                           &remote_addr_);
    137  ASSERT_EQ(0, r);
    138 
    139  dummy_->CheckWriteBuffer(nullptr, 0);
    140 
    141  r = nr_socket_sendto(test_socket_, kStunMessage, kStunMessageLen, 0,
    142                       &remote_addr_);
    143  ASSERT_EQ(R_WOULDBLOCK, r);
    144 
    145  dummy_->CheckWriteBuffer(nullptr, 0);
    146 }
    147 
    148 TEST_F(BufferedStunSocketTest, TestSendToWrongAddr) {
    149  nr_transport_addr addr;
    150 
    151  int r = nr_str_port_to_transport_addr((char*)"192.0.2.134", 3333, IPPROTO_TCP,
    152                                        &addr);
    153  ASSERT_EQ(0, r);
    154 
    155  r = nr_socket_sendto(test_socket_, kStunMessage, kStunMessageLen, 0, &addr);
    156  ASSERT_EQ(R_BAD_DATA, r);
    157 }
    158 
    159 TEST_F(BufferedStunSocketTest, TestReceiveRecvFrom) {
    160  dummy_->SetReadBuffer(kStunMessage, kStunMessageLen);
    161 
    162  unsigned char tmp[2048];
    163  size_t len;
    164  nr_transport_addr addr;
    165 
    166  int r = nr_socket_recvfrom(test_socket_, tmp, sizeof(tmp), &len, 0, &addr);
    167  ASSERT_EQ(0, r);
    168  ASSERT_EQ(kStunMessageLen, len);
    169  ASSERT_EQ(0, memcmp(kStunMessage, tmp, kStunMessageLen));
    170  ASSERT_EQ(0, nr_transport_addr_cmp(&addr, &remote_addr_,
    171                                     NR_TRANSPORT_ADDR_CMP_MODE_ALL));
    172 }
    173 
    174 TEST_F(BufferedStunSocketTest, TestReceiveRecvFromPartial) {
    175  dummy_->SetReadBuffer(kStunMessage, 15);
    176 
    177  unsigned char tmp[2048];
    178  size_t len;
    179  nr_transport_addr addr;
    180 
    181  int r = nr_socket_recvfrom(test_socket_, tmp, sizeof(tmp), &len, 0, &addr);
    182  ASSERT_EQ(R_WOULDBLOCK, r);
    183 
    184  dummy_->SetReadBuffer(kStunMessage + 15, kStunMessageLen - 15);
    185 
    186  r = nr_socket_recvfrom(test_socket_, tmp, sizeof(tmp), &len, 0, &addr);
    187  ASSERT_EQ(0, r);
    188  ASSERT_EQ(kStunMessageLen, len);
    189  ASSERT_EQ(0, memcmp(kStunMessage, tmp, kStunMessageLen));
    190  ASSERT_EQ(0, nr_transport_addr_cmp(&addr, &remote_addr_,
    191                                     NR_TRANSPORT_ADDR_CMP_MODE_ALL));
    192 
    193  r = nr_socket_recvfrom(test_socket_, tmp, sizeof(tmp), &len, 0, &addr);
    194  ASSERT_EQ(R_WOULDBLOCK, r);
    195 }
    196 
    197 TEST_F(BufferedStunSocketTest, TestReceiveRecvFromGarbage) {
    198  uint8_t garbage[50];
    199  memset(garbage, 0xff, sizeof(garbage));
    200 
    201  dummy_->SetReadBuffer(garbage, sizeof(garbage));
    202 
    203  unsigned char tmp[2048];
    204  size_t len;
    205  nr_transport_addr addr;
    206  int r = nr_socket_recvfrom(test_socket_, tmp, sizeof(tmp), &len, 0, &addr);
    207  ASSERT_EQ(R_BAD_DATA, r);
    208 
    209  r = nr_socket_recvfrom(test_socket_, tmp, sizeof(tmp), &len, 0, &addr);
    210  ASSERT_EQ(R_FAILED, r);
    211 }
    212 
    213 TEST_F(BufferedStunSocketTest, TestReceiveRecvFromTooShort) {
    214  dummy_->SetReadBuffer(kStunMessage, kStunMessageLen);
    215 
    216  unsigned char tmp[2048];
    217  size_t len;
    218  nr_transport_addr addr;
    219 
    220  int r = nr_socket_recvfrom(test_socket_, tmp, kStunMessageLen - 1, &len, 0,
    221                             &addr);
    222  ASSERT_EQ(R_BAD_ARGS, r);
    223 }
    224 
    225 TEST_F(BufferedStunSocketTest, TestReceiveRecvFromReallyLong) {
    226  uint8_t garbage[4096];
    227  memset(garbage, 0xff, sizeof(garbage));
    228  memcpy(garbage, kStunMessage, kStunMessageLen);
    229  nr_stun_message_header* hdr =
    230      reinterpret_cast<nr_stun_message_header*>(garbage);
    231  hdr->length = htons(3000);
    232 
    233  dummy_->SetReadBuffer(garbage, sizeof(garbage));
    234 
    235  unsigned char tmp[4096];
    236  size_t len;
    237  nr_transport_addr addr;
    238 
    239  int r = nr_socket_recvfrom(test_socket_, tmp, kStunMessageLen - 1, &len, 0,
    240                             &addr);
    241  ASSERT_EQ(R_BAD_DATA, r);
    242 }