1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_TEST_FAKE_SOCKET_FACTORY_H_
#define REMOTING_TEST_FAKE_SOCKET_FACTORY_H_
#include <stdint.h>
#include <list>
#include <memory>
#include "base/compiler_specific.h"
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "remoting/test/fake_network_dispatcher.h"
#include "third_party/webrtc/api/packet_socket_factory.h"
namespace remoting {
class FakeNetworkDispatcher;
class LeakyBucket;
class FakePacketSocketFactory : public webrtc::PacketSocketFactory,
public FakeNetworkDispatcher::Node {
public:
// |dispatcher| must outlive the factory.
explicit FakePacketSocketFactory(FakeNetworkDispatcher* dispatcher);
FakePacketSocketFactory(const FakePacketSocketFactory&) = delete;
FakePacketSocketFactory& operator=(const FakePacketSocketFactory&) = delete;
~FakePacketSocketFactory() override;
void OnSocketDestroyed(int port);
// |bandwidth| - simulated link bandwidth in bytes/second. 0 indicates that
// bandwidth is unlimited.
// |max_buffer| - size of buffers in bytes. Ignored when |bandwidth| is 0.
void SetBandwidth(int bandwidth, int max_buffer);
// Specifies parameters for simulated network latency. Latency is generated
// with normal distribution around |average| with the given |stddev|. Random
// latency calculated based on these parameters is added to the buffering
// delay (which is calculated based on the parameters passed to
// SetBandwidth()). I.e. total latency for each packet is calculated using the
// following formula
//
// l = NormalRand(average, stddev) + bytes_buffered / bandwidth .
//
// Where bytes_buffered is the current level in the leaky bucket used to
// control bandwidth.
void SetLatency(base::TimeDelta average, base::TimeDelta stddev);
void set_out_of_order_rate(double out_of_order_rate) {
out_of_order_rate_ = out_of_order_rate;
}
void ResetStats();
base::TimeDelta average_buffer_delay() {
return total_packets_received_ > 0
? (total_buffer_delay_ / total_packets_received_)
: base::TimeDelta();
}
base::TimeDelta max_buffer_delay() { return max_buffer_delay_; }
double drop_rate() {
return static_cast<double>(total_packets_dropped_) /
(total_packets_received_ + total_packets_dropped_);
}
// webrtc::PacketSocketFactory interface.
webrtc::AsyncPacketSocket* CreateUdpSocket(
const webrtc::SocketAddress& local_address,
uint16_t min_port,
uint16_t max_port) override;
webrtc::AsyncListenSocket* CreateServerTcpSocket(
const webrtc::SocketAddress& local_address,
uint16_t min_port,
uint16_t max_port,
int opts) override;
webrtc::AsyncPacketSocket* CreateClientTcpSocket(
const webrtc::SocketAddress& local_address,
const webrtc::SocketAddress& remote_address,
const webrtc::PacketSocketTcpOptions& opts) override;
std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAsyncDnsResolver()
override;
// FakeNetworkDispatcher::Node interface.
const scoped_refptr<base::SingleThreadTaskRunner>& GetThread() const override;
const webrtc::IPAddress& GetAddress() const override;
void ReceivePacket(const webrtc::SocketAddress& from,
const webrtc::SocketAddress& to,
const scoped_refptr<net::IOBuffer>& data,
int data_size) override;
private:
struct PendingPacket {
PendingPacket();
PendingPacket(const webrtc::SocketAddress& from,
const webrtc::SocketAddress& to,
const scoped_refptr<net::IOBuffer>& data,
int data_size);
PendingPacket(const PendingPacket& other);
~PendingPacket();
webrtc::SocketAddress from;
webrtc::SocketAddress to;
scoped_refptr<net::IOBuffer> data;
int data_size;
};
using ReceiveCallback =
base::RepeatingCallback<void(const webrtc::SocketAddress& from,
const webrtc::SocketAddress& to,
const scoped_refptr<net::IOBuffer>& data,
int data_size)>;
typedef std::map<uint16_t, ReceiveCallback> UdpSocketsMap;
void DoReceivePacket();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<FakeNetworkDispatcher> dispatcher_;
webrtc::IPAddress address_;
std::unique_ptr<LeakyBucket> leaky_bucket_;
base::TimeDelta latency_average_;
base::TimeDelta latency_stddev_;
double out_of_order_rate_;
UdpSocketsMap udp_sockets_;
uint16_t next_port_;
std::list<PendingPacket> pending_packets_;
int total_packets_received_ = 0;
int total_packets_dropped_ = 0;
base::TimeDelta total_buffer_delay_;
base::TimeDelta max_buffer_delay_;
base::WeakPtrFactory<FakePacketSocketFactory> weak_factory_{this};
};
} // namespace remoting
#endif // REMOTING_TEST_FAKE_SOCKET_FACTORY_H_
|