blob: f8acb4f6a86209e2f90aca70db7df4740b2ade11 [file] [log] [blame]
// Copyright (c) 2019 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 "quic/qbone/qbone_packet_exchanger.h"
#include <utility>
namespace quic {
bool QbonePacketExchanger::ReadAndDeliverPacket(
QboneClientInterface* qbone_client) {
bool blocked = false;
std::string error;
std::unique_ptr<QuicData> packet = ReadPacket(&blocked, &error);
if (packet == nullptr) {
if (!blocked && visitor_) {
visitor_->OnReadError(error);
}
return false;
}
qbone_client->ProcessPacketFromNetwork(packet->AsStringPiece());
return true;
}
void QbonePacketExchanger::WritePacketToNetwork(const char* packet,
size_t size) {
bool blocked = false;
std::string error;
if (packet_queue_.empty() && !write_blocked_) {
if (WritePacket(packet, size, &blocked, &error)) {
return;
}
if (blocked) {
write_blocked_ = true;
} else {
QUIC_LOG_EVERY_N_SEC(ERROR, 60) << "Packet write failed: " << error;
if (visitor_) {
visitor_->OnWriteError(error);
}
}
}
// Drop the packet on the floor if the queue if full.
if (packet_queue_.size() >= max_pending_packets_) {
return;
}
auto data_copy = new char[size];
memcpy(data_copy, packet, size);
packet_queue_.push_back(
std::make_unique<QuicData>(data_copy, size, /* owns_buffer = */ true));
}
void QbonePacketExchanger::SetWritable() {
write_blocked_ = false;
while (!packet_queue_.empty()) {
bool blocked = false;
std::string error;
if (WritePacket(packet_queue_.front()->data(),
packet_queue_.front()->length(), &blocked, &error)) {
packet_queue_.pop_front();
} else {
if (!blocked && visitor_) {
visitor_->OnWriteError(error);
}
write_blocked_ = blocked;
return;
}
}
}
} // namespace quic