103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file.
403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// MSVC++ requires this to be set before any other includes to get M_PI.
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define _USE_MATH_DEFINES
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "remoting/test/fake_socket_factory.h"
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <math.h>
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/bind.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/callback.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/location.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/rand_util.h"
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/single_thread_task_runner.h"
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/thread_task_runner_handle.h"
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/base/io_buffer.h"
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "remoting/test/leaky_bucket.h"
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "third_party/webrtc/base/asyncpacketsocket.h"
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace remoting {
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace {
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const int kPortRangeStart = 1024;
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const int kPortRangeEnd = 65535;
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)double GetNormalRandom(double average, double stddev) {
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Based on Box-Muller transform, see
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // http://en.wikipedia.org/wiki/Box_Muller_transform .
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return average +
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         stddev * sqrt(-2.0 * log(1.0 - base::RandDouble())) *
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)             cos(base::RandDouble() * 2.0 * M_PI);
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class FakeUdpSocket : public rtc::AsyncPacketSocket {
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public:
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FakeUdpSocket(FakePacketSocketFactory* factory,
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                scoped_refptr<FakeNetworkDispatcher> dispatcher,
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                const rtc::SocketAddress& local_address);
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual ~FakeUdpSocket();
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void ReceivePacket(const rtc::SocketAddress& from,
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     const rtc::SocketAddress& to,
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     const scoped_refptr<net::IOBuffer>& data,
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     int data_size);
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // rtc::AsyncPacketSocket interface.
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual rtc::SocketAddress GetLocalAddress() const OVERRIDE;
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual rtc::SocketAddress GetRemoteAddress() const OVERRIDE;
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual int Send(const void* data, size_t data_size,
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   const rtc::PacketOptions& options) OVERRIDE;
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual int SendTo(const void* data, size_t data_size,
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     const rtc::SocketAddress& address,
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     const rtc::PacketOptions& options) OVERRIDE;
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual int Close() OVERRIDE;
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual State GetState() const OVERRIDE;
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual int GetOption(rtc::Socket::Option option, int* value) OVERRIDE;
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual int SetOption(rtc::Socket::Option option, int value) OVERRIDE;
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual int GetError() const OVERRIDE;
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void SetError(int error) OVERRIDE;
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FakePacketSocketFactory* factory_;
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<FakeNetworkDispatcher> dispatcher_;
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  rtc::SocketAddress local_address_;
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  State state_;
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeUdpSocket);
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakeUdpSocket::FakeUdpSocket(FakePacketSocketFactory* factory,
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             scoped_refptr<FakeNetworkDispatcher> dispatcher,
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             const rtc::SocketAddress& local_address)
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : factory_(factory),
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      dispatcher_(dispatcher),
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      local_address_(local_address),
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      state_(STATE_BOUND) {
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakeUdpSocket::~FakeUdpSocket() {
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  factory_->OnSocketDestroyed(local_address_.port());
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakeUdpSocket::ReceivePacket(const rtc::SocketAddress& from,
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  const rtc::SocketAddress& to,
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  const scoped_refptr<net::IOBuffer>& data,
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  int data_size) {
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SignalReadPacket(
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      this, data->data(), data_size, from, rtc::CreatePacketTime(0));
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)rtc::SocketAddress FakeUdpSocket::GetLocalAddress() const {
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return local_address_;
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)rtc::SocketAddress FakeUdpSocket::GetRemoteAddress() const {
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NOTREACHED();
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return rtc::SocketAddress();
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)int FakeUdpSocket::Send(const void* data, size_t data_size,
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                        const rtc::PacketOptions& options) {
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NOTREACHED();
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return EINVAL;
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)int FakeUdpSocket::SendTo(const void* data, size_t data_size,
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                          const rtc::SocketAddress& address,
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                          const rtc::PacketOptions& options) {
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_size);
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  memcpy(buffer->data(), data, data_size);
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  dispatcher_->DeliverPacket(local_address_, address, buffer, data_size);
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return data_size;
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)int FakeUdpSocket::Close() {
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  state_ = STATE_CLOSED;
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return 0;
12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)rtc::AsyncPacketSocket::State FakeUdpSocket::GetState() const {
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return state_;
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)int FakeUdpSocket::GetOption(rtc::Socket::Option option, int* value) {
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NOTIMPLEMENTED();
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return -1;
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)int FakeUdpSocket::SetOption(rtc::Socket::Option option, int value) {
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NOTIMPLEMENTED();
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return -1;
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)int FakeUdpSocket::GetError() const {
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return 0;
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakeUdpSocket::SetError(int error) {
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NOTREACHED();
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakePacketSocketFactory::PendingPacket::PendingPacket()
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : data_size(0) {
14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakePacketSocketFactory::PendingPacket::PendingPacket(
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::SocketAddress& from,
15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::SocketAddress& to,
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<net::IOBuffer>& data,
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int data_size)
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : from(from), to(to), data(data), data_size(data_size) {
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakePacketSocketFactory::PendingPacket::~PendingPacket() {
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakePacketSocketFactory::FakePacketSocketFactory(
16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    FakeNetworkDispatcher* dispatcher)
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : task_runner_(base::ThreadTaskRunnerHandle::Get()),
16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      dispatcher_(dispatcher),
16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      address_(dispatcher_->AllocateAddress()),
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      out_of_order_rate_(0.0),
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      next_port_(kPortRangeStart),
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      weak_factory_(this) {
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  dispatcher_->AddNode(this);
17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakePacketSocketFactory::~FakePacketSocketFactory() {
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CHECK(udp_sockets_.empty());
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  dispatcher_->RemoveNode(this);
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakePacketSocketFactory::OnSocketDestroyed(int port) {
17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  udp_sockets_.erase(port);
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakePacketSocketFactory::SetBandwidth(int bandwidth, int max_buffer) {
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (bandwidth <= 0) {
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    leaky_bucket_.reset();
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else {
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    leaky_bucket_.reset(new LeakyBucket(max_buffer, bandwidth));
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakePacketSocketFactory::SetLatency(base::TimeDelta average,
19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                         base::TimeDelta stddev) {
19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  latency_average_ = average;
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  latency_stddev_ = stddev;
19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)rtc::AsyncPacketSocket* FakePacketSocketFactory::CreateUdpSocket(
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::SocketAddress& local_address,
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int min_port, int max_port) {
20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int port = -1;
20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (min_port > 0 && max_port > 0) {
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    for (int i = min_port; i <= max_port; ++i) {
20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      if (udp_sockets_.find(i) == udp_sockets_.end()) {
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        port = i;
20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        break;
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      }
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (port < 0)
21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return NULL;
21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else {
21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    do {
21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      port = next_port_;
21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      next_port_ =
21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          (next_port_ >= kPortRangeEnd) ? kPortRangeStart : (next_port_ + 1);
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    } while (udp_sockets_.find(port) != udp_sockets_.end());
22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CHECK(local_address.ipaddr() == address_);
22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FakeUdpSocket* result =
22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      new FakeUdpSocket(this, dispatcher_,
22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                        rtc::SocketAddress(local_address.ipaddr(), port));
22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  udp_sockets_[port] =
22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakeUdpSocket::ReceivePacket, base::Unretained(result));
23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return result;
23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)rtc::AsyncPacketSocket* FakePacketSocketFactory::CreateServerTcpSocket(
23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::SocketAddress& local_address,
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int min_port, int max_port,
23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int opts) {
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return NULL;
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)rtc::AsyncPacketSocket* FakePacketSocketFactory::CreateClientTcpSocket(
24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::SocketAddress& local_address,
24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::SocketAddress& remote_address,
24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::ProxyInfo& proxy_info,
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const std::string& user_agent,
24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int opts) {
24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return NULL;
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)rtc::AsyncResolverInterface*
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakePacketSocketFactory::CreateAsyncResolver() {
25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return NULL;
25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const scoped_refptr<base::SingleThreadTaskRunner>&
25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FakePacketSocketFactory::GetThread() const {
25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return task_runner_;
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const rtc::IPAddress& FakePacketSocketFactory::GetAddress() const {
26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return address_;
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakePacketSocketFactory::ReceivePacket(
26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::SocketAddress& from,
26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const rtc::SocketAddress& to,
26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<net::IOBuffer>& data,
26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int data_size) {
26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(to.ipaddr() == address_);
27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::TimeDelta delay;
27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (leaky_bucket_) {
27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    delay = leaky_bucket_->AddPacket(data_size);
27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (delay.is_max()) {
27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // Drop the packet.
27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return;
27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (latency_average_ > base::TimeDelta()) {
28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    delay += base::TimeDelta::FromMillisecondsD(
28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GetNormalRandom(latency_average_.InMillisecondsF(),
28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                        latency_stddev_.InMillisecondsF()));
28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (delay < base::TimeDelta())
28803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    delay = base::TimeDelta();
28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Put the packet to the |pending_packets_| and post a task for
29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // DoReceivePackets(). Note that the DoReceivePackets() task posted here may
29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // deliver a different packet, not the one added to the queue here. This
29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // would happen if another task gets posted with a shorted delay or when
29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |out_of_order_rate_| is greater than 0. It's implemented this way to
29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // decouple latency variability from out-of-order delivery.
29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  PendingPacket packet(from, to, data, data_size);
29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  pending_packets_.push_back(packet);
29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  task_runner_->PostDelayedTask(
29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&FakePacketSocketFactory::DoReceivePacket,
30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 weak_factory_.GetWeakPtr()),
30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      delay);
30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FakePacketSocketFactory::DoReceivePacket() {
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  PendingPacket packet;
30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (pending_packets_.size() > 1 && base::RandDouble() < out_of_order_rate_) {
31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::list<PendingPacket>::iterator it = pending_packets_.begin();
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ++it;
31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    packet = *it;
31303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    pending_packets_.erase(it);
31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else {
31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    packet = pending_packets_.front();
31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    pending_packets_.pop_front();
31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  UdpSocketsMap::iterator iter = udp_sockets_.find(packet.to.port());
32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (iter == udp_sockets_.end()) {
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Invalid port number.
32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return;
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  iter->second.Run(packet.from, packet.to, packet.data, packet.data_size);
32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace remoting
329