1// Copyright (c) 2013 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_test_utils.h" 6 7#include "base/sys_byteorder.h" 8#include "base/thread_task_runner_handle.h" 9#include "net/base/completion_callback.h" 10#include "net/base/io_buffer.h" 11 12const int kStunHeaderSize = 20; 13const uint16 kStunBindingRequest = 0x0001; 14const uint16 kStunBindingResponse = 0x0102; 15const uint16 kStunBindingError = 0x0111; 16const uint32 kStunMagicCookie = 0x2112A442; 17 18MockIPCSender::MockIPCSender() { } 19MockIPCSender::~MockIPCSender() { } 20 21FakeSocket::FakeSocket(std::string* written_data) 22 : read_pending_(false), 23 input_pos_(0), 24 written_data_(written_data), 25 async_write_(false), 26 write_pending_(false) { 27} 28 29FakeSocket::~FakeSocket() { } 30 31void FakeSocket::AppendInputData(const char* data, int data_size) { 32 input_data_.insert(input_data_.end(), data, data + data_size); 33 // Complete pending read if any. 34 if (read_pending_) { 35 read_pending_ = false; 36 int result = std::min(read_buffer_size_, 37 static_cast<int>(input_data_.size() - input_pos_)); 38 CHECK(result > 0); 39 memcpy(read_buffer_->data(), &input_data_[0] + input_pos_, result); 40 input_pos_ += result; 41 read_buffer_ = NULL; 42 net::CompletionCallback cb = read_callback_; 43 read_callback_.Reset(); 44 cb.Run(result); 45 } 46} 47 48void FakeSocket::SetPeerAddress(const net::IPEndPoint& peer_address) { 49 peer_address_ = peer_address; 50} 51 52void FakeSocket::SetLocalAddress(const net::IPEndPoint& local_address) { 53 local_address_ = local_address; 54} 55 56int FakeSocket::Read(net::IOBuffer* buf, int buf_len, 57 const net::CompletionCallback& callback) { 58 DCHECK(buf); 59 if (input_pos_ < static_cast<int>(input_data_.size())){ 60 int result = std::min(buf_len, 61 static_cast<int>(input_data_.size()) - input_pos_); 62 memcpy(buf->data(), &(*input_data_.begin()) + input_pos_, result); 63 input_pos_ += result; 64 return result; 65 } else { 66 read_pending_ = true; 67 read_buffer_ = buf; 68 read_buffer_size_ = buf_len; 69 read_callback_ = callback; 70 return net::ERR_IO_PENDING; 71 } 72} 73 74int FakeSocket::Write(net::IOBuffer* buf, int buf_len, 75 const net::CompletionCallback& callback) { 76 DCHECK(buf); 77 DCHECK(!write_pending_); 78 79 if (async_write_) { 80 81 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind( 82 &FakeSocket::DoAsyncWrite, base::Unretained(this), 83 scoped_refptr<net::IOBuffer>(buf), buf_len, callback)); 84 write_pending_ = true; 85 return net::ERR_IO_PENDING; 86 } 87 88 if (written_data_) { 89 written_data_->insert(written_data_->end(), 90 buf->data(), buf->data() + buf_len); 91 } 92 return buf_len; 93} 94 95void FakeSocket::DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len, 96 const net::CompletionCallback& callback) { 97 write_pending_ = false; 98 99 if (written_data_) { 100 written_data_->insert(written_data_->end(), 101 buf->data(), buf->data() + buf_len); 102 } 103 callback.Run(buf_len); 104} 105 106int FakeSocket::SetReceiveBufferSize(int32 size) { 107 NOTIMPLEMENTED(); 108 return net::ERR_NOT_IMPLEMENTED; 109} 110 111int FakeSocket::SetSendBufferSize(int32 size) { 112 NOTIMPLEMENTED(); 113 return net::ERR_NOT_IMPLEMENTED; 114} 115 116int FakeSocket::Connect(const net::CompletionCallback& callback) { 117 return 0; 118} 119 120void FakeSocket::Disconnect() { 121 NOTREACHED(); 122} 123 124bool FakeSocket::IsConnected() const { 125 return true; 126} 127 128bool FakeSocket::IsConnectedAndIdle() const { 129 return false; 130} 131 132int FakeSocket::GetPeerAddress(net::IPEndPoint* address) const { 133 *address = peer_address_; 134 return net::OK; 135} 136 137int FakeSocket::GetLocalAddress(net::IPEndPoint* address) const { 138 *address = local_address_; 139 return net::OK; 140} 141 142const net::BoundNetLog& FakeSocket::NetLog() const { 143 NOTREACHED(); 144 return net_log_; 145} 146 147void FakeSocket::SetSubresourceSpeculation() { 148 NOTREACHED(); 149} 150 151void FakeSocket::SetOmniboxSpeculation() { 152 NOTREACHED(); 153} 154 155bool FakeSocket::WasEverUsed() const { 156 return true; 157} 158 159bool FakeSocket::UsingTCPFastOpen() const { 160 return false; 161} 162 163bool FakeSocket::WasNpnNegotiated() const { 164 return false; 165} 166 167net::NextProto FakeSocket::GetNegotiatedProtocol() const { 168 return net::kProtoUnknown; 169} 170 171bool FakeSocket::GetSSLInfo(net::SSLInfo* ssl_info) { 172 return false; 173} 174 175void CreateRandomPacket(std::vector<char>* packet) { 176 size_t size = kStunHeaderSize + rand() % 1000; 177 packet->resize(size); 178 for (size_t i = 0; i < size; i++) { 179 (*packet)[i] = rand() % 256; 180 } 181 // Always set the first bit to ensure that generated packet is not 182 // valid STUN packet. 183 (*packet)[0] = (*packet)[0] | 0x80; 184} 185 186static void CreateStunPacket(std::vector<char>* packet, uint16 type) { 187 CreateRandomPacket(packet); 188 *reinterpret_cast<uint16*>(&*packet->begin()) = base::HostToNet16(type); 189 *reinterpret_cast<uint16*>(&*packet->begin() + 2) = 190 base::HostToNet16(packet->size() - kStunHeaderSize); 191 *reinterpret_cast<uint32*>(&*packet->begin() + 4) = 192 base::HostToNet32(kStunMagicCookie); 193} 194 195void CreateStunRequest(std::vector<char>* packet) { 196 CreateStunPacket(packet, kStunBindingRequest); 197} 198 199void CreateStunResponse(std::vector<char>* packet) { 200 CreateStunPacket(packet, kStunBindingResponse); 201} 202 203void CreateStunError(std::vector<char>* packet) { 204 CreateStunPacket(packet, kStunBindingError); 205} 206 207net::IPEndPoint ParseAddress(const std::string ip_str, int port) { 208 net::IPAddressNumber ip; 209 EXPECT_TRUE(net::ParseIPLiteralToNumber(ip_str, &ip)); 210 return net::IPEndPoint(ip, port); 211} 212