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_udp.h"
      6 
      7 #include <deque>
      8 #include <vector>
      9 
     10 #include "base/logging.h"
     11 #include "base/sys_byteorder.h"
     12 #include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
     13 #include "net/base/io_buffer.h"
     14 #include "net/base/ip_endpoint.h"
     15 #include "net/base/net_errors.h"
     16 #include "net/udp/datagram_server_socket.h"
     17 #include "testing/gmock/include/gmock/gmock.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 using ::testing::_;
     21 using ::testing::DeleteArg;
     22 using ::testing::DoAll;
     23 using ::testing::Return;
     24 
     25 namespace {
     26 
     27 class FakeDatagramServerSocket : public net::DatagramServerSocket {
     28  public:
     29   typedef std::pair<net::IPEndPoint, std::vector<char> > UDPPacket;
     30 
     31   // P2PSocketHostUdp destroyes a socket on errors so sent packets
     32   // need to be stored outside of this object.
     33   explicit FakeDatagramServerSocket(std::deque<UDPPacket>* sent_packets)
     34       : sent_packets_(sent_packets) {
     35   }
     36 
     37   virtual void Close() OVERRIDE {
     38   }
     39 
     40   virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE {
     41     NOTREACHED();
     42     return net::ERR_SOCKET_NOT_CONNECTED;
     43   }
     44 
     45   virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE {
     46     *address = address_;
     47     return 0;
     48   }
     49 
     50   virtual int Listen(const net::IPEndPoint& address) OVERRIDE {
     51     address_ = address;
     52     return 0;
     53   }
     54 
     55   virtual int RecvFrom(net::IOBuffer* buf, int buf_len,
     56                        net::IPEndPoint* address,
     57                        const net::CompletionCallback& callback) OVERRIDE {
     58     CHECK(recv_callback_.is_null());
     59     if (incoming_packets_.size() > 0) {
     60       scoped_refptr<net::IOBuffer> buffer(buf);
     61       int size = std::min(
     62           static_cast<int>(incoming_packets_.front().second.size()), buf_len);
     63       memcpy(buffer->data(), &*incoming_packets_.front().second.begin(), size);
     64       *address = incoming_packets_.front().first;
     65       incoming_packets_.pop_front();
     66       return size;
     67     } else {
     68       recv_callback_ = callback;
     69       recv_buffer_ = buf;
     70       recv_size_ = buf_len;
     71       recv_address_ = address;
     72       return net::ERR_IO_PENDING;
     73     }
     74   }
     75 
     76   virtual int SendTo(net::IOBuffer* buf, int buf_len,
     77                      const net::IPEndPoint& address,
     78                      const net::CompletionCallback& callback) OVERRIDE {
     79     scoped_refptr<net::IOBuffer> buffer(buf);
     80     std::vector<char> data_vector(buffer->data(), buffer->data() + buf_len);
     81     sent_packets_->push_back(UDPPacket(address, data_vector));
     82     return buf_len;
     83   }
     84 
     85   virtual bool SetReceiveBufferSize(int32 size) OVERRIDE {
     86     return true;
     87   }
     88 
     89   virtual bool SetSendBufferSize(int32 size) OVERRIDE {
     90     return true;
     91   }
     92 
     93   void ReceivePacket(const net::IPEndPoint& address, std::vector<char> data) {
     94     if (!recv_callback_.is_null()) {
     95       int size = std::min(recv_size_, static_cast<int>(data.size()));
     96       memcpy(recv_buffer_->data(), &*data.begin(), size);
     97       *recv_address_ = address;
     98       net::CompletionCallback cb = recv_callback_;
     99       recv_callback_.Reset();
    100       recv_buffer_ = NULL;
    101       cb.Run(size);
    102     } else {
    103       incoming_packets_.push_back(UDPPacket(address, data));
    104     }
    105   }
    106 
    107   virtual const net::BoundNetLog& NetLog() const OVERRIDE {
    108     return net_log_;
    109   }
    110 
    111   virtual void AllowAddressReuse() OVERRIDE {
    112     NOTIMPLEMENTED();
    113   }
    114 
    115   virtual void AllowBroadcast() OVERRIDE {
    116     NOTIMPLEMENTED();
    117   }
    118 
    119   virtual int JoinGroup(
    120       const net::IPAddressNumber& group_address) const OVERRIDE {
    121     NOTIMPLEMENTED();
    122     return net::ERR_NOT_IMPLEMENTED;
    123   }
    124 
    125   virtual int LeaveGroup(
    126       const net::IPAddressNumber& group_address) const OVERRIDE {
    127     NOTIMPLEMENTED();
    128     return net::ERR_NOT_IMPLEMENTED;
    129   }
    130 
    131   virtual int SetMulticastTimeToLive(int time_to_live) OVERRIDE {
    132     NOTIMPLEMENTED();
    133     return net::ERR_NOT_IMPLEMENTED;
    134   }
    135 
    136   virtual int SetMulticastLoopbackMode(bool loopback) OVERRIDE {
    137     NOTIMPLEMENTED();
    138     return net::ERR_NOT_IMPLEMENTED;
    139   }
    140 
    141  private:
    142   net::IPEndPoint address_;
    143   std::deque<UDPPacket>* sent_packets_;
    144   std::deque<UDPPacket> incoming_packets_;
    145   net::BoundNetLog net_log_;
    146 
    147   scoped_refptr<net::IOBuffer> recv_buffer_;
    148   net::IPEndPoint* recv_address_;
    149   int recv_size_;
    150   net::CompletionCallback recv_callback_;
    151 };
    152 
    153 }  // namespace
    154 
    155 namespace content {
    156 
    157 class P2PSocketHostUdpTest : public testing::Test {
    158  protected:
    159   virtual void SetUp() OVERRIDE {
    160     EXPECT_CALL(sender_, Send(
    161         MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
    162         .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    163 
    164     socket_host_.reset(new P2PSocketHostUdp(&sender_, 0));
    165     socket_ = new FakeDatagramServerSocket(&sent_packets_);
    166     socket_host_->socket_.reset(socket_);
    167 
    168     local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1);
    169     socket_host_->Init(local_address_, net::IPEndPoint());
    170 
    171     dest1_ = ParseAddress(kTestIpAddress1, kTestPort1);
    172     dest2_ = ParseAddress(kTestIpAddress2, kTestPort2);
    173   }
    174 
    175   std::deque<FakeDatagramServerSocket::UDPPacket> sent_packets_;
    176   FakeDatagramServerSocket* socket_; // Owned by |socket_host_|.
    177   scoped_ptr<P2PSocketHostUdp> socket_host_;
    178   MockIPCSender sender_;
    179 
    180   net::IPEndPoint local_address_;
    181 
    182   net::IPEndPoint dest1_;
    183   net::IPEndPoint dest2_;
    184 };
    185 
    186 // Verify that we can send STUN messages before we receive anything
    187 // from the other side.
    188 TEST_F(P2PSocketHostUdpTest, SendStunNoAuth) {
    189   EXPECT_CALL(sender_, Send(
    190       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    191       .Times(3)
    192       .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
    193 
    194   std::vector<char> packet1;
    195   CreateStunRequest(&packet1);
    196   socket_host_->Send(dest1_, packet1);
    197 
    198   std::vector<char> packet2;
    199   CreateStunResponse(&packet2);
    200   socket_host_->Send(dest1_, packet2);
    201 
    202   std::vector<char> packet3;
    203   CreateStunError(&packet3);
    204   socket_host_->Send(dest1_, packet3);
    205 
    206   ASSERT_EQ(sent_packets_.size(), 3U);
    207   ASSERT_EQ(sent_packets_[0].second, packet1);
    208   ASSERT_EQ(sent_packets_[1].second, packet2);
    209   ASSERT_EQ(sent_packets_[2].second, packet3);
    210 }
    211 
    212 // Verify that no data packets can be sent before STUN binding has
    213 // finished.
    214 TEST_F(P2PSocketHostUdpTest, SendDataNoAuth) {
    215   EXPECT_CALL(sender_, Send(
    216       MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
    217       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    218 
    219   std::vector<char> packet;
    220   CreateRandomPacket(&packet);
    221   socket_host_->Send(dest1_, packet);
    222 
    223   ASSERT_EQ(sent_packets_.size(), 0U);
    224 }
    225 
    226 // Verify that we can send data after we've received STUN request
    227 // from the other side.
    228 TEST_F(P2PSocketHostUdpTest, SendAfterStunRequest) {
    229   // Receive packet from |dest1_|.
    230   std::vector<char> request_packet;
    231   CreateStunRequest(&request_packet);
    232 
    233   EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
    234       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    235   socket_->ReceivePacket(dest1_, request_packet);
    236 
    237   // Now we should be able to send any data to |dest1_|.
    238   EXPECT_CALL(sender_, Send(
    239       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    240       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    241   std::vector<char> packet;
    242   CreateRandomPacket(&packet);
    243   socket_host_->Send(dest1_, packet);
    244 
    245   ASSERT_EQ(1U, sent_packets_.size());
    246   ASSERT_EQ(dest1_, sent_packets_[0].first);
    247 }
    248 
    249 // Verify that we can send data after we've received STUN response
    250 // from the other side.
    251 TEST_F(P2PSocketHostUdpTest, SendAfterStunResponse) {
    252   // Receive packet from |dest1_|.
    253   std::vector<char> request_packet;
    254   CreateStunRequest(&request_packet);
    255 
    256   EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
    257       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    258   socket_->ReceivePacket(dest1_, request_packet);
    259 
    260   // Now we should be able to send any data to |dest1_|.
    261   EXPECT_CALL(sender_, Send(
    262       MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
    263       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    264   std::vector<char> packet;
    265   CreateRandomPacket(&packet);
    266   socket_host_->Send(dest1_, packet);
    267 
    268   ASSERT_EQ(1U, sent_packets_.size());
    269   ASSERT_EQ(dest1_, sent_packets_[0].first);
    270 }
    271 
    272 // Verify messages still cannot be sent to an unathorized host after
    273 // successful binding with different host.
    274 TEST_F(P2PSocketHostUdpTest, SendAfterStunResponseDifferentHost) {
    275   // Receive packet from |dest1_|.
    276   std::vector<char> request_packet;
    277   CreateStunRequest(&request_packet);
    278 
    279   EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
    280       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    281   socket_->ReceivePacket(dest1_, request_packet);
    282 
    283   // Should fail when trying to send the same packet to |dest2_|.
    284   std::vector<char> packet;
    285   CreateRandomPacket(&packet);
    286   EXPECT_CALL(sender_, Send(
    287       MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
    288       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    289   socket_host_->Send(dest2_, packet);
    290 }
    291 
    292 }  // namespace content
    293