Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2013 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/p2p/base/asyncstuntcpsocket.h"
     12 #include "webrtc/base/asyncsocket.h"
     13 #include "webrtc/base/gunit.h"
     14 #include "webrtc/base/physicalsocketserver.h"
     15 #include "webrtc/base/virtualsocketserver.h"
     16 
     17 namespace cricket {
     18 
     19 static unsigned char kStunMessageWithZeroLength[] = {
     20   0x00, 0x01, 0x00, 0x00,  // length of 0 (last 2 bytes)
     21   0x21, 0x12, 0xA4, 0x42,
     22   '0', '1', '2', '3',
     23   '4', '5', '6', '7',
     24   '8', '9', 'a', 'b',
     25 };
     26 
     27 
     28 static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
     29   0x40, 0x00, 0x00, 0x00,  // length of 0 (last 2 bytes)
     30 };
     31 
     32 static unsigned char kTurnChannelDataMessage[] = {
     33   0x40, 0x00, 0x00, 0x10,
     34   0x21, 0x12, 0xA4, 0x42,
     35   '0', '1', '2', '3',
     36   '4', '5', '6', '7',
     37   '8', '9', 'a', 'b',
     38 };
     39 
     40 static unsigned char kStunMessageWithInvalidLength[] = {
     41   0x00, 0x01, 0x00, 0x10,
     42   0x21, 0x12, 0xA4, 0x42,
     43   '0', '1', '2', '3',
     44   '4', '5', '6', '7',
     45   '8', '9', 'a', 'b',
     46 };
     47 
     48 static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
     49   0x80, 0x00, 0x00, 0x20,
     50   0x21, 0x12, 0xA4, 0x42,
     51   '0', '1', '2', '3',
     52   '4', '5', '6', '7',
     53   '8', '9', 'a', 'b',
     54 };
     55 
     56 static unsigned char kTurnChannelDataMessageWithOddLength[] = {
     57   0x40, 0x00, 0x00, 0x05,
     58   0x21, 0x12, 0xA4, 0x42,
     59   '0',
     60 };
     61 
     62 
     63 static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
     64 static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
     65 
     66 class AsyncStunTCPSocketTest : public testing::Test,
     67                                public sigslot::has_slots<> {
     68  protected:
     69   AsyncStunTCPSocketTest()
     70       : vss_(new rtc::VirtualSocketServer(NULL)),
     71         ss_scope_(vss_.get()) {
     72   }
     73 
     74   virtual void SetUp() {
     75     CreateSockets();
     76   }
     77 
     78   void CreateSockets() {
     79     rtc::AsyncSocket* server = vss_->CreateAsyncSocket(
     80         kServerAddr.family(), SOCK_STREAM);
     81     server->Bind(kServerAddr);
     82     recv_socket_.reset(new AsyncStunTCPSocket(server, true));
     83     recv_socket_->SignalNewConnection.connect(
     84         this, &AsyncStunTCPSocketTest::OnNewConnection);
     85 
     86     rtc::AsyncSocket* client = vss_->CreateAsyncSocket(
     87         kClientAddr.family(), SOCK_STREAM);
     88     send_socket_.reset(AsyncStunTCPSocket::Create(
     89         client, kClientAddr, recv_socket_->GetLocalAddress()));
     90     ASSERT_TRUE(send_socket_.get() != NULL);
     91     vss_->ProcessMessagesUntilIdle();
     92   }
     93 
     94   void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
     95                     size_t len, const rtc::SocketAddress& remote_addr,
     96                     const rtc::PacketTime& packet_time) {
     97     recv_packets_.push_back(std::string(data, len));
     98   }
     99 
    100   void OnNewConnection(rtc::AsyncPacketSocket* server,
    101                        rtc::AsyncPacketSocket* new_socket) {
    102     listen_socket_.reset(new_socket);
    103     new_socket->SignalReadPacket.connect(
    104         this, &AsyncStunTCPSocketTest::OnReadPacket);
    105   }
    106 
    107   bool Send(const void* data, size_t len) {
    108     rtc::PacketOptions options;
    109     size_t ret = send_socket_->Send(
    110         reinterpret_cast<const char*>(data), len, options);
    111     vss_->ProcessMessagesUntilIdle();
    112     return (ret == len);
    113   }
    114 
    115   bool CheckData(const void* data, int len) {
    116     bool ret = false;
    117     if (recv_packets_.size()) {
    118       std::string packet =  recv_packets_.front();
    119       recv_packets_.pop_front();
    120       ret = (memcmp(data, packet.c_str(), len) == 0);
    121     }
    122     return ret;
    123   }
    124 
    125   rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
    126   rtc::SocketServerScope ss_scope_;
    127   rtc::scoped_ptr<AsyncStunTCPSocket> send_socket_;
    128   rtc::scoped_ptr<AsyncStunTCPSocket> recv_socket_;
    129   rtc::scoped_ptr<rtc::AsyncPacketSocket> listen_socket_;
    130   std::list<std::string> recv_packets_;
    131 };
    132 
    133 // Testing a stun packet sent/recv properly.
    134 TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
    135   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
    136                    sizeof(kStunMessageWithZeroLength)));
    137   EXPECT_EQ(1u, recv_packets_.size());
    138   EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
    139                         sizeof(kStunMessageWithZeroLength)));
    140 }
    141 
    142 // Verify sending multiple packets.
    143 TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
    144   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
    145                    sizeof(kStunMessageWithZeroLength)));
    146   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
    147                    sizeof(kStunMessageWithZeroLength)));
    148   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
    149                    sizeof(kStunMessageWithZeroLength)));
    150   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
    151                    sizeof(kStunMessageWithZeroLength)));
    152   EXPECT_EQ(4u, recv_packets_.size());
    153 }
    154 
    155 // Verifying TURN channel data message with zero length.
    156 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
    157   EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
    158                    sizeof(kTurnChannelDataMessageWithZeroLength)));
    159   EXPECT_EQ(1u, recv_packets_.size());
    160   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
    161                         sizeof(kTurnChannelDataMessageWithZeroLength)));
    162 }
    163 
    164 // Verifying TURN channel data message.
    165 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
    166   EXPECT_TRUE(Send(kTurnChannelDataMessage,
    167                    sizeof(kTurnChannelDataMessage)));
    168   EXPECT_EQ(1u, recv_packets_.size());
    169   EXPECT_TRUE(CheckData(kTurnChannelDataMessage,
    170                         sizeof(kTurnChannelDataMessage)));
    171 }
    172 
    173 // Verifying TURN channel messages which needs padding handled properly.
    174 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
    175   EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
    176                    sizeof(kTurnChannelDataMessageWithOddLength)));
    177   EXPECT_EQ(1u, recv_packets_.size());
    178   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
    179                         sizeof(kTurnChannelDataMessageWithOddLength)));
    180 }
    181 
    182 // Verifying stun message with invalid length.
    183 TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
    184   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
    185                     sizeof(kStunMessageWithInvalidLength)));
    186   EXPECT_EQ(0u, recv_packets_.size());
    187 
    188   // Modify the message length to larger value.
    189   kStunMessageWithInvalidLength[2] = 0xFF;
    190   kStunMessageWithInvalidLength[3] = 0xFF;
    191   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
    192                     sizeof(kStunMessageWithInvalidLength)));
    193 
    194   // Modify the message length to smaller value.
    195   kStunMessageWithInvalidLength[2] = 0x00;
    196   kStunMessageWithInvalidLength[3] = 0x01;
    197   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
    198                     sizeof(kStunMessageWithInvalidLength)));
    199 }
    200 
    201 // Verifying TURN channel data message with invalid length.
    202 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
    203   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
    204                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
    205   // Modify the length to larger value.
    206   kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
    207   kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
    208   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
    209                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
    210 
    211   // Modify the length to smaller value.
    212   kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
    213   kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
    214   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
    215                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
    216 }
    217 
    218 // Verifying a small buffer handled (dropped) properly. This will be
    219 // a common one for both stun and turn.
    220 TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
    221   char data[1];
    222   EXPECT_FALSE(Send(data, sizeof(data)));
    223 }
    224 
    225 // Verifying a legal large turn message.
    226 TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
    227   // We have problem in getting the SignalWriteEvent from the virtual socket
    228   // server. So increasing the send buffer to 64k.
    229   // TODO(mallinath) - Remove this setting after we fix vss issue.
    230   vss_->set_send_buffer_capacity(64 * 1024);
    231   unsigned char packet[65539];
    232   packet[0] = 0x40;
    233   packet[1] = 0x00;
    234   packet[2] = 0xFF;
    235   packet[3] = 0xFF;
    236   EXPECT_TRUE(Send(packet, sizeof(packet)));
    237 }
    238 
    239 // Verifying a legal large stun message.
    240 TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
    241   // We have problem in getting the SignalWriteEvent from the virtual socket
    242   // server. So increasing the send buffer to 64k.
    243   // TODO(mallinath) - Remove this setting after we fix vss issue.
    244   vss_->set_send_buffer_capacity(64 * 1024);
    245   unsigned char packet[65552];
    246   packet[0] = 0x00;
    247   packet[1] = 0x01;
    248   packet[2] = 0xFF;
    249   packet[3] = 0xFC;
    250   EXPECT_TRUE(Send(packet, sizeof(packet)));
    251 }
    252 
    253 // Investigate why WriteEvent is not signaled from VSS.
    254 TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
    255   vss_->set_send_buffer_capacity(1);
    256   Send(kTurnChannelDataMessageWithOddLength,
    257        sizeof(kTurnChannelDataMessageWithOddLength));
    258   EXPECT_EQ(1u, recv_packets_.size());
    259   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
    260                         sizeof(kTurnChannelDataMessageWithOddLength)));
    261 }
    262 
    263 }  // namespace cricket
    264