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