11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file. 41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifndef NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_ 61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_ 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <list> 91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h" 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/logging.h" 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/synchronization/lock.h" 141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/quic/quic_alarm.h" 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h" 161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/tools/quic/quic_epoll_clock.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/tools/quic/quic_packet_writer_wrapper.h" 181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/tools/quic/test_tools/quic_test_client.h" 191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/tools/quic/test_tools/quic_test_utils.h" 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace net { 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace tools { 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace test { 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Simulates a connection that drops packets a configured percentage of the time 261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// and has a blocked socket a configured percentage of the time. Also provides 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// the options to delay packets and reorder packets if delay is enabled. 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PacketDroppingTestWriter : public QuicPacketWriterWrapper { 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class Delegate { 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~Delegate() {} 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual void OnPacketSent(WriteResult result) = 0; 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnCanWrite() = 0; 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) PacketDroppingTestWriter(); 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual ~PacketDroppingTestWriter(); 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Must be called before blocking, reordering or delaying (loss is OK). May be 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // called after connecting if the helper is not available before. 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |on_can_write| will be triggered when fake-unblocking; ownership will be 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // assumed. 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Initialize(QuicEpollConnectionHelper* helper, Delegate* on_can_write); 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // QuicPacketWriter methods: 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual WriteResult WritePacket( 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* buffer, 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t buf_len, 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const IPAddressNumber& self_address, 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const IPEndPoint& peer_address) OVERRIDE; 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool IsWriteBlocked() const OVERRIDE; 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SetWritable() OVERRIDE; 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Writes out any packet which should have been sent by now 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // to the contained writer and returns the time 601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // for the next delayed packet to be written. 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicTime ReleaseOldPackets(); 621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnCanWrite(); 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The percent of time a packet is simulated as being lost. 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void set_fake_packet_loss_percentage(int32 fake_packet_loss_percentage) { 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::AutoLock locked(config_mutex_); 681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fake_packet_loss_percentage_ = fake_packet_loss_percentage; 691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The percent of time WritePacket will block and set WriteResult's status 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // to WRITE_STATUS_BLOCKED. 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void set_fake_blocked_socket_percentage( 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int32 fake_blocked_socket_percentage) { 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(clock_); 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::AutoLock locked(config_mutex_); 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fake_blocked_socket_percentage_ = fake_blocked_socket_percentage; 781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The percent of time a packet is simulated as being reordered. 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void set_fake_reorder_percentage(int32 fake_packet_reorder_percentage) { 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(clock_); 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::AutoLock locked(config_mutex_); 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!fake_packet_delay_.IsZero()); 851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fake_packet_reorder_percentage_ = fake_packet_reorder_percentage; 861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The percent of time WritePacket will block and set WriteResult's status 891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // to WRITE_STATUS_BLOCKED. 901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) { 911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(clock_); 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::AutoLock locked(config_mutex_); 931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fake_packet_delay_ = fake_packet_delay; 941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The maximum bandwidth and buffer size of the connection. When these are 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // set, packets will be delayed until a connection with that bandwidth would 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // transmit it. Once the |buffer_size| is reached, all new packets are 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // dropped. 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth, 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicByteCount buffer_size) { 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(clock_); 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::AutoLock locked(config_mutex_); 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fake_bandwidth_ = fake_bandwidth; 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer_size_ = buffer_size; 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void set_seed(uint64 seed) { 1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) simple_random_.set_seed(seed); 1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private: 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Writes out the next packet to the contained writer and returns the time 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // for the next delayed packet to be written. 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicTime ReleaseNextPacket(); 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // A single packet which will be sent at the supplied send_time. 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct DelayedWrite { 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DelayedWrite(const char* buffer, 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t buf_len, 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const IPAddressNumber& self_address, 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const IPEndPoint& peer_address, 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) QuicTime send_time); 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ~DelayedWrite(); 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) string buffer; 1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const IPAddressNumber self_address; 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const IPEndPoint peer_address; 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) QuicTime send_time; 1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }; 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) typedef std::list<DelayedWrite> DelayedPacketList; 1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const QuicClock* clock_; 1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<QuicAlarm> write_unblocked_alarm_; 1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<QuicAlarm> delay_alarm_; 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<Delegate> on_can_write_; 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) net::test::SimpleRandom simple_random_; 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stored packets delayed by fake packet delay or bandwidth restrictions. 1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DelayedPacketList delayed_packets_; 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicByteCount cur_buffer_size_; 1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Lock config_mutex_; 1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int32 fake_packet_loss_percentage_; 1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int32 fake_blocked_socket_percentage_; 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int32 fake_packet_reorder_percentage_; 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) QuicTime::Delta fake_packet_delay_; 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicBandwidth fake_bandwidth_; 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicByteCount buffer_size_; 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PacketDroppingTestWriter); 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}; 1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} // namespace test 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} // namespace tools 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} // namespace net 1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif // NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_ 160