• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
6 #define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
7 
8 #include <list>
9 
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/synchronization/lock.h"
14 #include "net/quic/quic_alarm.h"
15 #include "net/quic/test_tools/quic_test_utils.h"
16 #include "net/tools/quic/quic_epoll_clock.h"
17 #include "net/tools/quic/quic_packet_writer_wrapper.h"
18 #include "net/tools/quic/test_tools/quic_test_client.h"
19 #include "net/tools/quic/test_tools/quic_test_utils.h"
20 
21 namespace net {
22 namespace tools {
23 namespace test {
24 
25 // Simulates a connection that drops packets a configured percentage of the time
26 // and has a blocked socket a configured percentage of the time.  Also provides
27 // the options to delay packets and reorder packets if delay is enabled.
28 class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
29  public:
30   class Delegate {
31    public:
~Delegate()32     virtual ~Delegate() {}
33     virtual void OnCanWrite() = 0;
34   };
35 
36   PacketDroppingTestWriter();
37 
38   virtual ~PacketDroppingTestWriter();
39 
40   // Must be called before blocking, reordering or delaying (loss is OK). May be
41   // called after connecting if the helper is not available before.
42   // |on_can_write| will be triggered when fake-unblocking; ownership will be
43   // assumed.
44   void Initialize(QuicEpollConnectionHelper* helper, Delegate* on_can_write);
45 
46   // QuicPacketWriter methods:
47   virtual WriteResult WritePacket(
48       const char* buffer,
49       size_t buf_len,
50       const IPAddressNumber& self_address,
51       const IPEndPoint& peer_address) OVERRIDE;
52 
53   virtual bool IsWriteBlocked() const OVERRIDE;
54 
55   virtual void SetWritable() OVERRIDE;
56 
57   // Writes out any packet which should have been sent by now
58   // to the contained writer and returns the time
59   // for the next delayed packet to be written.
60   QuicTime ReleaseOldPackets();
61 
62   void OnCanWrite();
63 
64   // The percent of time a packet is simulated as being lost.
set_fake_packet_loss_percentage(int32 fake_packet_loss_percentage)65   void set_fake_packet_loss_percentage(int32 fake_packet_loss_percentage) {
66     base::AutoLock locked(config_mutex_);
67     fake_packet_loss_percentage_ = fake_packet_loss_percentage;
68   }
69 
70   // The percent of time WritePacket will block and set WriteResult's status
71   // to WRITE_STATUS_BLOCKED.
set_fake_blocked_socket_percentage(int32 fake_blocked_socket_percentage)72   void set_fake_blocked_socket_percentage(
73       int32 fake_blocked_socket_percentage) {
74     DCHECK(clock_);
75     base::AutoLock locked(config_mutex_);
76     fake_blocked_socket_percentage_  = fake_blocked_socket_percentage;
77   }
78 
79   // The percent of time a packet is simulated as being reordered.
set_fake_reorder_percentage(int32 fake_packet_reorder_percentage)80   void set_fake_reorder_percentage(int32 fake_packet_reorder_percentage) {
81     DCHECK(clock_);
82     base::AutoLock locked(config_mutex_);
83     DCHECK(!fake_packet_delay_.IsZero());
84     fake_packet_reorder_percentage_ = fake_packet_reorder_percentage;
85   }
86 
87   // The percent of time WritePacket will block and set WriteResult's status
88   // to WRITE_STATUS_BLOCKED.
set_fake_packet_delay(QuicTime::Delta fake_packet_delay)89   void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
90     DCHECK(clock_);
91     base::AutoLock locked(config_mutex_);
92     fake_packet_delay_  = fake_packet_delay;
93   }
94 
95   // The maximum bandwidth and buffer size of the connection.  When these are
96   // set, packets will be delayed until a connection with that bandwidth would
97   // transmit it.  Once the |buffer_size| is reached, all new packets are
98   // dropped.
set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth,QuicByteCount buffer_size)99   void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth,
100                                          QuicByteCount buffer_size) {
101     DCHECK(clock_);
102     base::AutoLock locked(config_mutex_);
103     fake_bandwidth_ = fake_bandwidth;
104     buffer_size_ = buffer_size;
105   }
106 
set_seed(uint64 seed)107   void set_seed(uint64 seed) {
108     simple_random_.set_seed(seed);
109   }
110 
111  private:
112   // Writes out the next packet to the contained writer and returns the time
113   // for the next delayed packet to be written.
114   QuicTime ReleaseNextPacket();
115 
116   // A single packet which will be sent at the supplied send_time.
117   struct DelayedWrite {
118    public:
119     DelayedWrite(const char* buffer,
120                  size_t buf_len,
121                  const IPAddressNumber& self_address,
122                  const IPEndPoint& peer_address,
123                  QuicTime send_time);
124     ~DelayedWrite();
125 
126     string buffer;
127     const IPAddressNumber self_address;
128     const IPEndPoint peer_address;
129     QuicTime send_time;
130   };
131 
132   typedef std::list<DelayedWrite> DelayedPacketList;
133 
134   const QuicClock* clock_;
135   scoped_ptr<QuicAlarm> write_unblocked_alarm_;
136   scoped_ptr<QuicAlarm> delay_alarm_;
137   scoped_ptr<Delegate> on_can_write_;
138   net::test::SimpleRandom simple_random_;
139   // Stored packets delayed by fake packet delay or bandwidth restrictions.
140   DelayedPacketList delayed_packets_;
141   QuicByteCount cur_buffer_size_;
142 
143   base::Lock config_mutex_;
144   int32 fake_packet_loss_percentage_;
145   int32 fake_blocked_socket_percentage_;
146   int32 fake_packet_reorder_percentage_;
147   QuicTime::Delta fake_packet_delay_;
148   QuicBandwidth fake_bandwidth_;
149   QuicByteCount buffer_size_;
150 
151   DISALLOW_COPY_AND_ASSIGN(PacketDroppingTestWriter);
152 };
153 
154 }  // namespace test
155 }  // namespace tools
156 }  // namespace net
157 
158 #endif  // NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
159