blob: 05f71c482915d09af2c4d2c0ce7379c1f9c58616 [file] [log] [blame]
// Copyright (c) 2018 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 "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
#include <utility>
#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
namespace quic {
namespace simulator {
SimulatedQuartcPacketTransport::SimulatedQuartcPacketTransport(
Simulator* simulator,
const std::string& name,
const std::string& peer_name,
QuicByteCount queue_capacity)
: Endpoint(simulator, name),
peer_name_(peer_name),
egress_queue_(simulator,
QuicStringPrintf("%s (TX Queue)", name.c_str()),
queue_capacity) {
egress_queue_.set_listener_interface(this);
}
int SimulatedQuartcPacketTransport::Write(const char* buffer,
size_t buf_len,
const PacketInfo& info) {
if (!writable_) {
return 0;
}
if (egress_queue_.bytes_queued() + buf_len > egress_queue_.capacity()) {
return 0;
}
last_packet_number_ = info.packet_number;
auto packet = std::make_unique<Packet>();
packet->contents = std::string(buffer, buf_len);
packet->size = buf_len;
packet->tx_timestamp = clock_->Now();
packet->source = name();
packet->destination = peer_name_;
egress_queue_.AcceptPacket(std::move(packet));
return buf_len;
}
void SimulatedQuartcPacketTransport::SetDelegate(Delegate* delegate) {
delegate_ = delegate;
Schedule(clock_->Now());
}
UnconstrainedPortInterface* SimulatedQuartcPacketTransport::GetRxPort() {
return this;
}
void SimulatedQuartcPacketTransport::SetTxPort(ConstrainedPortInterface* port) {
egress_queue_.set_tx_port(port);
Schedule(clock_->Now());
}
void SimulatedQuartcPacketTransport::AcceptPacket(
std::unique_ptr<Packet> packet) {
// Simulated switches broadcast packets to all ports if the cannot determine
// the recipient, so we need to drop packets that aren't intended for us.
if (packet->destination != name()) {
return;
}
if (delegate_) {
delegate_->OnTransportReceived(packet->contents.data(), packet->size);
}
}
void SimulatedQuartcPacketTransport::OnPacketDequeued() {
if (delegate_ && writable_) {
delegate_->OnTransportCanWrite();
}
}
void SimulatedQuartcPacketTransport::Act() {
if (delegate_ && writable_) {
delegate_->OnTransportCanWrite();
}
}
void SimulatedQuartcPacketTransport::SetWritable(bool writable) {
writable_ = writable;
if (writable_) {
// May need to call |Delegate::OnTransportCanWrite|.
Schedule(clock_->Now());
}
}
} // namespace simulator
} // namespace quic