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

Unified Diff: net/quic/quic_framer.cc

Issue 16256017: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix for Android DEBUG builds with DEATH_TEST Created 7 years, 6 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 4fd1539db2a32ff0fdfcadb77f73ee5f678bf902..7b30344e951bb3cff5c9bcf3af9500861948a3a3 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -22,8 +22,14 @@ namespace net {
namespace {
// Mask to select the lowest 48 bits of a sequence number.
-const QuicPacketSequenceNumber kSequenceNumberMask =
+const QuicPacketSequenceNumber k6ByteSequenceNumberMask =
GG_UINT64_C(0x0000FFFFFFFFFFFF);
+const QuicPacketSequenceNumber k4ByteSequenceNumberMask =
+ GG_UINT64_C(0x00000000FFFFFFFF);
+const QuicPacketSequenceNumber k2ByteSequenceNumberMask =
+ GG_UINT64_C(0x000000000000FFFF);
+const QuicPacketSequenceNumber k1ByteSequenceNumberMask =
+ GG_UINT64_C(0x00000000000000FF);
const QuicGuid k1ByteGuidMask = GG_UINT64_C(0x00000000000000FF);
const QuicGuid k4ByteGuidMask = GG_UINT64_C(0x00000000FFFFFFFF);
@@ -83,9 +89,10 @@ size_t QuicFramer::GetMinStreamFrameSize() {
// static
size_t QuicFramer::GetMinAckFrameSize() {
- return kQuicFrameTypeSize + kQuicEntropyHashSize + kSequenceNumberSize +
- kQuicEntropyHashSize + kSequenceNumberSize +
- kQuicDeltaTimeLargestObservedSize + kNumberOfMissingPacketsSize;
+ return kQuicFrameTypeSize + kQuicEntropyHashSize +
+ PACKET_6BYTE_SEQUENCE_NUMBER + kQuicEntropyHashSize +
+ PACKET_6BYTE_SEQUENCE_NUMBER + kQuicDeltaTimeLargestObservedSize +
+ kNumberOfMissingPacketsSize;
}
// static
@@ -113,7 +120,7 @@ size_t QuicFramer::GetMinGoAwayFrameSize() {
// 12-byte tags.
size_t QuicFramer::GetMaxUnackedPackets(QuicPacketHeader header) {
return (kMaxPacketSize - GetPacketHeaderSize(header) -
- GetMinAckFrameSize() - 16) / kSequenceNumberSize;
+ GetMinAckFrameSize() - 16) / PACKET_6BYTE_SEQUENCE_NUMBER;
}
bool QuicFramer::IsSupportedVersion(QuicTag version) {
@@ -241,7 +248,8 @@ SerializedPacket QuicFramer::ConstructFrameDataPacket(
DCHECK_LE(len, packet_size);
QuicPacket* packet = QuicPacket::NewDataPacket(
writer.take(), len, true, header.public_header.guid_length,
- header.public_header.version_flag);
+ header.public_header.version_flag,
+ header.public_header.sequence_number_length);
if (fec_builder_) {
fec_builder_->OnBuiltFecProtectedPayload(header,
@@ -274,7 +282,8 @@ SerializedPacket QuicFramer::ConstructFecPacket(
header.packet_sequence_number,
QuicPacket::NewFecPacket(writer.take(), len, true,
header.public_header.guid_length,
- header.public_header.version_flag),
+ header.public_header.version_flag,
+ header.public_header.sequence_number_length),
GetPacketEntropyHash(header), NULL);
}
@@ -286,7 +295,8 @@ QuicEncryptedPacket* QuicFramer::ConstructPublicResetPacket(
QuicDataWriter writer(len);
uint8 flags = static_cast<uint8>(PACKET_PUBLIC_FLAGS_RST |
- PACKET_PUBLIC_FLAGS_8BYTE_GUID);
+ PACKET_PUBLIC_FLAGS_8BYTE_GUID |
+ PACKET_PUBLIC_FLAGS_6BYTE_SEQUENCE);
if (!writer.WriteUInt8(flags)) {
return NULL;
}
@@ -299,7 +309,8 @@ QuicEncryptedPacket* QuicFramer::ConstructPublicResetPacket(
return NULL;
}
- if (!AppendPacketSequenceNumber(packet.rejected_sequence_number,
+ if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ packet.rejected_sequence_number,
&writer)) {
return NULL;
}
@@ -315,7 +326,8 @@ QuicEncryptedPacket* QuicFramer::ConstructVersionNegotiationPacket(
QuicDataWriter writer(len);
uint8 flags = static_cast<uint8>(PACKET_PUBLIC_FLAGS_VERSION |
- PACKET_PUBLIC_FLAGS_8BYTE_GUID);
+ PACKET_PUBLIC_FLAGS_8BYTE_GUID |
+ PACKET_PUBLIC_FLAGS_6BYTE_SEQUENCE);
if (!writer.WriteUInt8(flags)) {
return NULL;
}
@@ -484,6 +496,21 @@ bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header,
if (header.public_header.version_flag) {
public_flags |= PACKET_PUBLIC_FLAGS_VERSION;
}
+ switch (header.public_header.sequence_number_length) {
+ case PACKET_1BYTE_SEQUENCE_NUMBER:
+ public_flags |= PACKET_PUBLIC_FLAGS_1BYTE_SEQUENCE;
+ break;
+ case PACKET_2BYTE_SEQUENCE_NUMBER:
+ public_flags |= PACKET_PUBLIC_FLAGS_2BYTE_SEQUENCE;
+ break;
+ case PACKET_4BYTE_SEQUENCE_NUMBER:
+ public_flags |= PACKET_PUBLIC_FLAGS_4BYTE_SEQUENCE;
+ break;
+ case PACKET_6BYTE_SEQUENCE_NUMBER:
+ public_flags |= PACKET_PUBLIC_FLAGS_6BYTE_SEQUENCE;
+ break;
+ }
+
switch (header.public_header.guid_length) {
case PACKET_0BYTE_GUID:
if (!writer->WriteUInt8(public_flags | PACKET_PUBLIC_FLAGS_0BYTE_GUID)) {
@@ -522,7 +549,8 @@ bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header,
writer->WriteUInt32(quic_version_);
}
- if (!AppendPacketSequenceNumber(header.packet_sequence_number, writer)) {
+ if (!AppendPacketSequenceNumber(header.public_header.sequence_number_length,
+ header.packet_sequence_number, writer)) {
return false;
}
@@ -558,38 +586,47 @@ bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header,
}
QuicPacketSequenceNumber QuicFramer::CalculatePacketSequenceNumberFromWire(
+ QuicSequenceNumberLength sequence_number_length,
QuicPacketSequenceNumber packet_sequence_number) const {
// The new sequence number might have wrapped to the next epoch, or
// it might have reverse wrapped to the previous epoch, or it might
// remain in the same epoch. Select the sequence number closest to the
- // previous sequence number.
- QuicPacketSequenceNumber epoch = last_sequence_number_ & ~kSequenceNumberMask;
- QuicPacketSequenceNumber prev_epoch = epoch - (GG_UINT64_C(1) << 48);
- QuicPacketSequenceNumber next_epoch = epoch + (GG_UINT64_C(1) << 48);
-
- return ClosestTo(last_sequence_number_,
+ // next expected sequence number, the previous sequence number plus 1.
+
+ // epoch_delta is the delta between epochs the sequence number was serialized
+ // with, so the correct value is likely the same epoch as the last sequence
+ // number or an adjacent epoch.
+ const QuicPacketSequenceNumber epoch_delta =
+ GG_UINT64_C(1) << (8 * sequence_number_length);
+ QuicPacketSequenceNumber next_sequence_number = last_sequence_number_ + 1;
+ QuicPacketSequenceNumber epoch = last_sequence_number_ & ~(epoch_delta - 1);
+ QuicPacketSequenceNumber prev_epoch = epoch - epoch_delta;
+ QuicPacketSequenceNumber next_epoch = epoch + epoch_delta;
+
+ return ClosestTo(next_sequence_number,
epoch + packet_sequence_number,
- ClosestTo(last_sequence_number_,
+ ClosestTo(next_sequence_number,
prev_epoch + packet_sequence_number,
next_epoch + packet_sequence_number));
}
-bool QuicFramer::ProcessPublicHeader(QuicPacketPublicHeader* public_header) {
+bool QuicFramer::ProcessPublicHeader(
+ QuicPacketPublicHeader* public_header) {
uint8 public_flags;
if (!reader_->ReadBytes(&public_flags, 1)) {
set_detailed_error("Unable to read public flags.");
return false;
}
- if (public_flags > PACKET_PUBLIC_FLAGS_MAX) {
- set_detailed_error("Illegal public flags value.");
- return false;
- }
-
public_header->reset_flag = (public_flags & PACKET_PUBLIC_FLAGS_RST) != 0;
public_header->version_flag =
(public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0;
+ if (!public_header->version_flag && public_flags > PACKET_PUBLIC_FLAGS_MAX) {
+ set_detailed_error("Illegal public flags value.");
+ return false;
+ }
+
if (public_header->reset_flag && public_header->version_flag) {
set_detailed_error("Got version flag in reset packet");
return false;
@@ -638,6 +675,21 @@ bool QuicFramer::ProcessPublicHeader(QuicPacketPublicHeader* public_header) {
break;
}
+ switch (public_flags & PACKET_PUBLIC_FLAGS_6BYTE_SEQUENCE) {
+ case PACKET_PUBLIC_FLAGS_6BYTE_SEQUENCE:
+ public_header->sequence_number_length = PACKET_6BYTE_SEQUENCE_NUMBER;
+ break;
+ case PACKET_PUBLIC_FLAGS_4BYTE_SEQUENCE:
+ public_header->sequence_number_length = PACKET_4BYTE_SEQUENCE_NUMBER;
+ break;
+ case PACKET_PUBLIC_FLAGS_2BYTE_SEQUENCE:
+ public_header->sequence_number_length = PACKET_2BYTE_SEQUENCE_NUMBER;
+ break;
+ case PACKET_PUBLIC_FLAGS_1BYTE_SEQUENCE:
+ public_header->sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
+ break;
+ }
+
if (public_header->version_flag && is_server_) {
QuicTag version;
if (!reader_->ReadUInt32(&version)) {
@@ -646,6 +698,10 @@ bool QuicFramer::ProcessPublicHeader(QuicPacketPublicHeader* public_header) {
set_detailed_error("Unable to read protocol version.");
return false;
}
+ if (version == quic_version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) {
+ set_detailed_error("Illegal public flags value.");
+ return false;
+ }
public_header->versions.push_back(version);
}
return true;
@@ -671,7 +727,8 @@ bool QuicFramer::ReadGuidFromPacket(const QuicEncryptedPacket& packet,
bool QuicFramer::ProcessPacketHeader(
QuicPacketHeader* header,
const QuicEncryptedPacket& packet) {
- if (!ProcessPacketSequenceNumber(&header->packet_sequence_number)) {
+ if (!ProcessPacketSequenceNumber(header->public_header.sequence_number_length,
+ &header->packet_sequence_number)) {
set_detailed_error("Unable to read sequence number.");
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
@@ -681,10 +738,7 @@ bool QuicFramer::ProcessPacketHeader(
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
- if (!DecryptPayload(header->packet_sequence_number,
- header->public_header.guid_length,
- header->public_header.version_flag,
- packet)) {
+ if (!DecryptPayload(*header, packet)) {
set_detailed_error("Unable to decrypt payload.");
return RaiseError(QUIC_DECRYPTION_FAILURE);
}
@@ -722,14 +776,18 @@ bool QuicFramer::ProcessPacketHeader(
}
bool QuicFramer::ProcessPacketSequenceNumber(
+ QuicSequenceNumberLength sequence_number_length,
QuicPacketSequenceNumber* sequence_number) {
- QuicPacketSequenceNumber wire_sequence_number;
- if (!reader_->ReadUInt48(&wire_sequence_number)) {
+ QuicPacketSequenceNumber wire_sequence_number = 0u;
+ if (!reader_->ReadBytes(&wire_sequence_number, sequence_number_length)) {
return false;
}
+ // TODO(ianswett): Explore the usefulness of trying multiple sequence numbers
+ // in case the first guess is incorrect.
*sequence_number =
- CalculatePacketSequenceNumberFromWire(wire_sequence_number);
+ CalculatePacketSequenceNumberFromWire(sequence_number_length,
+ wire_sequence_number);
return true;
}
@@ -884,7 +942,8 @@ bool QuicFramer::ProcessReceivedInfo(ReceivedPacketInfo* received_info) {
return false;
}
- if (!ProcessPacketSequenceNumber(&received_info->largest_observed)) {
+ if (!ProcessPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ &received_info->largest_observed)) {
set_detailed_error("Unable to read largest observed.");
return false;
}
@@ -910,7 +969,8 @@ bool QuicFramer::ProcessReceivedInfo(ReceivedPacketInfo* received_info) {
for (int i = 0; i < num_missing_packets; ++i) {
QuicPacketSequenceNumber sequence_number;
- if (!ProcessPacketSequenceNumber(&sequence_number)) {
+ if (!ProcessPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ &sequence_number)) {
set_detailed_error("Unable to read sequence number in missing packets.");
return false;
}
@@ -926,7 +986,8 @@ bool QuicFramer::ProcessSentInfo(SentPacketInfo* sent_info) {
return false;
}
- if (!ProcessPacketSequenceNumber(&sent_info->least_unacked)) {
+ if (!ProcessPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ &sent_info->least_unacked)) {
set_detailed_error("Unable to read least unacked.");
return false;
}
@@ -962,7 +1023,8 @@ bool QuicFramer::ProcessQuicCongestionFeedbackFrame(
if (num_received_packets > 0u) {
uint64 smallest_received;
- if (!ProcessPacketSequenceNumber(&smallest_received)) {
+ if (!ProcessPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ &smallest_received)) {
set_detailed_error("Unable to read smallest received.");
return false;
}
@@ -1130,10 +1192,12 @@ bool QuicFramer::ProcessGoAwayFrame(QuicGoAwayFrame* frame) {
StringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket(
const QuicEncryptedPacket& encrypted,
QuicGuidLength guid_length,
- bool includes_version) {
+ bool includes_version,
+ QuicSequenceNumberLength sequence_number_length) {
return StringPiece(encrypted.data() + kStartOfHashData,
GetStartOfEncryptedData(
- guid_length, includes_version) - kStartOfHashData);
+ guid_length, includes_version, sequence_number_length)
+ - kStartOfHashData);
}
void QuicFramer::SetDecrypter(QuicDecrypter* decrypter) {
@@ -1221,9 +1285,7 @@ size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) {
return min_plaintext_size;
}
-bool QuicFramer::DecryptPayload(QuicPacketSequenceNumber sequence_number,
- QuicGuidLength guid_length,
- bool version_flag,
+bool QuicFramer::DecryptPayload(const QuicPacketHeader& header,
const QuicEncryptedPacket& packet) {
StringPiece encrypted;
if (!reader_->ReadStringPiece(&encrypted, reader_->BytesRemaining())) {
@@ -1231,13 +1293,21 @@ bool QuicFramer::DecryptPayload(QuicPacketSequenceNumber sequence_number,
}
DCHECK(decrypter_.get() != NULL);
decrypted_.reset(decrypter_->DecryptPacket(
- sequence_number,
- GetAssociatedDataFromEncryptedPacket(packet, guid_length, version_flag),
+ header.packet_sequence_number,
+ GetAssociatedDataFromEncryptedPacket(
+ packet,
+ header.public_header.guid_length,
+ header.public_header.version_flag,
+ header.public_header.sequence_number_length),
encrypted));
if (decrypted_.get() == NULL && alternative_decrypter_.get() != NULL) {
decrypted_.reset(alternative_decrypter_->DecryptPacket(
- sequence_number,
- GetAssociatedDataFromEncryptedPacket(packet, guid_length, version_flag),
+ header.packet_sequence_number,
+ GetAssociatedDataFromEncryptedPacket(
+ packet,
+ header.public_header.guid_length,
+ header.public_header.version_flag,
+ header.public_header.sequence_number_length),
encrypted));
if (decrypted_.get() != NULL) {
if (alternative_decrypter_latch_) {
@@ -1265,8 +1335,8 @@ size_t QuicFramer::ComputeFrameLength(const QuicFrame& frame) {
return GetMinStreamFrameSize() + frame.stream_frame->data.size();
case ACK_FRAME: {
const QuicAckFrame& ack = *frame.ack_frame;
- return GetMinAckFrameSize() +
- kSequenceNumberSize * ack.received_info.missing_packets.size();
+ return GetMinAckFrameSize() + PACKET_6BYTE_SEQUENCE_NUMBER *
+ ack.received_info.missing_packets.size();
}
case CONGESTION_FEEDBACK_FRAME: {
size_t len = kQuicFrameTypeSize;
@@ -1281,10 +1351,10 @@ size_t QuicFramer::ComputeFrameLength(const QuicFrame& frame) {
len += 2;
len += 1; // Number received packets.
if (inter_arrival.received_packet_times.size() > 0) {
- len += kSequenceNumberSize; // Smallest received.
+ len += PACKET_6BYTE_SEQUENCE_NUMBER; // Smallest received.
len += 8; // Time.
// 2 bytes per sequence number delta plus 4 bytes per delta time.
- len += kSequenceNumberSize *
+ len += PACKET_6BYTE_SEQUENCE_NUMBER *
(inter_arrival.received_packet_times.size() - 1);
}
break;
@@ -1309,7 +1379,8 @@ size_t QuicFramer::ComputeFrameLength(const QuicFrame& frame) {
const QuicAckFrame& ack = frame.connection_close_frame->ack_frame;
return GetMinConnectionCloseFrameSize() +
frame.connection_close_frame->error_details.size() +
- kSequenceNumberSize * ack.received_info.missing_packets.size();
+ PACKET_6BYTE_SEQUENCE_NUMBER *
+ ack.received_info.missing_packets.size();
}
case GOAWAY_FRAME:
return GetMinGoAwayFrameSize() + frame.goaway_frame->reason_phrase.size();
@@ -1328,13 +1399,35 @@ size_t QuicFramer::ComputeFrameLength(const QuicFrame& frame) {
// static
bool QuicFramer::AppendPacketSequenceNumber(
+ QuicSequenceNumberLength sequence_number_length,
QuicPacketSequenceNumber packet_sequence_number,
QuicDataWriter* writer) {
// Ensure the entire sequence number can be written.
- if (writer->capacity() - writer->length() < kSequenceNumberSize) {
+ if (writer->capacity() - writer->length() <
+ static_cast<size_t>( sequence_number_length)) {
return false;
}
- return writer->WriteUInt48(packet_sequence_number & kSequenceNumberMask);
+ switch (sequence_number_length) {
+ case PACKET_1BYTE_SEQUENCE_NUMBER:
+ return writer->WriteUInt8(
+ packet_sequence_number & k1ByteSequenceNumberMask);
+ break;
+ case PACKET_2BYTE_SEQUENCE_NUMBER:
+ return writer->WriteUInt16(
+ packet_sequence_number & k2ByteSequenceNumberMask);
+ break;
+ case PACKET_4BYTE_SEQUENCE_NUMBER:
+ return writer->WriteUInt32(
+ packet_sequence_number & k4ByteSequenceNumberMask);
+ break;
+ case PACKET_6BYTE_SEQUENCE_NUMBER:
+ return writer->WriteUInt48(
+ packet_sequence_number & k6ByteSequenceNumberMask);
+ break;
+ default:
+ NOTREACHED() << "sequence_number_length: " << sequence_number_length;
+ return false;
+ }
}
bool QuicFramer::AppendStreamFramePayload(
@@ -1352,8 +1445,7 @@ bool QuicFramer::AppendStreamFramePayload(
if (!writer->WriteUInt16(frame.data.size())) {
return false;
}
- if (!writer->WriteBytes(frame.data.data(),
- frame.data.size())) {
+ if (!writer->WriteBytes(frame.data.data(), frame.data.size())) {
return false;
}
return true;
@@ -1386,7 +1478,8 @@ bool QuicFramer::AppendAckFramePayload(
return false;
}
- if (!AppendPacketSequenceNumber(frame.sent_info.least_unacked, writer)) {
+ if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ frame.sent_info.least_unacked, writer)) {
return false;
}
@@ -1396,7 +1489,8 @@ bool QuicFramer::AppendAckFramePayload(
}
size_t largest_observed_offset = writer->length();
- if (!AppendPacketSequenceNumber(frame.received_info.largest_observed,
+ if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ frame.received_info.largest_observed,
writer)) {
return false;
}
@@ -1423,7 +1517,8 @@ bool QuicFramer::AppendAckFramePayload(
frame.received_info.missing_packets.begin();
int num_missing_packets_written = 0;
for (; it != frame.received_info.missing_packets.end(); ++it) {
- if (!AppendPacketSequenceNumber(*it, writer)) {
+ if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ *it, writer)) {
// We are truncating.
QuicPacketSequenceNumber largest_observed =
CalculateLargestObserved(frame.received_info.missing_packets, --it);
@@ -1432,7 +1527,7 @@ bool QuicFramer::AppendAckFramePayload(
entropy_calculator_->ReceivedEntropyHash(largest_observed),
received_entropy_offset);
// Overwrite largest_observed.
- writer->WriteUInt48ToOffset(largest_observed & kSequenceNumberMask,
+ writer->WriteUInt48ToOffset(largest_observed & k6ByteSequenceNumberMask,
largest_observed_offset);
writer->WriteUInt32ToOffset(kInvalidDeltaTime,
delta_time_largest_observed_offset);
@@ -1479,7 +1574,8 @@ bool QuicFramer::AppendQuicCongestionFeedbackFramePayload(
inter_arrival.received_packet_times.begin();
QuicPacketSequenceNumber lowest_sequence = it->first;
- if (!AppendPacketSequenceNumber(lowest_sequence, writer)) {
+ if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
+ lowest_sequence, writer)) {
return false;
}

Powered by Google App Engine
This is Rietveld 408576698