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, ¶ms); 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, ¶ms); 315 return params.b == address; 316 } 317 318 } // namespace 319 320 #endif // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_ 321