Home | History | Annotate | Download | only in utility
      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