blob: 263c21395e012c1fa629b7c065fb838353b1c9d3 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 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#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
bnc463f2352019-10-10 04:49:34 -07006
7#include <utility>
8
dmcardlec60e87a2019-12-12 09:43:19 -08009#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
11namespace quic {
12namespace simulator {
13
14SimulatedQuartcPacketTransport::SimulatedQuartcPacketTransport(
15 Simulator* simulator,
vasilvvc48c8712019-03-11 13:38:16 -070016 const std::string& name,
17 const std::string& peer_name,
QUICHE teama6ef0a62019-03-07 20:34:33 -050018 QuicByteCount queue_capacity)
19 : Endpoint(simulator, name),
20 peer_name_(peer_name),
21 egress_queue_(simulator,
dmcardlec60e87a2019-12-12 09:43:19 -080022 quiche::QuicheStringPrintf("%s (TX Queue)", name.c_str()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050023 queue_capacity) {
24 egress_queue_.set_listener_interface(this);
25}
26
27int SimulatedQuartcPacketTransport::Write(const char* buffer,
28 size_t buf_len,
29 const PacketInfo& info) {
30 if (!writable_) {
31 return 0;
32 }
33 if (egress_queue_.bytes_queued() + buf_len > egress_queue_.capacity()) {
34 return 0;
35 }
36
37 last_packet_number_ = info.packet_number;
38
vasilvv0fc587f2019-09-06 13:33:08 -070039 auto packet = std::make_unique<Packet>();
vasilvvc48c8712019-03-11 13:38:16 -070040 packet->contents = std::string(buffer, buf_len);
QUICHE teama6ef0a62019-03-07 20:34:33 -050041 packet->size = buf_len;
42 packet->tx_timestamp = clock_->Now();
43 packet->source = name();
44 packet->destination = peer_name_;
45
46 egress_queue_.AcceptPacket(std::move(packet));
47 return buf_len;
48}
49
50void SimulatedQuartcPacketTransport::SetDelegate(Delegate* delegate) {
51 delegate_ = delegate;
52 Schedule(clock_->Now());
53}
54
55UnconstrainedPortInterface* SimulatedQuartcPacketTransport::GetRxPort() {
56 return this;
57}
58
59void SimulatedQuartcPacketTransport::SetTxPort(ConstrainedPortInterface* port) {
60 egress_queue_.set_tx_port(port);
61 Schedule(clock_->Now());
62}
63
64void SimulatedQuartcPacketTransport::AcceptPacket(
65 std::unique_ptr<Packet> packet) {
66 // Simulated switches broadcast packets to all ports if the cannot determine
67 // the recipient, so we need to drop packets that aren't intended for us.
68 if (packet->destination != name()) {
69 return;
70 }
71
72 if (delegate_) {
73 delegate_->OnTransportReceived(packet->contents.data(), packet->size);
74 }
75}
76
77void SimulatedQuartcPacketTransport::OnPacketDequeued() {
78 if (delegate_ && writable_) {
79 delegate_->OnTransportCanWrite();
80 }
81}
82
83void SimulatedQuartcPacketTransport::Act() {
84 if (delegate_ && writable_) {
85 delegate_->OnTransportCanWrite();
86 }
87}
88
89void SimulatedQuartcPacketTransport::SetWritable(bool writable) {
90 writable_ = writable;
91 if (writable_) {
92 // May need to call |Delegate::OnTransportCanWrite|.
93 Schedule(clock_->Now());
94 }
95}
96
97} // namespace simulator
98} // namespace quic