1 // Copyright (c) 2012 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 QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_ 6 #define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_ 7 8 #include <memory> 9 10 #include "absl/container/flat_hash_map.h" 11 #include "quiche/quic/core/crypto/null_decrypter.h" 12 #include "quiche/quic/core/crypto/null_encrypter.h" 13 #include "quiche/quic/core/quic_connection.h" 14 #include "quiche/quic/core/quic_packet_writer.h" 15 #include "quiche/quic/core/quic_packets.h" 16 #include "quiche/quic/core/quic_stream_frame_data_producer.h" 17 #include "quiche/quic/core/quic_trace_visitor.h" 18 #include "quiche/quic/test_tools/mock_connection_id_generator.h" 19 #include "quiche/quic/test_tools/simple_session_notifier.h" 20 #include "quiche/quic/test_tools/simulator/link.h" 21 #include "quiche/quic/test_tools/simulator/queue.h" 22 23 namespace quic { 24 namespace simulator { 25 26 // Size of the TX queue used by the kernel/NIC. 1000 is the Linux 27 // kernel default. 28 const QuicByteCount kTxQueueSize = 1000; 29 30 // Generate a random local network host-port tuple based on the name of the 31 // endpoint. 32 QuicSocketAddress GetAddressFromName(std::string name); 33 34 // A QUIC connection endpoint. If the specific data transmitted does not matter 35 // (e.g. for congestion control purposes), QuicEndpoint is the subclass that 36 // transmits dummy data. If the actual semantics of the connection matter, 37 // subclassing QuicEndpointBase is required. 38 class QuicEndpointBase : public Endpoint, 39 public UnconstrainedPortInterface, 40 public Queue::ListenerInterface { 41 public: 42 // Does not create the connection; the subclass has to create connection by 43 // itself. 44 QuicEndpointBase(Simulator* simulator, std::string name, 45 std::string peer_name); 46 ~QuicEndpointBase() override; 47 connection()48 QuicConnection* connection() { return connection_.get(); } write_blocked_count()49 size_t write_blocked_count() { return write_blocked_count_; } 50 51 // Drop the next packet upon receipt. 52 void DropNextIncomingPacket(); 53 54 // UnconstrainedPortInterface method. Called whenever the endpoint receives a 55 // packet. 56 void AcceptPacket(std::unique_ptr<Packet> packet) override; 57 58 // Enables logging of the connection trace at the end of the unit test. 59 void RecordTrace(); 60 61 // Begin Endpoint implementation. 62 UnconstrainedPortInterface* GetRxPort() override; 63 void SetTxPort(ConstrainedPortInterface* port) override; 64 // End Endpoint implementation. 65 66 // Actor method. Act()67 void Act() override {} 68 69 // Queue::ListenerInterface method. 70 void OnPacketDequeued() override; 71 72 protected: 73 // A Writer object that writes into the |nic_tx_queue_|. 74 class Writer : public QuicPacketWriter { 75 public: 76 explicit Writer(QuicEndpointBase* endpoint); 77 ~Writer() override; 78 79 WriteResult WritePacket(const char* buffer, size_t buf_len, 80 const QuicIpAddress& self_address, 81 const QuicSocketAddress& peer_address, 82 PerPacketOptions* options, 83 const QuicPacketWriterParams& params) override; 84 bool IsWriteBlocked() const override; 85 void SetWritable() override; 86 std::optional<int> MessageTooBigErrorCode() const override; 87 QuicByteCount GetMaxPacketSize( 88 const QuicSocketAddress& peer_address) const override; 89 bool SupportsReleaseTime() const override; 90 bool IsBatchMode() const override; SupportsEcn()91 bool SupportsEcn() const override { return false; } 92 QuicPacketBuffer GetNextWriteLocation( 93 const QuicIpAddress& self_address, 94 const QuicSocketAddress& peer_address) override; 95 WriteResult Flush() override; 96 97 private: 98 QuicEndpointBase* endpoint_; 99 100 bool is_blocked_; 101 }; 102 103 // The producer outputs the repetition of the same byte. That sequence is 104 // verified by the receiver. 105 class DataProducer : public QuicStreamFrameDataProducer { 106 public: 107 WriteStreamDataResult WriteStreamData(QuicStreamId id, 108 QuicStreamOffset offset, 109 QuicByteCount data_length, 110 QuicDataWriter* writer) override; 111 bool WriteCryptoData(EncryptionLevel level, QuicStreamOffset offset, 112 QuicByteCount data_length, 113 QuicDataWriter* writer) override; 114 }; 115 116 std::string peer_name_; 117 118 Writer writer_; 119 // The queue for the outgoing packets. In reality, this might be either on 120 // the network card, or in the kernel, but for concreteness we assume it's on 121 // the network card. 122 Queue nic_tx_queue_; 123 // Created by the subclass. 124 std::unique_ptr<QuicConnection> connection_; 125 126 // Counts the number of times the writer became write-blocked. 127 size_t write_blocked_count_; 128 129 // If true, drop the next packet when receiving it. 130 bool drop_next_packet_; 131 132 std::unique_ptr<QuicTraceVisitor> trace_visitor_; 133 134 test::MockConnectionIdGenerator connection_id_generator_; 135 }; 136 137 // Multiplexes multiple connections at the same host on the network. 138 class QuicEndpointMultiplexer : public Endpoint, 139 public UnconstrainedPortInterface { 140 public: 141 QuicEndpointMultiplexer(std::string name, 142 const std::vector<QuicEndpointBase*>& endpoints); 143 ~QuicEndpointMultiplexer() override; 144 145 // Receives a packet and passes it to the specified endpoint if that endpoint 146 // is one of the endpoints being multiplexed, otherwise ignores the packet. 147 void AcceptPacket(std::unique_ptr<Packet> packet) override; 148 UnconstrainedPortInterface* GetRxPort() override; 149 150 // Sets the egress port for all the endpoints being multiplexed. 151 void SetTxPort(ConstrainedPortInterface* port) override; 152 Act()153 void Act() override {} 154 155 private: 156 absl::flat_hash_map<std::string, QuicEndpointBase*> mapping_; 157 }; 158 159 } // namespace simulator 160 } // namespace quic 161 162 #endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_ 163