naiveproxy/net/quic/core/quic_packets.cc
2018-01-29 00:30:36 +08:00

257 lines
10 KiB
C++

// Copyright (c) 2012 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/quic/core/quic_packets.h"
#include "net/quic/core/quic_utils.h"
#include "net/quic/core/quic_versions.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_str_cat.h"
#include "net/quic/platform/api/quic_text_utils.h"
using std::string;
namespace net {
size_t GetPacketHeaderSize(QuicTransportVersion version,
const QuicPacketHeader& header) {
return GetPacketHeaderSize(version, header.public_header.connection_id_length,
header.public_header.version_flag,
header.public_header.nonce != nullptr,
header.public_header.packet_number_length);
}
size_t GetPacketHeaderSize(QuicTransportVersion version,
QuicConnectionIdLength connection_id_length,
bool include_version,
bool include_diversification_nonce,
QuicPacketNumberLength packet_number_length) {
return kPublicFlagsSize + connection_id_length +
(include_version ? kQuicVersionSize : 0) + packet_number_length +
(include_diversification_nonce ? kDiversificationNonceSize : 0);
}
size_t GetStartOfEncryptedData(QuicTransportVersion version,
const QuicPacketHeader& header) {
return GetPacketHeaderSize(version, header);
}
size_t GetStartOfEncryptedData(QuicTransportVersion version,
QuicConnectionIdLength connection_id_length,
bool include_version,
bool include_diversification_nonce,
QuicPacketNumberLength packet_number_length) {
// Encryption starts before private flags.
return GetPacketHeaderSize(version, connection_id_length, include_version,
include_diversification_nonce,
packet_number_length);
}
QuicPacketPublicHeader::QuicPacketPublicHeader()
: connection_id(0),
connection_id_length(PACKET_8BYTE_CONNECTION_ID),
reset_flag(false),
version_flag(false),
packet_number_length(PACKET_6BYTE_PACKET_NUMBER),
nonce(nullptr) {}
QuicPacketPublicHeader::QuicPacketPublicHeader(
const QuicPacketPublicHeader& other) = default;
QuicPacketPublicHeader::~QuicPacketPublicHeader() {}
QuicPacketHeader::QuicPacketHeader() : packet_number(0) {}
QuicPacketHeader::QuicPacketHeader(const QuicPacketPublicHeader& header)
: public_header(header), packet_number(0) {}
QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
QuicPublicResetPacket::QuicPublicResetPacket() : nonce_proof(0) {}
QuicPublicResetPacket::QuicPublicResetPacket(
const QuicPacketPublicHeader& header)
: public_header(header), nonce_proof(0) {}
std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
os << "{ connection_id: " << header.public_header.connection_id
<< ", connection_id_length: " << header.public_header.connection_id_length
<< ", packet_number_length: " << header.public_header.packet_number_length
<< ", reset_flag: " << header.public_header.reset_flag
<< ", version_flag: " << header.public_header.version_flag;
if (header.public_header.version_flag) {
os << ", version:";
for (size_t i = 0; i < header.public_header.versions.size(); ++i) {
os << " ";
os << QuicVersionToString(header.public_header.versions[i]);
}
}
if (header.public_header.nonce != nullptr) {
os << ", diversification_nonce: "
<< QuicTextUtils::HexEncode(
QuicStringPiece(header.public_header.nonce->data(),
header.public_header.nonce->size()));
}
os << ", packet_number: " << header.packet_number << " }\n";
return os;
}
QuicData::QuicData(const char* buffer, size_t length)
: buffer_(buffer), length_(length), owns_buffer_(false) {}
QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer)
: buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
QuicData::~QuicData() {
if (owns_buffer_) {
delete[] const_cast<char*>(buffer_);
}
}
QuicPacket::QuicPacket(char* buffer,
size_t length,
bool owns_buffer,
QuicConnectionIdLength connection_id_length,
bool includes_version,
bool includes_diversification_nonce,
QuicPacketNumberLength packet_number_length)
: QuicData(buffer, length, owns_buffer),
buffer_(buffer),
connection_id_length_(connection_id_length),
includes_version_(includes_version),
includes_diversification_nonce_(includes_diversification_nonce),
packet_number_length_(packet_number_length) {}
QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
: QuicData(buffer, length) {}
QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer,
size_t length,
bool owns_buffer)
: QuicData(buffer, length, owns_buffer) {}
std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const {
char* buffer = new char[this->length()];
memcpy(buffer, this->data(), this->length());
return QuicMakeUnique<QuicEncryptedPacket>(buffer, this->length(), true);
}
std::ostream& operator<<(std::ostream& os, const QuicEncryptedPacket& s) {
os << s.length() << "-byte data";
return os;
}
QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
size_t length,
QuicTime receipt_time)
: QuicEncryptedPacket(buffer, length),
receipt_time_(receipt_time),
ttl_(0) {}
QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
size_t length,
QuicTime receipt_time,
bool owns_buffer)
: QuicEncryptedPacket(buffer, length, owns_buffer),
receipt_time_(receipt_time),
ttl_(0) {}
QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
size_t length,
QuicTime receipt_time,
bool owns_buffer,
int ttl,
bool ttl_valid)
: QuicEncryptedPacket(buffer, length, owns_buffer),
receipt_time_(receipt_time),
ttl_(ttl_valid ? ttl : -1) {}
std::unique_ptr<QuicReceivedPacket> QuicReceivedPacket::Clone() const {
char* buffer = new char[this->length()];
memcpy(buffer, this->data(), this->length());
return QuicMakeUnique<QuicReceivedPacket>(
buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0);
}
std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) {
os << s.length() << "-byte data";
return os;
}
QuicStringPiece QuicPacket::AssociatedData(QuicTransportVersion version) const {
return QuicStringPiece(
data(), GetStartOfEncryptedData(
version, connection_id_length_, includes_version_,
includes_diversification_nonce_, packet_number_length_));
}
QuicStringPiece QuicPacket::Plaintext(QuicTransportVersion version) const {
const size_t start_of_encrypted_data = GetStartOfEncryptedData(
version, connection_id_length_, includes_version_,
includes_diversification_nonce_, packet_number_length_);
return QuicStringPiece(data() + start_of_encrypted_data,
length() - start_of_encrypted_data);
}
SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
QuicPacketNumberLength packet_number_length,
const char* encrypted_buffer,
QuicPacketLength encrypted_length,
bool has_ack,
bool has_stop_waiting)
: encrypted_buffer(encrypted_buffer),
encrypted_length(encrypted_length),
has_crypto_handshake(NOT_HANDSHAKE),
num_padding_bytes(0),
packet_number(packet_number),
packet_number_length(packet_number_length),
encryption_level(ENCRYPTION_NONE),
has_ack(has_ack),
has_stop_waiting(has_stop_waiting),
transmission_type(NOT_RETRANSMISSION),
original_packet_number(0),
largest_acked(0) {}
SerializedPacket::SerializedPacket(const SerializedPacket& other) = default;
SerializedPacket& SerializedPacket::operator=(const SerializedPacket& other) =
default;
SerializedPacket::SerializedPacket(SerializedPacket&& other)
: encrypted_buffer(other.encrypted_buffer),
encrypted_length(other.encrypted_length),
has_crypto_handshake(other.has_crypto_handshake),
num_padding_bytes(other.num_padding_bytes),
packet_number(other.packet_number),
packet_number_length(other.packet_number_length),
encryption_level(other.encryption_level),
has_ack(other.has_ack),
has_stop_waiting(other.has_stop_waiting),
transmission_type(other.transmission_type),
original_packet_number(other.original_packet_number),
largest_acked(other.largest_acked) {
retransmittable_frames.swap(other.retransmittable_frames);
listeners.swap(other.listeners);
}
SerializedPacket::~SerializedPacket() {}
void ClearSerializedPacket(SerializedPacket* serialized_packet) {
if (!serialized_packet->retransmittable_frames.empty()) {
DeleteFrames(&serialized_packet->retransmittable_frames);
}
serialized_packet->encrypted_buffer = nullptr;
serialized_packet->encrypted_length = 0;
serialized_packet->largest_acked = 0;
}
char* CopyBuffer(const SerializedPacket& packet) {
char* dst_buffer = new char[packet.encrypted_length];
memcpy(dst_buffer, packet.encrypted_buffer, packet.encrypted_length);
return dst_buffer;
}
} // namespace net