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