| // 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 |