Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Unified Diff: net/quic/quic_framer.cc

Issue 15937012: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Small bug fixes Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/quic/quic_framer.cc
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index deb55e6efe08073e7da4e7109f8cfaa5116a4b55..4fd1539db2a32ff0fdfcadb77f73ee5f678bf902 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -25,6 +25,9 @@ namespace {
const QuicPacketSequenceNumber kSequenceNumberMask =
GG_UINT64_C(0x0000FFFFFFFFFFFF);
+const QuicGuid k1ByteGuidMask = GG_UINT64_C(0x00000000000000FF);
+const QuicGuid k4ByteGuidMask = GG_UINT64_C(0x00000000FFFFFFFF);
+
const uint32 kInvalidDeltaTime = 0xffffffff;
// Returns the absolute value of the difference between |a| and |b|.
@@ -52,6 +55,7 @@ QuicFramer::QuicFramer(QuicTag version,
fec_builder_(NULL),
error_(QUIC_NO_ERROR),
last_sequence_number_(0),
+ last_serialized_guid_(0),
quic_version_(version),
decrypter_(QuicDecrypter::Create(kNULL)),
alternative_decrypter_latch_(false),
@@ -107,8 +111,8 @@ size_t QuicFramer::GetMinGoAwayFrameSize() {
// QuicEncrypter::GetMaxPlaintextSize.
// 16 is a conservative estimate in the case of AEAD_AES_128_GCM_12, which uses
// 12-byte tags.
-size_t QuicFramer::GetMaxUnackedPackets(bool include_version) {
- return (kMaxPacketSize - GetPacketHeaderSize(include_version) -
+size_t QuicFramer::GetMaxUnackedPackets(QuicPacketHeader header) {
+ return (kMaxPacketSize - GetPacketHeaderSize(header) -
GetMinAckFrameSize() - 16) / kSequenceNumberSize;
}
@@ -117,7 +121,7 @@ bool QuicFramer::IsSupportedVersion(QuicTag version) {
}
size_t QuicFramer::GetVersionNegotiationPacketSize(size_t number_versions) {
- return kPublicFlagsSize + kQuicGuidSize +
+ return kPublicFlagsSize + PACKET_8BYTE_GUID +
number_versions * kQuicVersionSize;
}
@@ -161,7 +165,7 @@ SerializedPacket QuicFramer::ConstructFrameDataPacket(
const QuicPacketHeader& header,
const QuicFrames& frames) {
const size_t max_plaintext_size = GetMaxPlaintextSize(kMaxPacketSize);
- size_t packet_size = GetPacketHeaderSize(header.public_header.version_flag);
+ size_t packet_size = GetPacketHeaderSize(header);
for (size_t i = 0; i < frames.size(); ++i) {
DCHECK_LE(packet_size, max_plaintext_size);
const size_t frame_size = GetSerializedFrameLength(
@@ -236,7 +240,8 @@ SerializedPacket QuicFramer::ConstructFrameDataPacket(
// length, even though they're typically slightly shorter.
DCHECK_LE(len, packet_size);
QuicPacket* packet = QuicPacket::NewDataPacket(
- writer.take(), len, true, header.public_header.version_flag);
+ writer.take(), len, true, header.public_header.guid_length,
+ header.public_header.version_flag);
if (fec_builder_) {
fec_builder_->OnBuiltFecProtectedPayload(header,
@@ -247,9 +252,12 @@ SerializedPacket QuicFramer::ConstructFrameDataPacket(
GetPacketEntropyHash(header), NULL);
}
-SerializedPacket QuicFramer::ConstructFecPacket(const QuicPacketHeader& header,
- const QuicFecData& fec) {
- size_t len = GetPacketHeaderSize(header.public_header.version_flag);
+SerializedPacket QuicFramer::ConstructFecPacket(
+ const QuicPacketHeader& header,
+ const QuicFecData& fec) {
+ DCHECK_EQ(IN_FEC_GROUP, header.is_in_fec_group);
+ DCHECK_NE(0u, header.fec_group);
+ size_t len = GetPacketHeaderSize(header);
len += fec.redundancy.length();
QuicDataWriter writer(len);
@@ -262,11 +270,12 @@ SerializedPacket QuicFramer::ConstructFecPacket(const QuicPacketHeader& header,
return kNoPacket;
}
- return SerializedPacket(header.packet_sequence_number,
- QuicPacket::NewFecPacket(
- writer.take(), len, true,
- header.public_header.version_flag),
- GetPacketEntropyHash(header), NULL);
+ return SerializedPacket(
+ header.packet_sequence_number,
+ QuicPacket::NewFecPacket(writer.take(), len, true,
+ header.public_header.guid_length,
+ header.public_header.version_flag),
+ GetPacketEntropyHash(header), NULL);
}
// static
@@ -399,7 +408,7 @@ bool QuicFramer::ProcessDataPacket(
// Handle the payload.
if (!header.fec_flag) {
- if (header.fec_group != 0) {
+ if (header.is_in_fec_group == IN_FEC_GROUP) {
StringPiece payload = reader_->PeekRemainingPayload();
visitor_->OnFecProtectedPayload(payload);
}
@@ -467,21 +476,46 @@ bool QuicFramer::ProcessRevivedPacket(QuicPacketHeader* header,
bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header,
QuicDataWriter* writer) {
- uint8 flags = 0;
+ DCHECK(header.fec_group > 0 || header.is_in_fec_group == NOT_IN_FEC_GROUP);
+ uint8 public_flags = 0;
if (header.public_header.reset_flag) {
- flags |= PACKET_PUBLIC_FLAGS_RST;
+ public_flags |= PACKET_PUBLIC_FLAGS_RST;
}
if (header.public_header.version_flag) {
- flags |= PACKET_PUBLIC_FLAGS_VERSION;
- }
- flags |= PACKET_PUBLIC_FLAGS_8BYTE_GUID;
- if (!writer->WriteUInt8(flags)) {
- return false;
+ public_flags |= PACKET_PUBLIC_FLAGS_VERSION;
}
-
- if (!writer->WriteUInt64(header.public_header.guid)) {
- return false;
+ switch (header.public_header.guid_length) {
+ case PACKET_0BYTE_GUID:
+ if (!writer->WriteUInt8(public_flags | PACKET_PUBLIC_FLAGS_0BYTE_GUID)) {
+ return false;
+ }
+ break;
+ case PACKET_1BYTE_GUID:
+ if (!writer->WriteUInt8(public_flags | PACKET_PUBLIC_FLAGS_1BYTE_GUID)) {
+ return false;
+ }
+ if (!writer->WriteUInt8(header.public_header.guid & k1ByteGuidMask)) {
+ return false;
+ }
+ break;
+ case PACKET_4BYTE_GUID:
+ if (!writer->WriteUInt8(public_flags | PACKET_PUBLIC_FLAGS_4BYTE_GUID)) {
+ return false;
+ }
+ if (!writer->WriteUInt32(header.public_header.guid & k4ByteGuidMask)) {
+ return false;
+ }
+ break;
+ case PACKET_8BYTE_GUID:
+ if (!writer->WriteUInt8(public_flags | PACKET_PUBLIC_FLAGS_8BYTE_GUID)) {
+ return false;
+ }
+ if (!writer->WriteUInt64(header.public_header.guid)) {
+ return false;
+ }
+ break;
}
+ last_serialized_guid_ = header.public_header.guid;
if (header.public_header.version_flag) {
DCHECK(!is_server_);
@@ -492,34 +526,32 @@ bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header,
return false;
}
- flags = 0;
- if (header.fec_flag) {
- flags |= PACKET_PRIVATE_FLAGS_FEC;
- }
+ uint8 private_flags = 0;
if (header.entropy_flag) {
- flags |= PACKET_PRIVATE_FLAGS_ENTROPY;
+ private_flags |= PACKET_PRIVATE_FLAGS_ENTROPY;
}
- if (header.fec_entropy_flag) {
- flags |= PACKET_PRIVATE_FLAGS_FEC_ENTROPY;
+ if (header.is_in_fec_group == IN_FEC_GROUP) {
+ private_flags |= PACKET_PRIVATE_FLAGS_FEC_GROUP;
+ }
+ if (header.fec_flag) {
+ private_flags |= PACKET_PRIVATE_FLAGS_FEC;
}
- if (!writer->WriteUInt8(flags)) {
+ if (!writer->WriteUInt8(private_flags)) {
return false;
}
- // Offset from the current packet sequence number to the first fec
- // protected packet, or kNoFecOffset to signal no FEC protection.
- uint8 first_fec_protected_packet_offset = kNoFecOffset;
-
// The FEC group number is the sequence number of the first fec
// protected packet, or 0 if this packet is not protected.
- if (header.fec_group != 0) {
+ if (header.is_in_fec_group == IN_FEC_GROUP) {
DCHECK_GE(header.packet_sequence_number, header.fec_group);
DCHECK_GT(255u, header.packet_sequence_number - header.fec_group);
- first_fec_protected_packet_offset =
+ // Offset from the current packet sequence number to the first fec
+ // protected packet.
+ uint8 first_fec_protected_packet_offset =
header.packet_sequence_number - header.fec_group;
- }
- if (!writer->WriteBytes(&first_fec_protected_packet_offset, 1)) {
- return false;
+ if (!writer->WriteBytes(&first_fec_protected_packet_offset, 1)) {
+ return false;
+ }
}
return true;
@@ -554,12 +586,6 @@ bool QuicFramer::ProcessPublicHeader(QuicPacketPublicHeader* public_header) {
return false;
}
- if ((public_flags & PACKET_PUBLIC_FLAGS_8BYTE_GUID) !=
- PACKET_PUBLIC_FLAGS_8BYTE_GUID) {
- set_detailed_error("Only full length guids (8 bytes) currently supported.");
- return false;
- }
-
public_header->reset_flag = (public_flags & PACKET_PUBLIC_FLAGS_RST) != 0;
public_header->version_flag =
(public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0;
@@ -569,9 +595,47 @@ bool QuicFramer::ProcessPublicHeader(QuicPacketPublicHeader* public_header) {
return false;
}
- if (!reader_->ReadUInt64(&public_header->guid)) {
- set_detailed_error("Unable to read GUID.");
- return false;
+ switch (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_GUID) {
+ case PACKET_PUBLIC_FLAGS_8BYTE_GUID:
+ if (!reader_->ReadUInt64(&public_header->guid)) {
+ set_detailed_error("Unable to read GUID.");
+ return false;
+ }
+ public_header->guid_length = PACKET_8BYTE_GUID;
+ break;
+ case PACKET_PUBLIC_FLAGS_4BYTE_GUID:
+ // If the guid is truncated, expect to read the last serialized guid.
+ if (!reader_->ReadBytes(&public_header->guid, PACKET_4BYTE_GUID)) {
+ set_detailed_error("Unable to read GUID.");
+ return false;
+ }
+ if ((public_header->guid & k4ByteGuidMask) !=
+ (last_serialized_guid_ & k4ByteGuidMask)) {
+ set_detailed_error(
+ "Truncated 4 byte GUID does not match previous guid.");
+ return false;
+ }
+ public_header->guid_length = PACKET_4BYTE_GUID;
+ public_header->guid = last_serialized_guid_;
+ break;
+ case PACKET_PUBLIC_FLAGS_1BYTE_GUID:
+ if (!reader_->ReadBytes(&public_header->guid, PACKET_1BYTE_GUID)) {
+ set_detailed_error("Unable to read GUID.");
+ return false;
+ }
+ if ((public_header->guid & k1ByteGuidMask) !=
+ (last_serialized_guid_ & k1ByteGuidMask)) {
+ set_detailed_error(
+ "Truncated 1 byte GUID does not match previous guid.");
+ return false;
+ }
+ public_header->guid_length = PACKET_1BYTE_GUID;
+ public_header->guid = last_serialized_guid_;
+ break;
+ case PACKET_PUBLIC_FLAGS_0BYTE_GUID:
+ public_header->guid_length = PACKET_0BYTE_GUID;
+ public_header->guid = last_serialized_guid_;
+ break;
}
if (public_header->version_flag && is_server_) {
@@ -618,6 +682,7 @@ bool QuicFramer::ProcessPacketHeader(
}
if (!DecryptPayload(header->packet_sequence_number,
+ header->public_header.guid_length,
header->public_header.version_flag,
packet)) {
set_detailed_error("Unable to decrypt payload.");
@@ -635,18 +700,19 @@ bool QuicFramer::ProcessPacketHeader(
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
- header->fec_flag = (private_flags & PACKET_PRIVATE_FLAGS_FEC) != 0;
header->entropy_flag = (private_flags & PACKET_PRIVATE_FLAGS_ENTROPY) != 0;
- header->fec_entropy_flag =
- (private_flags & PACKET_PRIVATE_FLAGS_FEC_ENTROPY) != 0;
+ header->fec_flag = (private_flags & PACKET_PRIVATE_FLAGS_FEC) != 0;
- uint8 first_fec_protected_packet_offset;
- if (!reader_->ReadBytes(&first_fec_protected_packet_offset, 1)) {
- set_detailed_error("Unable to read first fec protected packet offset.");
- return RaiseError(QUIC_INVALID_PACKET_HEADER);
+ if ((private_flags & PACKET_PRIVATE_FLAGS_FEC_GROUP) != 0) {
+ header->is_in_fec_group = IN_FEC_GROUP;
+ uint8 first_fec_protected_packet_offset;
+ if (!reader_->ReadBytes(&first_fec_protected_packet_offset, 1)) {
+ set_detailed_error("Unable to read first fec protected packet offset.");
+ return RaiseError(QUIC_INVALID_PACKET_HEADER);
+ }
+ header->fec_group =
+ header->packet_sequence_number - first_fec_protected_packet_offset;
}
- header->fec_group = first_fec_protected_packet_offset == kNoFecOffset ? 0 :
- header->packet_sequence_number - first_fec_protected_packet_offset;
header->entropy_hash = GetPacketEntropyHash(*header);
// Set the last sequence number after we have decrypted the packet
@@ -1062,10 +1128,12 @@ bool QuicFramer::ProcessGoAwayFrame(QuicGoAwayFrame* frame) {
// static
StringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket(
- const QuicEncryptedPacket& encrypted, bool includes_version) {
+ const QuicEncryptedPacket& encrypted,
+ QuicGuidLength guid_length,
+ bool includes_version) {
return StringPiece(encrypted.data() + kStartOfHashData,
- GetStartOfEncryptedData(includes_version) -
- kStartOfHashData);
+ GetStartOfEncryptedData(
+ guid_length, includes_version) - kStartOfHashData);
}
void QuicFramer::SetDecrypter(QuicDecrypter* decrypter) {
@@ -1154,6 +1222,7 @@ size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) {
}
bool QuicFramer::DecryptPayload(QuicPacketSequenceNumber sequence_number,
+ QuicGuidLength guid_length,
bool version_flag,
const QuicEncryptedPacket& packet) {
StringPiece encrypted;
@@ -1163,12 +1232,12 @@ bool QuicFramer::DecryptPayload(QuicPacketSequenceNumber sequence_number,
DCHECK(decrypter_.get() != NULL);
decrypted_.reset(decrypter_->DecryptPacket(
sequence_number,
- GetAssociatedDataFromEncryptedPacket(packet, version_flag),
+ GetAssociatedDataFromEncryptedPacket(packet, guid_length, version_flag),
encrypted));
if (decrypted_.get() == NULL && alternative_decrypter_.get() != NULL) {
decrypted_.reset(alternative_decrypter_->DecryptPacket(
sequence_number,
- GetAssociatedDataFromEncryptedPacket(packet, version_flag),
+ GetAssociatedDataFromEncryptedPacket(packet, guid_length, version_flag),
encrypted));
if (decrypted_.get() != NULL) {
if (alternative_decrypter_latch_) {

Powered by Google App Engine
This is Rietveld 408576698