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 #ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
      6 #define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/location.h"
     11 #include "base/single_thread_task_runner.h"
     12 #include "base/sys_byteorder.h"
     13 #include "base/thread_task_runner_handle.h"
     14 #include "content/common/p2p_messages.h"
     15 #include "ipc/ipc_message_utils.h"
     16 #include "ipc/ipc_sender.h"
     17 #include "net/base/address_list.h"
     18 #include "net/base/completion_callback.h"
     19 #include "net/base/io_buffer.h"
     20 #include "net/base/net_errors.h"
     21 #include "net/socket/stream_socket.h"
     22 #include "testing/gmock/include/gmock/gmock.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 
     25 namespace {
     26 
     27 const char kTestLocalIpAddress[] = "123.44.22.4";
     28 const char kTestIpAddress1[] = "123.44.22.31";
     29 const int kTestPort1 = 234;
     30 const char kTestIpAddress2[] = "133.11.22.33";
     31 const int kTestPort2 = 543;
     32 
     33 const int kStunHeaderSize = 20;
     34 const uint16 kStunBindingRequest = 0x0001;
     35 const uint16 kStunBindingResponse = 0x0102;
     36 const uint16 kStunBindingError = 0x0111;
     37 const uint32 kStunMagicCookie = 0x2112A442;
     38 
     39 class MockIPCSender : public IPC::Sender {
     40  public:
     41   MockIPCSender();
     42   virtual ~MockIPCSender();
     43 
     44   MOCK_METHOD1(Send, bool(IPC::Message* msg));
     45 };
     46 
     47 MockIPCSender::MockIPCSender() { }
     48 MockIPCSender::~MockIPCSender() { }
     49 
     50 class FakeSocket : public net::StreamSocket {
     51  public:
     52   FakeSocket(std::string* written_data);
     53   virtual ~FakeSocket();
     54 
     55   void set_async_write(bool async_write) { async_write_ = async_write; }
     56   void AppendInputData(const char* data, int data_size);
     57   int input_pos() const { return input_pos_; }
     58   bool read_pending() const { return read_pending_; }
     59   void SetPeerAddress(const net::IPEndPoint& peer_address);
     60   void SetLocalAddress(const net::IPEndPoint& local_address);
     61 
     62   // net::Socket implementation.
     63   virtual int Read(net::IOBuffer* buf, int buf_len,
     64                    const net::CompletionCallback& callback) OVERRIDE;
     65   virtual int Write(net::IOBuffer* buf, int buf_len,
     66                     const net::CompletionCallback& callback) OVERRIDE;
     67   virtual bool SetReceiveBufferSize(int32 size) OVERRIDE;
     68   virtual bool SetSendBufferSize(int32 size) OVERRIDE;
     69   virtual int Connect(const net::CompletionCallback& callback) OVERRIDE;
     70   virtual void Disconnect() OVERRIDE;
     71   virtual bool IsConnected() const OVERRIDE;
     72   virtual bool IsConnectedAndIdle() const OVERRIDE;
     73   virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE;
     74   virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE;
     75   virtual const net::BoundNetLog& NetLog() const OVERRIDE;
     76   virtual void SetSubresourceSpeculation() OVERRIDE;
     77   virtual void SetOmniboxSpeculation() OVERRIDE;
     78   virtual bool WasEverUsed() const OVERRIDE;
     79   virtual bool UsingTCPFastOpen() const OVERRIDE;
     80   virtual bool WasNpnNegotiated() const OVERRIDE;
     81   virtual net::NextProto GetNegotiatedProtocol() const OVERRIDE;
     82   virtual bool GetSSLInfo(net::SSLInfo* ssl_info) OVERRIDE;
     83 
     84  private:
     85   void DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len,
     86                     const net::CompletionCallback& callback);
     87 
     88   bool read_pending_;
     89   scoped_refptr<net::IOBuffer> read_buffer_;
     90   int read_buffer_size_;
     91   net::CompletionCallback read_callback_;
     92 
     93   std::string input_data_;
     94   int input_pos_;
     95 
     96   std::string* written_data_;
     97   bool async_write_;
     98   bool write_pending_;
     99 
    100   net::IPEndPoint peer_address_;
    101   net::IPEndPoint local_address_;
    102 
    103   net::BoundNetLog net_log_;
    104 };
    105 
    106 FakeSocket::FakeSocket(std::string* written_data)
    107     : read_pending_(false),
    108       input_pos_(0),
    109       written_data_(written_data),
    110       async_write_(false),
    111       write_pending_(false) {
    112 }
    113 
    114 FakeSocket::~FakeSocket() { }
    115 
    116 void FakeSocket::AppendInputData(const char* data, int data_size) {
    117   input_data_.insert(input_data_.end(), data, data + data_size);
    118   // Complete pending read if any.
    119   if (read_pending_) {
    120     read_pending_ = false;
    121     int result = std::min(read_buffer_size_,
    122                           static_cast<int>(input_data_.size() - input_pos_));
    123     CHECK(result > 0);
    124     memcpy(read_buffer_->data(), &input_data_[0] + input_pos_, result);
    125     input_pos_ += result;
    126     read_buffer_ = NULL;
    127     net::CompletionCallback cb = read_callback_;
    128     read_callback_.Reset();
    129     cb.Run(result);
    130   }
    131 }
    132 
    133 void FakeSocket::SetPeerAddress(const net::IPEndPoint& peer_address) {
    134   peer_address_ = peer_address;
    135 }
    136 
    137 void FakeSocket::SetLocalAddress(const net::IPEndPoint& local_address) {
    138   local_address_ = local_address;
    139 }
    140 
    141 int FakeSocket::Read(net::IOBuffer* buf, int buf_len,
    142                      const net::CompletionCallback& callback) {
    143   DCHECK(buf);
    144   if (input_pos_ < static_cast<int>(input_data_.size())){
    145     int result = std::min(buf_len,
    146                           static_cast<int>(input_data_.size()) - input_pos_);
    147     memcpy(buf->data(), &(*input_data_.begin()) + input_pos_, result);
    148     input_pos_ += result;
    149     return result;
    150   } else {
    151     read_pending_ = true;
    152     read_buffer_ = buf;
    153     read_buffer_size_ = buf_len;
    154     read_callback_ = callback;
    155     return net::ERR_IO_PENDING;
    156   }
    157 }
    158 
    159 int FakeSocket::Write(net::IOBuffer* buf, int buf_len,
    160                       const net::CompletionCallback& callback) {
    161   DCHECK(buf);
    162   DCHECK(!write_pending_);
    163 
    164   if (async_write_) {
    165 
    166     base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(
    167         &FakeSocket::DoAsyncWrite, base::Unretained(this),
    168         scoped_refptr<net::IOBuffer>(buf), buf_len, callback));
    169     write_pending_ = true;
    170     return net::ERR_IO_PENDING;
    171   }
    172 
    173   if (written_data_) {
    174     written_data_->insert(written_data_->end(),
    175                           buf->data(), buf->data() + buf_len);
    176   }
    177   return buf_len;
    178 }
    179 
    180 void FakeSocket::DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len,
    181                               const net::CompletionCallback& callback) {
    182   write_pending_ = false;
    183 
    184   if (written_data_) {
    185     written_data_->insert(written_data_->end(),
    186                           buf->data(), buf->data() + buf_len);
    187   }
    188   callback.Run(buf_len);
    189 }
    190 
    191 bool FakeSocket::SetReceiveBufferSize(int32 size) {
    192   NOTIMPLEMENTED();
    193   return false;
    194 }
    195 bool FakeSocket::SetSendBufferSize(int32 size) {
    196   NOTIMPLEMENTED();
    197   return false;
    198 }
    199 
    200 int FakeSocket::Connect(const net::CompletionCallback& callback) {
    201   return 0;
    202 }
    203 
    204 void FakeSocket::Disconnect() {
    205   NOTREACHED();
    206 }
    207 
    208 bool FakeSocket::IsConnected() const {
    209   return true;
    210 }
    211 
    212 bool FakeSocket::IsConnectedAndIdle() const {
    213   return false;
    214 }
    215 
    216 int FakeSocket::GetPeerAddress(net::IPEndPoint* address) const {
    217   *address = peer_address_;
    218   return net::OK;
    219 }
    220 
    221 int FakeSocket::GetLocalAddress(net::IPEndPoint* address) const {
    222   *address = local_address_;
    223   return net::OK;
    224 }
    225 
    226 const net::BoundNetLog& FakeSocket::NetLog() const {
    227   NOTREACHED();
    228   return net_log_;
    229 }
    230 
    231 void FakeSocket::SetSubresourceSpeculation() {
    232   NOTREACHED();
    233 }
    234 
    235 void FakeSocket::SetOmniboxSpeculation() {
    236   NOTREACHED();
    237 }
    238 
    239 bool FakeSocket::WasEverUsed() const {
    240   return true;
    241 }
    242 
    243 bool FakeSocket::UsingTCPFastOpen() const {
    244   return false;
    245 }
    246 
    247 bool FakeSocket::WasNpnNegotiated() const {
    248   return false;
    249 }
    250 
    251 net::NextProto FakeSocket::GetNegotiatedProtocol() const {
    252   return net::kProtoUnknown;
    253 }
    254 
    255 bool FakeSocket::GetSSLInfo(net::SSLInfo* ssl_info) {
    256   return false;
    257 }
    258 
    259 void CreateRandomPacket(std::vector<char>* packet) {
    260   size_t size = kStunHeaderSize + rand() % 1000;
    261   packet->resize(size);
    262   for (size_t i = 0; i < size; i++) {
    263     (*packet)[i] = rand() % 256;
    264   }
    265   // Always set the first bit to ensure that generated packet is not
    266   // valid STUN packet.
    267   (*packet)[0] = (*packet)[0] | 0x80;
    268 }
    269 
    270 void CreateStunPacket(std::vector<char>* packet, uint16 type) {
    271   CreateRandomPacket(packet);
    272   *reinterpret_cast<uint16*>(&*packet->begin()) = base::HostToNet16(type);
    273   *reinterpret_cast<uint16*>(&*packet->begin() + 2) =
    274       base::HostToNet16(packet->size() - kStunHeaderSize);
    275   *reinterpret_cast<uint32*>(&*packet->begin() + 4) =
    276       base::HostToNet32(kStunMagicCookie);
    277 }
    278 
    279 void CreateStunRequest(std::vector<char>* packet) {
    280   CreateStunPacket(packet, kStunBindingRequest);
    281 }
    282 
    283 void CreateStunResponse(std::vector<char>* packet) {
    284   CreateStunPacket(packet, kStunBindingResponse);
    285 }
    286 
    287 void CreateStunError(std::vector<char>* packet) {
    288   CreateStunPacket(packet, kStunBindingError);
    289 }
    290 
    291 net::IPEndPoint ParseAddress(const std::string ip_str, int port) {
    292   net::IPAddressNumber ip;
    293   EXPECT_TRUE(net::ParseIPLiteralToNumber(ip_str, &ip));
    294   return net::IPEndPoint(ip, port);
    295 }
    296 
    297 MATCHER_P(MatchMessage, type, "") {
    298   return arg->type() == type;
    299 }
    300 
    301 MATCHER_P(MatchPacketMessage, packet_content, "") {
    302   if (arg->type() != P2PMsg_OnDataReceived::ID)
    303     return false;
    304   P2PMsg_OnDataReceived::Param params;
    305   P2PMsg_OnDataReceived::Read(arg, &params);
    306   return params.c == packet_content;
    307 }
    308 
    309 MATCHER_P(MatchIncomingSocketMessage, address, "") {
    310   if (arg->type() != P2PMsg_OnIncomingTcpConnection::ID)
    311     return false;
    312   P2PMsg_OnIncomingTcpConnection::Param params;
    313   P2PMsg_OnIncomingTcpConnection::Read(
    314       arg, &params);
    315   return params.b == address;
    316 }
    317 
    318 }  // namespace
    319 
    320 #endif  // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
    321