udp_proxy.h revision effb81e5f8246d0db0270817048dc992db66e9fb
1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#ifndef MEDIA_CAST_TEST_UTILITY_UDP_PROXY_H_
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#define MEDIA_CAST_TEST_UTILITY_UDP_PROXY_H_
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <vector>
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/basictypes.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/memory/ref_counted.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/memory/scoped_ptr.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "net/base/ip_endpoint.h"
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace net {
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass NetLog;
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace media {
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace cast {
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace test {
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// A single UDP packet.
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Technically, our UDP proxy should really chop UDP packets
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// into MTU-sized chunks and then do all the horribly things it
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// does to those chunks, but since cast *should* normally only
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// send packets that are sized below the MTU limit, we should
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// be able to ignore that.
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstruct Packet : public base::RefCountedThreadSafe<Packet> {
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  explicit Packet(size_t size);
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<unsigned char> data;
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  friend class base::RefCountedThreadSafe<Packet>;
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ~Packet();
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass PacketPipe {
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PacketPipe();
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual ~PacketPipe();
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void Send(scoped_refptr<Packet> packet) = 0;
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void InitOnIOThread();
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void AppendToPipe(scoped_ptr<PacketPipe> pipe);
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch protected:
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<PacketPipe> pipe_;
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// A UDPProxy will set up a UDP socket and bind to |local_port|.
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Packets send to that port will be forwarded to |destination|.
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Packets send from |destination| to |local_port| will be returned
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// to whoever sent a packet to |local_port| last. (Not counting packets
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// from |destination|.) The UDPProxy will run a separate thread to
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// do the forwarding of packets, and will keep doing so until destroyed.
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// You can insert delays and packet drops by supplying a PacketPipe.
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// The PacketPipes may also be NULL if you just want to forward packets.
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass UDPProxy {
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual ~UDPProxy() {}
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static scoped_ptr<UDPProxy> Create(const net::IPEndPoint& local_port,
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     const net::IPEndPoint& destination,
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     scoped_ptr<PacketPipe> to_dest_pipe,
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     scoped_ptr<PacketPipe> from_dest_pipe,
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     net::NetLog* net_log);
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// The following functions create PacketPipes which can be linked
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// together (with AppendToPipe) and passed into UdpProxy::Create below.
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This PacketPipe emulates a buffer of a given size. Limits our output
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// from the buffer at a rate given by |bandwidth| (in megabits per second).
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Packets entering the buffer will be dropped if there is not enough
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// room for them.
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<PacketPipe> NewBuffer(size_t buffer_size, double bandwidth);
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Randomly drops |drop_fraction|*100% of packets.
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<PacketPipe> NewRandomDrop(double drop_fraction);
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Delays each packet by |delay_seconds|.
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<PacketPipe> NewConstantDelay(double delay_seconds);
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Delays packets by a random amount between zero and |delay|.
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This PacketPipe can reorder packets.
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<PacketPipe> NewRandomUnsortedDelay(double delay);
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This PacketPipe inserts a random delay between each packet.
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This PacketPipe cannot re-order packets. The delay between each
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// packet is asically |min_delay| + random( |random_delay| )
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// However, every now and then a delay of |big_delay| will be
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// inserted (roughly every |seconds_between_big_delay| seconds).
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<PacketPipe> NewRandomSortedDelay(double random_delay,
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                            double big_delay,
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                            double seconds_between_big_delay);
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This PacketPipe emulates network outages. It basically waits
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// for 0-2*|average_work_time| seconds, then kills the network for
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// 0-|2*average_outage_time| seconds. Then it starts over again.
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<PacketPipe> NewNetworkGlitchPipe(double average_work_time,
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                            double average_outage_time);
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This method builds a stack of PacketPipes to emulate a reasonably
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// good wifi network. ~5mbit, 1% packet loss, ~3ms latency.
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<PacketPipe> WifiNetwork();
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This method builds a stack of PacketPipes to emulate a crappy wifi network.
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// ~1mbit, 20% packet loss, ~40ms latency and packets can get reordered.
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<PacketPipe> EvilNetwork();
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace test
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace cast
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace media
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif  // MEDIA_CAST_TEST_UTILITY_UDP_PROXY_H_
115