| // 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 "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 = QuicMakeUnique<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 |