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