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 12 const int kStunHeaderSize = 20; 13 const uint16 kStunBindingRequest = 0x0001; 14 const uint16 kStunBindingResponse = 0x0102; 15 const uint16 kStunBindingError = 0x0111; 16 const uint32 kStunMagicCookie = 0x2112A442; 17 18 MockIPCSender::MockIPCSender() { } 19 MockIPCSender::~MockIPCSender() { } 20 21 FakeSocket::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 29 FakeSocket::~FakeSocket() { } 30 31 void 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 48 void FakeSocket::SetPeerAddress(const net::IPEndPoint& peer_address) { 49 peer_address_ = peer_address; 50 } 51 52 void FakeSocket::SetLocalAddress(const net::IPEndPoint& local_address) { 53 local_address_ = local_address; 54 } 55 56 int 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 74 int 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 95 void 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 106 int FakeSocket::SetReceiveBufferSize(int32 size) { 107 NOTIMPLEMENTED(); 108 return net::ERR_NOT_IMPLEMENTED; 109 } 110 111 int FakeSocket::SetSendBufferSize(int32 size) { 112 NOTIMPLEMENTED(); 113 return net::ERR_NOT_IMPLEMENTED; 114 } 115 116 int FakeSocket::Connect(const net::CompletionCallback& callback) { 117 return 0; 118 } 119 120 void FakeSocket::Disconnect() { 121 NOTREACHED(); 122 } 123 124 bool FakeSocket::IsConnected() const { 125 return true; 126 } 127 128 bool FakeSocket::IsConnectedAndIdle() const { 129 return false; 130 } 131 132 int FakeSocket::GetPeerAddress(net::IPEndPoint* address) const { 133 *address = peer_address_; 134 return net::OK; 135 } 136 137 int FakeSocket::GetLocalAddress(net::IPEndPoint* address) const { 138 *address = local_address_; 139 return net::OK; 140 } 141 142 const net::BoundNetLog& FakeSocket::NetLog() const { 143 NOTREACHED(); 144 return net_log_; 145 } 146 147 void FakeSocket::SetSubresourceSpeculation() { 148 NOTREACHED(); 149 } 150 151 void FakeSocket::SetOmniboxSpeculation() { 152 NOTREACHED(); 153 } 154 155 bool FakeSocket::WasEverUsed() const { 156 return true; 157 } 158 159 bool FakeSocket::UsingTCPFastOpen() const { 160 return false; 161 } 162 163 bool FakeSocket::WasNpnNegotiated() const { 164 return false; 165 } 166 167 net::NextProto FakeSocket::GetNegotiatedProtocol() const { 168 return net::kProtoUnknown; 169 } 170 171 bool FakeSocket::GetSSLInfo(net::SSLInfo* ssl_info) { 172 return false; 173 } 174 175 void 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 186 static 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 195 void CreateStunRequest(std::vector<char>* packet) { 196 CreateStunPacket(packet, kStunBindingRequest); 197 } 198 199 void CreateStunResponse(std::vector<char>* packet) { 200 CreateStunPacket(packet, kStunBindingResponse); 201 } 202 203 void CreateStunError(std::vector<char>* packet) { 204 CreateStunPacket(packet, kStunBindingError); 205 } 206 207 net::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