blob: cf97c216eac77198b35b4009244878552ee5de94 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "quiche/common/masque/connect_ip_datagram_payload.h"
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_bug_tracker.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/common/quiche_data_writer.h"
namespace quiche {
// static
std::unique_ptr<ConnectIpDatagramPayload> ConnectIpDatagramPayload::Parse(
absl::string_view datagram_payload) {
QuicheDataReader data_reader(datagram_payload);
uint64_t context_id;
if (!data_reader.ReadVarInt62(&context_id)) {
QUICHE_DVLOG(1) << "Could not parse malformed IP proxy payload";
return nullptr;
}
if (ContextId{context_id} == ConnectIpDatagramIpPacketPayload::kContextId) {
return std::make_unique<ConnectIpDatagramIpPacketPayload>(
data_reader.ReadRemainingPayload());
} else {
return std::make_unique<ConnectIpDatagramUnknownPayload>(
ContextId{context_id}, data_reader.ReadRemainingPayload());
}
}
std::string ConnectIpDatagramPayload::Serialize() const {
std::string buffer(SerializedLength(), '\0');
QuicheDataWriter writer(buffer.size(), buffer.data());
bool result = SerializeTo(writer);
QUICHE_DCHECK(result);
QUICHE_DCHECK_EQ(writer.remaining(), 0u);
return buffer;
}
ConnectIpDatagramIpPacketPayload::ConnectIpDatagramIpPacketPayload(
absl::string_view ip_packet)
: ip_packet_(ip_packet) {}
ConnectIpDatagramPayload::ContextId
ConnectIpDatagramIpPacketPayload::GetContextId() const {
return kContextId;
}
ConnectIpDatagramPayload::Type ConnectIpDatagramIpPacketPayload::GetType()
const {
return Type::kIpPacket;
}
absl::string_view ConnectIpDatagramIpPacketPayload::GetIpProxyingPayload()
const {
return ip_packet_;
}
size_t ConnectIpDatagramIpPacketPayload::SerializedLength() const {
return ip_packet_.size() +
QuicheDataWriter::GetVarInt62Len(uint64_t{kContextId});
}
bool ConnectIpDatagramIpPacketPayload::SerializeTo(
QuicheDataWriter& writer) const {
if (!writer.WriteVarInt62(uint64_t{kContextId})) {
return false;
}
if (!writer.WriteStringPiece(ip_packet_)) {
return false;
}
return true;
}
ConnectIpDatagramUnknownPayload::ConnectIpDatagramUnknownPayload(
ContextId context_id, absl::string_view ip_proxying_payload)
: context_id_(context_id), ip_proxying_payload_(ip_proxying_payload) {
if (context_id == ConnectIpDatagramIpPacketPayload::kContextId) {
QUICHE_BUG(ip_proxy_unknown_payload_ip_context)
<< "ConnectIpDatagramUnknownPayload created with IP packet context "
"ID (0). Should instead create a "
"ConnectIpDatagramIpPacketPayload.";
}
}
ConnectIpDatagramPayload::ContextId
ConnectIpDatagramUnknownPayload::GetContextId() const {
return context_id_;
}
ConnectIpDatagramPayload::Type ConnectIpDatagramUnknownPayload::GetType()
const {
return Type::kUnknown;
}
absl::string_view ConnectIpDatagramUnknownPayload::GetIpProxyingPayload()
const {
return ip_proxying_payload_;
}
size_t ConnectIpDatagramUnknownPayload::SerializedLength() const {
return ip_proxying_payload_.size() +
QuicheDataWriter::GetVarInt62Len(uint64_t{context_id_});
}
bool ConnectIpDatagramUnknownPayload::SerializeTo(
QuicheDataWriter& writer) const {
if (!writer.WriteVarInt62(uint64_t{context_id_})) {
return false;
}
if (!writer.WriteStringPiece(ip_proxying_payload_)) {
return false;
}
return true;
}
} // namespace quiche