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_SWITCH_H_ 6 #define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_ 7 8 #include <deque> 9 10 #include "absl/container/flat_hash_map.h" 11 #include "quiche/quic/test_tools/simulator/queue.h" 12 13 namespace quic { 14 namespace simulator { 15 16 using SwitchPortNumber = size_t; 17 18 // Simulates a network switch with simple persistent learning scheme and queues 19 // on every output port. 20 class Switch { 21 public: 22 Switch(Simulator* simulator, std::string name, SwitchPortNumber port_count, 23 QuicByteCount queue_capacity); 24 Switch(const Switch&) = delete; 25 Switch& operator=(const Switch&) = delete; 26 ~Switch(); 27 28 // Returns Endpoint associated with the port under number |port_number|. Just 29 // like on most real switches, port numbering starts with 1. port(SwitchPortNumber port_number)30 Endpoint* port(SwitchPortNumber port_number) { 31 QUICHE_DCHECK_NE(port_number, 0u); 32 return &ports_[port_number - 1]; 33 } 34 port_queue(SwitchPortNumber port_number)35 Queue* port_queue(SwitchPortNumber port_number) { 36 return ports_[port_number - 1].queue(); 37 } 38 39 private: 40 class Port : public Endpoint, public UnconstrainedPortInterface { 41 public: 42 Port(Simulator* simulator, std::string name, Switch* parent, 43 SwitchPortNumber port_number, QuicByteCount queue_capacity); 44 Port(Port&&) = delete; 45 Port(const Port&) = delete; 46 Port& operator=(const Port&) = delete; ~Port()47 ~Port() override {} 48 49 // Accepts packet to be routed into the switch. 50 void AcceptPacket(std::unique_ptr<Packet> packet) override; 51 // Enqueue packet to be routed out of the switch. 52 void EnqueuePacket(std::unique_ptr<Packet> packet); 53 54 UnconstrainedPortInterface* GetRxPort() override; 55 void SetTxPort(ConstrainedPortInterface* port) override; 56 57 void Act() override; 58 connected()59 bool connected() const { return connected_; } queue()60 Queue* queue() { return &queue_; } 61 62 private: 63 Switch* parent_; 64 SwitchPortNumber port_number_; 65 bool connected_; 66 67 Queue queue_; 68 }; 69 70 // Sends the packet to the appropriate port, or to all ports if the 71 // appropriate port is not known. 72 void DispatchPacket(SwitchPortNumber port_number, 73 std::unique_ptr<Packet> packet); 74 75 // This cannot be a quiche::QuicheCircularDeque since pointers into this are 76 // assumed to be stable. 77 std::deque<Port> ports_; 78 absl::flat_hash_map<std::string, Port*> switching_table_; 79 }; 80 81 } // namespace simulator 82 } // namespace quic 83 84 #endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_ 85