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