Home | History | Annotate | Download | only in p2p
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/renderer_host/p2p/socket_host_tcp.h"
      6 
      7 #include <deque>
      8 
      9 #include "base/sys_byteorder.h"
     10 #include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
     11 #include "net/socket/stream_socket.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using ::testing::_;
     16 using ::testing::DeleteArg;
     17 using ::testing::DoAll;
     18 using ::testing::Return;
     19 
     20 namespace content {
     21 
     22 class P2PSocketHostTcpTestBase : public testing::Test {
     23  protected:
     24   explicit P2PSocketHostTcpTestBase(P2PSocketType type)
     25       : socket_type_(type) {
     26   }
     27 
     28   virtual void SetUp() OVERRIDE {
     29     EXPECT_CALL(sender_, Send(
     30         MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
     31         .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
     32 
     33     if (socket_type_ == P2P_SOCKET_TCP_CLIENT) {
     34       socket_host_.reset(new P2PSocketHostTcp(
     35                             &sender_, 0,  P2P_SOCKET_TCP_CLIENT, NULL));
     36     } else {
     37       socket_host_.reset(new P2PSocketHostStunTcp(
     38                             &sender_, 0,  P2P_SOCKET_STUN_TCP_CLIENT, NULL));
     39     }
     40 
     41     socket_ = new FakeSocket(&sent_data_);
     42     socket_->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
     43     socket_host_->socket_.reset(socket_);
     44 
     45     dest_ = ParseAddress(kTestIpAddress1, kTestPort1);
     46 
     47     local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1);
     48 
     49     socket_host_->remote_address_ = dest_;
     50     socket_host_->state_ = P2PSocketHost::STATE_CONNECTING;
     51     socket_host_->OnConnected(net::OK);
     52   }
     53 
     54   std::string IntToSize(int size) {
     55     std::string result;
     56     uint16 size16 = base::HostToNet16(size);
     57     result.resize(sizeof(size16));
     58     memcpy(&result[0], &size16, sizeof(size16));
     59     return result;
     60   }
     61 
     62   std::string sent_data_;
     63   FakeSocket* socket_;  // Owned by |socket_host_|.
     64   scoped_ptr<P2PSocketHostTcpBase> socket_host_;
     65   MockIPCSender sender_;
     66 
     67   net::IPEndPoint local_address_;
     68 
     69   net::IPEndPoint dest_;
     70   net::IPEndPoint dest2_;
     71 
     72   P2PSocketType socket_type_;
     73 };
     74 
     75 class P2PSocketHostTcpTest : public P2PSocketHostTcpTestBase {
     76  protected:
     77   P2PSocketHostTcpTest() : P2PSocketHostTcpTestBase(P2P_SOCKET_TCP_CLIENT) { }
     78 };
     79 
     80 class P2PSocketHostStunTcpTest : public P2PSocketHostTcpTestBase {
     81  protected:
     82   P2PSocketHostStunTcpTest()
     83       : P2PSocketHostTcpTestBase(P2P_SOCKET_STUN_TCP_CLIENT) {
     84   }
     85 };
     86 
     87 // Verify that we can send STUN message and that they are formatted
     88 // properly.
     89 TEST_F(P2PSocketHostTcpTest, SendStunNoAuth) {
     90   EXPECT_CALL(sender_, Send(
     91       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
     92       .Times(3)
     93       .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
     94 
     95   std::vector<char> packet1;
     96   CreateStunRequest(&packet1);
     97   socket_host_->Send(dest_, packet1);
     98 
     99   std::vector<char> packet2;
    100   CreateStunResponse(&packet2);
    101   socket_host_->Send(dest_, packet2);
    102 
    103   std::vector<char> packet3;
    104   CreateStunError(&packet3);
    105   socket_host_->Send(dest_, packet3);
    106 
    107   std::string expected_data;
    108   expected_data.append(IntToSize(packet1.size()));
    109   expected_data.append(packet1.begin(), packet1.end());
    110   expected_data.append(IntToSize(packet2.size()));
    111   expected_data.append(packet2.begin(), packet2.end());
    112   expected_data.append(IntToSize(packet3.size()));
    113   expected_data.append(packet3.begin(), packet3.end());
    114 
    115   EXPECT_EQ(expected_data, sent_data_);
    116 }
    117 
    118 // Verify that we can receive STUN messages from the socket, and that
    119 // the messages are parsed properly.
    120 TEST_F(P2PSocketHostTcpTest, ReceiveStun) {
    121   EXPECT_CALL(sender_, Send(
    122       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    123       .Times(3)
    124       .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
    125 
    126   std::vector<char> packet1;
    127   CreateStunRequest(&packet1);
    128   socket_host_->Send(dest_, packet1);
    129 
    130   std::vector<char> packet2;
    131   CreateStunResponse(&packet2);
    132   socket_host_->Send(dest_, packet2);
    133 
    134   std::vector<char> packet3;
    135   CreateStunError(&packet3);
    136   socket_host_->Send(dest_, packet3);
    137 
    138   std::string received_data;
    139   received_data.append(IntToSize(packet1.size()));
    140   received_data.append(packet1.begin(), packet1.end());
    141   received_data.append(IntToSize(packet2.size()));
    142   received_data.append(packet2.begin(), packet2.end());
    143   received_data.append(IntToSize(packet3.size()));
    144   received_data.append(packet3.begin(), packet3.end());
    145 
    146   EXPECT_CALL(sender_, Send(MatchPacketMessage(packet1)))
    147       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    148   EXPECT_CALL(sender_, Send(MatchPacketMessage(packet2)))
    149       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    150   EXPECT_CALL(sender_, Send(MatchPacketMessage(packet3)))
    151       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    152 
    153   size_t pos = 0;
    154   size_t step_sizes[] = {3, 2, 1};
    155   size_t step = 0;
    156   while (pos < received_data.size()) {
    157     size_t step_size = std::min(step_sizes[step], received_data.size() - pos);
    158     socket_->AppendInputData(&received_data[pos], step_size);
    159     pos += step_size;
    160     if (++step >= arraysize(step_sizes))
    161       step = 0;
    162   }
    163 }
    164 
    165 // Verify that we can't send data before we've received STUN response
    166 // from the other side.
    167 TEST_F(P2PSocketHostTcpTest, SendDataNoAuth) {
    168   EXPECT_CALL(sender_, Send(
    169       MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
    170       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    171 
    172   std::vector<char> packet;
    173   CreateRandomPacket(&packet);
    174   socket_host_->Send(dest_, packet);
    175 
    176   EXPECT_EQ(0U, sent_data_.size());
    177 }
    178 
    179 // Verify that we can send data after we've received STUN response
    180 // from the other side.
    181 TEST_F(P2PSocketHostTcpTest, SendAfterStunRequest) {
    182   // Receive packet from |dest_|.
    183   std::vector<char> request_packet;
    184   CreateStunRequest(&request_packet);
    185 
    186   std::string received_data;
    187   received_data.append(IntToSize(request_packet.size()));
    188   received_data.append(request_packet.begin(), request_packet.end());
    189 
    190   EXPECT_CALL(sender_, Send(
    191       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    192       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    193   EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
    194       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    195   socket_->AppendInputData(&received_data[0], received_data.size());
    196 
    197   // Now we should be able to send any data to |dest_|.
    198   std::vector<char> packet;
    199   CreateRandomPacket(&packet);
    200   socket_host_->Send(dest_, packet);
    201 
    202   std::string expected_data;
    203   expected_data.append(IntToSize(packet.size()));
    204   expected_data.append(packet.begin(), packet.end());
    205 
    206   EXPECT_EQ(expected_data, sent_data_);
    207 }
    208 
    209 // Verify that asynchronous writes are handled correctly.
    210 TEST_F(P2PSocketHostTcpTest, AsyncWrites) {
    211   base::MessageLoop message_loop;
    212 
    213   socket_->set_async_write(true);
    214 
    215   EXPECT_CALL(sender_, Send(
    216       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    217       .Times(2)
    218       .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
    219 
    220   std::vector<char> packet1;
    221   CreateStunRequest(&packet1);
    222   socket_host_->Send(dest_, packet1);
    223 
    224   std::vector<char> packet2;
    225   CreateStunResponse(&packet2);
    226   socket_host_->Send(dest_, packet2);
    227 
    228   message_loop.RunUntilIdle();
    229 
    230   std::string expected_data;
    231   expected_data.append(IntToSize(packet1.size()));
    232   expected_data.append(packet1.begin(), packet1.end());
    233   expected_data.append(IntToSize(packet2.size()));
    234   expected_data.append(packet2.begin(), packet2.end());
    235 
    236   EXPECT_EQ(expected_data, sent_data_);
    237 }
    238 
    239 // Verify that we can send STUN message and that they are formatted
    240 // properly.
    241 TEST_F(P2PSocketHostStunTcpTest, SendStunNoAuth) {
    242   EXPECT_CALL(sender_, Send(
    243       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    244       .Times(3)
    245       .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
    246 
    247   std::vector<char> packet1;
    248   CreateStunRequest(&packet1);
    249   socket_host_->Send(dest_, packet1);
    250 
    251   std::vector<char> packet2;
    252   CreateStunResponse(&packet2);
    253   socket_host_->Send(dest_, packet2);
    254 
    255   std::vector<char> packet3;
    256   CreateStunError(&packet3);
    257   socket_host_->Send(dest_, packet3);
    258 
    259   std::string expected_data;
    260   expected_data.append(packet1.begin(), packet1.end());
    261   expected_data.append(packet2.begin(), packet2.end());
    262   expected_data.append(packet3.begin(), packet3.end());
    263 
    264   EXPECT_EQ(expected_data, sent_data_);
    265 }
    266 
    267 // Verify that we can receive STUN messages from the socket, and that
    268 // the messages are parsed properly.
    269 TEST_F(P2PSocketHostStunTcpTest, ReceiveStun) {
    270   EXPECT_CALL(sender_, Send(
    271       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    272       .Times(3)
    273       .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
    274 
    275   std::vector<char> packet1;
    276   CreateStunRequest(&packet1);
    277   socket_host_->Send(dest_, packet1);
    278 
    279   std::vector<char> packet2;
    280   CreateStunResponse(&packet2);
    281   socket_host_->Send(dest_, packet2);
    282 
    283   std::vector<char> packet3;
    284   CreateStunError(&packet3);
    285   socket_host_->Send(dest_, packet3);
    286 
    287   std::string received_data;
    288   received_data.append(packet1.begin(), packet1.end());
    289   received_data.append(packet2.begin(), packet2.end());
    290   received_data.append(packet3.begin(), packet3.end());
    291 
    292   EXPECT_CALL(sender_, Send(MatchPacketMessage(packet1)))
    293       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    294   EXPECT_CALL(sender_, Send(MatchPacketMessage(packet2)))
    295       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    296   EXPECT_CALL(sender_, Send(MatchPacketMessage(packet3)))
    297       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    298 
    299   size_t pos = 0;
    300   size_t step_sizes[] = {3, 2, 1};
    301   size_t step = 0;
    302   while (pos < received_data.size()) {
    303     size_t step_size = std::min(step_sizes[step], received_data.size() - pos);
    304     socket_->AppendInputData(&received_data[pos], step_size);
    305     pos += step_size;
    306     if (++step >= arraysize(step_sizes))
    307       step = 0;
    308   }
    309 }
    310 
    311 // Verify that we can't send data before we've received STUN response
    312 // from the other side.
    313 TEST_F(P2PSocketHostStunTcpTest, SendDataNoAuth) {
    314   EXPECT_CALL(sender_, Send(
    315       MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
    316       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    317 
    318   std::vector<char> packet;
    319   CreateRandomPacket(&packet);
    320   socket_host_->Send(dest_, packet);
    321 
    322   EXPECT_EQ(0U, sent_data_.size());
    323 }
    324 
    325 // Verify that asynchronous writes are handled correctly.
    326 TEST_F(P2PSocketHostStunTcpTest, AsyncWrites) {
    327   base::MessageLoop message_loop;
    328 
    329   socket_->set_async_write(true);
    330 
    331   EXPECT_CALL(sender_, Send(
    332       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    333       .Times(2)
    334       .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
    335 
    336   std::vector<char> packet1;
    337   CreateStunRequest(&packet1);
    338   socket_host_->Send(dest_, packet1);
    339 
    340   std::vector<char> packet2;
    341   CreateStunResponse(&packet2);
    342   socket_host_->Send(dest_, packet2);
    343 
    344   message_loop.RunUntilIdle();
    345 
    346   std::string expected_data;
    347   expected_data.append(packet1.begin(), packet1.end());
    348   expected_data.append(packet2.begin(), packet2.end());
    349 
    350   EXPECT_EQ(expected_data, sent_data_);
    351 }
    352 
    353 }  // namespace content
    354