xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/test_tools/simulator/switch.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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