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/logging.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/synchronization/lock.h" 13 #include "net/quic/quic_alarm.h" 14 #include "net/quic/quic_blocked_writer_interface.h" 15 #include "net/quic/quic_packet_writer.h" 16 #include "net/quic/test_tools/quic_test_writer.h" 17 #include "net/tools/quic/quic_epoll_clock.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 net::test::QuicTestWriter { 29 public: 30 PacketDroppingTestWriter(); 31 32 virtual ~PacketDroppingTestWriter(); 33 34 void SetConnectionHelper(QuicEpollConnectionHelper* helper); 35 36 // QuicPacketWriter methods: 37 virtual WriteResult WritePacket( 38 const char* buffer, size_t buf_len, 39 const IPAddressNumber& self_address, 40 const IPEndPoint& peer_address, 41 QuicBlockedWriterInterface* blocked_writer) OVERRIDE; 42 43 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE; 44 45 // Writes out any packet which should have been sent by now 46 // to the contained writer and returns the time 47 // for the next delayed packet to be written. 48 QuicTime ReleaseOldPackets(); 49 50 QuicBlockedWriterInterface* blocked_writer() { return blocked_writer_; } 51 52 // The percent of time a packet is simulated as being lost. 53 void set_fake_packet_loss_percentage(int32 fake_packet_loss_percentage) { 54 base::AutoLock locked(config_mutex_); 55 fake_packet_loss_percentage_ = fake_packet_loss_percentage; 56 } 57 58 // The percent of time WritePacket will block and set WriteResult's status 59 // to WRITE_STATUS_BLOCKED. 60 void set_fake_blocked_socket_percentage( 61 int32 fake_blocked_socket_percentage) { 62 DCHECK(clock_); 63 base::AutoLock locked(config_mutex_); 64 fake_blocked_socket_percentage_ = fake_blocked_socket_percentage; 65 } 66 67 // The percent of time a packet is simulated as being reordered. 68 void set_fake_reorder_percentage(int32 fake_packet_reorder_percentage) { 69 DCHECK(clock_); 70 base::AutoLock locked(config_mutex_); 71 DCHECK(!fake_packet_delay_.IsZero()); 72 fake_packet_reorder_percentage_ = fake_packet_reorder_percentage; 73 } 74 75 // The percent of time WritePacket will block and set WriteResult's status 76 // to WRITE_STATUS_BLOCKED. 77 void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) { 78 DCHECK(clock_); 79 base::AutoLock locked(config_mutex_); 80 fake_packet_delay_ = fake_packet_delay; 81 } 82 83 // The maximum bandwidth and buffer size of the connection. When these are 84 // set, packets will be delayed until a connection with that bandwidth would 85 // transmit it. Once the |buffer_size| is reached, all new packets are 86 // dropped. 87 void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth, 88 QuicByteCount buffer_size) { 89 DCHECK(clock_); 90 base::AutoLock locked(config_mutex_); 91 fake_bandwidth_ = fake_bandwidth; 92 buffer_size_ = buffer_size; 93 } 94 95 void set_seed(uint64 seed) { 96 simple_random_.set_seed(seed); 97 } 98 99 private: 100 // Writes out the next packet to the contained writer and returns the time 101 // for the next delayed packet to be written. 102 QuicTime ReleaseNextPacket(); 103 104 // A single packet which will be sent at the supplied send_time. 105 class DelayedWrite { 106 public: 107 DelayedWrite(const char* buffer, 108 size_t buf_len, 109 const IPAddressNumber& self_address, 110 const IPEndPoint& peer_address, 111 QuicTime send_time); 112 ~DelayedWrite(); 113 114 string buffer; 115 const IPAddressNumber self_address; 116 const IPEndPoint peer_address; 117 QuicTime send_time; 118 }; 119 120 typedef std::list<DelayedWrite> DelayedPacketList; 121 122 const QuicClock* clock_; 123 scoped_ptr<QuicAlarm> write_unblocked_alarm_; 124 scoped_ptr<QuicAlarm> delay_alarm_; 125 QuicBlockedWriterInterface* blocked_writer_; 126 SimpleRandom simple_random_; 127 // Stored packets delayed by fake packet delay or bandwidth restrictions. 128 DelayedPacketList delayed_packets_; 129 QuicByteCount cur_buffer_size_; 130 131 base::Lock config_mutex_; 132 int32 fake_packet_loss_percentage_; 133 int32 fake_blocked_socket_percentage_; 134 int32 fake_packet_reorder_percentage_; 135 QuicTime::Delta fake_packet_delay_; 136 QuicBandwidth fake_bandwidth_; 137 QuicByteCount buffer_size_; 138 139 DISALLOW_COPY_AND_ASSIGN(PacketDroppingTestWriter); 140 }; 141 142 } // namespace test 143 } // namespace tools 144 } // namespace net 145 146 #endif // NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_ 147