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; |
} |