Index: net/quic/core/congestion_control/simulation/README.md |
diff --git a/net/quic/core/congestion_control/simulation/README.md b/net/quic/core/congestion_control/simulation/README.md |
new file mode 100644 |
index 0000000000000000000000000000000000000000..02ffa0a1c37a509b60049dc9ab07b47721da0ded |
--- /dev/null |
+++ b/net/quic/core/congestion_control/simulation/README.md |
@@ -0,0 +1,98 @@ |
+# QUIC network simulator |
+ |
+This directory contains a discrete event network simulator which QUIC code uses |
+for testing congestion control and other transmission control code that requires |
+a network simulation for tests on QuicConnection level of abstraction. |
+ |
+## Actors |
+ |
+The core of the simulator is the Simulator class, which maintains a virtual |
+clock and an event queue. Any object in a simulation that needs to schedule |
+events has to subclass Actor. Subclassing Actor involves: |
+ |
+1. Calling the `Actor::Actor(Simulator*, std::string)` constructor to establish |
+ the name of the object and the simulator it is associated with. |
+2. Calling `Schedule(QuicTime)` to schedule the time at which `Act()` method is |
+ called. `Schedule` will only cause the object to be rescheduled if the time |
+ for which it is currently scheduled is later than the new time. |
+3. Implementing `Act()` method with the relevant logic. The actor will be |
+ removed from the event queue right before `Act()` is called. |
+ |
+Here is a simple example of an object that outputs simulation time into the log |
+every 100 ms. |
+ |
+```c++ |
+class LogClock : public Actor { |
+ public: |
+ LogClock(Simulator* simulator, std::string name) : Actor(simulator, name) { |
+ Schedule(clock_->Now()); |
+ } |
+ ~LogClock() override {} |
+ |
+ void Act() override { |
+ VLOG(1) << "The current time is " << clock_->Now().ToDebuggingValue(); |
+ Schedule(clock_->Now() + QuicTime::Delta::FromMilliseconds(100)); |
+ } |
+}; |
+``` |
+ |
+A QuicAlarm object can be used to schedule events in the simulation using |
+`Simulator::GetAlarmFactory()`. |
+ |
+## Ports |
+ |
+The simulated network transfers packets, which are modelled as an instance of |
+struct `Packet`. A packet consists of source and destination address (which are |
+just plain strings), a transmission timestamp and the UDP-layer payload. |
+ |
+The simulation uses the push model: any object that wishes to transfer a packet |
+to another component in the simulation has to explicitly do it itself. Any |
+object that can accept a packet is called a *port*. There are two types of |
+ports: unconstrained ports, which can always accept packets, and constrained |
+ports, which signal when they can accept a new packet. |
+ |
+An endpoint is an object that is connected to the network and can both receive |
+and send packets. In our model, the endpoint always receives packets as an |
+unconstrained port (*RX port*), and always writes packets to a constrained port |
+(*TX port*). |
+ |
+## Links |
+ |
+The `SymmetricLink` class models a symmetric duplex links with finite bandwidth |
+and propagation delay. It consists of a pair of identical `OneWayLink`s, which |
+accept packets as a constrained port (where constrain comes from the finiteness |
+of bandwidth) and outputs them into an unconstrained port. Two endpoints |
+connected via a `SymmetricLink` look like this: |
+ |
+```none |
+ Endpoint A Endpoint B |
++-----------+ SymmetricLink +-----------+ |
+| | +------------------------------+ | | |
+| +---------+ | +------------------------+ | +---------+ | |
+| | RX port <-----| OneWayLink *<-----| TX port | | |
+| +---------+ | +------------------------+ | +---------+ | |
+| | | | | | |
+| +---------+ | +------------------------+ | +---------+ | |
+| | TX port |----->* OneWayLink |-----> RX port | | |
+| +---------+ | +------------------------+ | +---------+ | |
+| | +------------------------------+ | | |
++-----------+ +-----------+ |
+ |
+ ( -->* denotes constrained port) |
+``` |
+ |
+In most common scenario, one of the endpoints is going to be a QUIC endpoint, |
+and another is going to be a switch port. |
+ |
+## Other objects |
+ |
+Besides `SymmetricLink`, the simulator provides the following objects: |
+ |
+* `Queue` allows to convert a constrained port into an unconstrained one by |
+ buffering packets upon arrival. The queue has a finite size, and once the |
+ queue is full, the packets are silently dropped. |
+* `Switch` simulates a multi-port learning switch with a fixed queue for each |
+ output port. |
+* `QuicEndpoint` allows QuicConnection to be run over the simulated network. |
+* `QuicEndpointMultiplexer` allows multiple connections to share the same |
+ network endpoint. |