blob: 5d723859e0c5ea21093d385557d77f35bb586cad [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <utility>
#include "quic/core/crypto/quic_random.h"
#include "quic/core/quic_bandwidth.h"
#include "quic/test_tools/simulator/actor.h"
#include "quic/test_tools/simulator/port.h"
#include "common/quiche_circular_deque.h"
namespace quic {
namespace simulator {
// A reliable simplex link between two endpoints with constrained bandwidth. A
// few microseconds of random delay are added for every packet to avoid
// synchronization issues.
class OneWayLink : public Actor, public ConstrainedPortInterface {
OneWayLink(Simulator* simulator,
std::string name,
UnconstrainedPortInterface* sink,
QuicBandwidth bandwidth,
QuicTime::Delta propagation_delay);
OneWayLink(const OneWayLink&) = delete;
OneWayLink& operator=(const OneWayLink&) = delete;
~OneWayLink() override;
void AcceptPacket(std::unique_ptr<Packet> packet) override;
QuicTime::Delta TimeUntilAvailable() override;
void Act() override;
inline QuicBandwidth bandwidth() const { return bandwidth_; }
inline void set_bandwidth(QuicBandwidth new_bandwidth) {
bandwidth_ = new_bandwidth;
// Get the value of a random delay imposed on each packet. By default, this
// is a short random delay in order to avoid artifical synchronization
// artifacts during the simulation. Subclasses may override this behavior
// (for example, to provide a random component of delay).
virtual QuicTime::Delta GetRandomDelay(QuicTime::Delta transfer_time);
struct QueuedPacket {
std::unique_ptr<Packet> packet;
QuicTime dequeue_time;
QueuedPacket(std::unique_ptr<Packet> packet, QuicTime dequeue_time);
QueuedPacket(QueuedPacket&& other);
// Schedule the next packet to be egressed out of the link if there are
// packets on the link.
void ScheduleNextPacketDeparture();
UnconstrainedPortInterface* sink_;
quiche::QuicheCircularDeque<QueuedPacket> packets_in_transit_;
QuicBandwidth bandwidth_;
const QuicTime::Delta propagation_delay_;
QuicTime next_write_at_;
// A full-duplex link between two endpoints, functionally equivalent to two
// OneWayLink objects tied together.
class SymmetricLink {
SymmetricLink(Simulator* simulator,
std::string name,
UnconstrainedPortInterface* sink_a,
UnconstrainedPortInterface* sink_b,
QuicBandwidth bandwidth,
QuicTime::Delta propagation_delay);
SymmetricLink(Endpoint* endpoint_a,
Endpoint* endpoint_b,
QuicBandwidth bandwidth,
QuicTime::Delta propagation_delay);
SymmetricLink(const SymmetricLink&) = delete;
SymmetricLink& operator=(const SymmetricLink&) = delete;
inline QuicBandwidth bandwidth() { return a_to_b_link_.bandwidth(); }
inline void set_bandwidth(QuicBandwidth new_bandwidth) {
OneWayLink a_to_b_link_;
OneWayLink b_to_a_link_;
} // namespace simulator
} // namespace quic