summaryrefslogtreecommitdiff
path: root/chromium/net/quic/quic_framer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/quic/quic_framer.cc')
-rw-r--r--chromium/net/quic/quic_framer.cc849
1 files changed, 439 insertions, 410 deletions
diff --git a/chromium/net/quic/quic_framer.cc b/chromium/net/quic/quic_framer.cc
index cfc8c95774b..cc02882ddc9 100644
--- a/chromium/net/quic/quic_framer.cc
+++ b/chromium/net/quic/quic_framer.cc
@@ -13,6 +13,8 @@
using base::StringPiece;
using std::make_pair;
using std::map;
+using std::max;
+using std::min;
using std::numeric_limits;
using std::string;
@@ -20,19 +22,6 @@ namespace net {
namespace {
-// TODO(jri): Remove uses of QuicFrameTypeOld when
-// QUIC versions < 10 are no longer supported.
-enum QuicFrameTypeOld {
- PADDING_FRAME_OLD = 0,
- STREAM_FRAME_OLD,
- ACK_FRAME_OLD,
- CONGESTION_FEEDBACK_FRAME_OLD,
- RST_STREAM_FRAME_OLD,
- CONNECTION_CLOSE_FRAME_OLD,
- GOAWAY_FRAME_OLD,
- NUM_FRAME_TYPES_OLD
-};
-
// Mask to select the lowest 48 bits of a sequence number.
const QuicPacketSequenceNumber k6ByteSequenceNumberMask =
GG_UINT64_C(0x0000FFFFFFFFFFFF);
@@ -46,6 +35,10 @@ const QuicPacketSequenceNumber k1ByteSequenceNumberMask =
const QuicGuid k1ByteGuidMask = GG_UINT64_C(0x00000000000000FF);
const QuicGuid k4ByteGuidMask = GG_UINT64_C(0x00000000FFFFFFFF);
+// Number of bits the sequence number length bits are shifted from the right
+// edge of the public header.
+const uint8 kPublicHeaderSequenceNumberShift = 4;
+
// New Frame Types, QUIC v. >= 10:
// There are two interpretations for the Frame Type byte in the QUIC protocol,
// resulting in two Frame Types: Special Frame Types and Regular Frame Types.
@@ -72,16 +65,6 @@ const uint8 kQuicFrameTypeStreamMask = 0x80;
const uint8 kQuicFrameTypeAckMask = 0x40;
const uint8 kQuicFrameTypeCongestionFeedbackMask = 0x20;
-// Mask to determine if it's a special frame type(Stream, Ack, or
-// Congestion Control) by checking if the first bit is 0, then shifting right.
-// TODO(jri): Remove kQuicFrameType0BitMask constant from v. 10 onwards.
-// Replaced by kQuicFrameTypeStream defined above.
-const uint8 kQuicFrameType0BitMask = 0x01;
-
-// Default frame type shift and mask.
-const uint8 kQuicDefaultFrameTypeShift = 3;
-const uint8 kQuicDefaultFrameTypeMask = 0x07;
-
// Stream frame relative shifts and masks for interpreting the stream flags.
// StreamID may be 1, 2, 3, or 4 bytes.
const uint8 kQuicStreamIdShift = 2;
@@ -99,8 +82,15 @@ const uint8 kQuicStreamDataLengthMask = 0x01;
const uint8 kQuicStreamFinShift = 1;
const uint8 kQuicStreamFinMask = 0x01;
+// Sequence number size shift used in AckFrames.
+const uint8 kQuicSequenceNumberLengthShift = 2;
+
+// Acks may be truncated.
+const uint8 kQuicAckTruncatedShift = 1;
+const uint8 kQuicAckTruncatedMask = 0x01;
-const uint32 kInvalidDeltaTime = 0xffffffff;
+// Acks may not have any nacks.
+const uint8 kQuicHasNacksMask = 0x01;
// Returns the absolute value of the difference between |a| and |b|.
QuicPacketSequenceNumber Delta(QuicPacketSequenceNumber a,
@@ -120,21 +110,24 @@ QuicPacketSequenceNumber ClosestTo(QuicPacketSequenceNumber target,
} // namespace
-QuicFramer::QuicFramer(QuicVersion version,
+QuicFramer::QuicFramer(const QuicVersionVector& supported_versions,
QuicTime creation_time,
bool is_server)
: visitor_(NULL),
fec_builder_(NULL),
+ entropy_calculator_(NULL),
error_(QUIC_NO_ERROR),
last_sequence_number_(0),
last_serialized_guid_(0),
- quic_version_(version),
- decrypter_(QuicDecrypter::Create(kNULL)),
+ supported_versions_(supported_versions),
alternative_decrypter_latch_(false),
is_server_(is_server),
creation_time_(creation_time) {
- DCHECK(IsSupportedVersion(version));
- encrypter_[ENCRYPTION_NONE].reset(QuicEncrypter::Create(kNULL));
+ DCHECK(!supported_versions.empty());
+ quic_version_ = supported_versions_[0];
+ decrypter_.reset(QuicDecrypter::Create(kNULL));
+ encrypter_[ENCRYPTION_NONE].reset(
+ QuicEncrypter::Create(kNULL));
}
QuicFramer::~QuicFramer() {}
@@ -150,11 +143,13 @@ size_t QuicFramer::GetMinStreamFrameSize(QuicVersion version,
}
// static
-size_t QuicFramer::GetMinAckFrameSize() {
+size_t QuicFramer::GetMinAckFrameSize(
+ QuicVersion version,
+ QuicSequenceNumberLength sequence_number_length,
+ QuicSequenceNumberLength largest_observed_length) {
return kQuicFrameTypeSize + kQuicEntropyHashSize +
- PACKET_6BYTE_SEQUENCE_NUMBER + kQuicEntropyHashSize +
- PACKET_6BYTE_SEQUENCE_NUMBER + kQuicDeltaTimeLargestObservedSize +
- kNumberOfMissingPacketsSize;
+ sequence_number_length + kQuicEntropyHashSize +
+ largest_observed_length + kQuicDeltaTimeLargestObservedSize;
}
// static
@@ -165,8 +160,7 @@ size_t QuicFramer::GetMinRstStreamFrameSize() {
// static
size_t QuicFramer::GetMinConnectionCloseFrameSize() {
- return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize +
- GetMinAckFrameSize();
+ return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize;
}
// static
@@ -176,16 +170,6 @@ size_t QuicFramer::GetMinGoAwayFrameSize() {
}
// static
-// TODO(satyamshekhar): 16 - Crypto hash for integrity. Not a static value. Use
-// 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(QuicPacketHeader header) {
- return (kMaxPacketSize - GetPacketHeaderSize(header) -
- GetMinAckFrameSize() - 16) / PACKET_6BYTE_SEQUENCE_NUMBER;
-}
-
-// static
size_t QuicFramer::GetStreamIdSize(QuicStreamId stream_id) {
// Sizes are 1 through 4 bytes.
for (int i = 1; i <= 4; ++i) {
@@ -223,20 +207,20 @@ size_t QuicFramer::GetVersionNegotiationPacketSize(size_t number_versions) {
}
// static
-bool QuicFramer::CanTruncate(const QuicFrame& frame, size_t free_bytes) {
- // TODO(ianswett): GetMinConnectionCloseFrameSize may be incorrect, because
- // checking for it here results in frames not being added, but the resulting
- // frames do actually fit.
+bool QuicFramer::CanTruncate(
+ QuicVersion version, const QuicFrame& frame, size_t free_bytes) {
if ((frame.type == ACK_FRAME || frame.type == CONNECTION_CLOSE_FRAME) &&
- free_bytes >= GetMinAckFrameSize()) {
+ free_bytes >= GetMinAckFrameSize(version,
+ PACKET_6BYTE_SEQUENCE_NUMBER,
+ PACKET_6BYTE_SEQUENCE_NUMBER)) {
return true;
}
return false;
}
bool QuicFramer::IsSupportedVersion(const QuicVersion version) const {
- for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
- if (version == kSupportedQuicVersions[i]) {
+ for (size_t i = 0; i < supported_versions_.size(); ++i) {
+ if (version == supported_versions_[i]) {
return true;
}
}
@@ -244,43 +228,43 @@ bool QuicFramer::IsSupportedVersion(const QuicVersion version) const {
}
size_t QuicFramer::GetSerializedFrameLength(
- const QuicFrame& frame, size_t free_bytes, bool first_frame) {
+ const QuicFrame& frame,
+ size_t free_bytes,
+ bool first_frame,
+ bool last_frame,
+ QuicSequenceNumberLength sequence_number_length) {
if (frame.type == PADDING_FRAME) {
// PADDING implies end of packet.
return free_bytes;
}
- // See if it fits as the non-last frame.
- size_t frame_len = ComputeFrameLength(frame, false);
- // STREAM frames save two bytes when they're the last frame in the packet.
- if (frame_len > free_bytes && frame.type == STREAM_FRAME) {
- frame_len = ComputeFrameLength(frame, true);
- }
+ size_t frame_len =
+ ComputeFrameLength(frame, last_frame, sequence_number_length);
if (frame_len > free_bytes) {
// Only truncate the first frame in a packet, so if subsequent ones go
// over, stop including more frames.
if (!first_frame) {
return 0;
}
- if (CanTruncate(frame, free_bytes)) {
+ if (CanTruncate(quic_version_, frame, free_bytes)) {
// Truncate the frame so the packet will not exceed kMaxPacketSize.
// Note that we may not use every byte of the writer in this case.
- DLOG(INFO) << "Truncating large frame";
+ DVLOG(1) << "Truncating large frame";
return free_bytes;
}
}
return frame_len;
}
+QuicFramer::AckFrameInfo::AckFrameInfo() : max_delta(0) { }
+
+QuicFramer::AckFrameInfo::~AckFrameInfo() { }
+
QuicPacketEntropyHash QuicFramer::GetPacketEntropyHash(
const QuicPacketHeader& header) const {
- if (!header.entropy_flag) {
- // TODO(satyamshekhar): Return some more better value here (something that
- // is not a constant).
- return 0;
- }
- return 1 << (header.packet_sequence_number % 8);
+ return header.entropy_flag << (header.packet_sequence_number % 8);
}
+// Test only.
SerializedPacket QuicFramer::BuildUnsizedDataPacket(
const QuicPacketHeader& header,
const QuicFrames& frames) {
@@ -288,8 +272,11 @@ SerializedPacket QuicFramer::BuildUnsizedDataPacket(
size_t packet_size = GetPacketHeaderSize(header);
for (size_t i = 0; i < frames.size(); ++i) {
DCHECK_LE(packet_size, max_plaintext_size);
+ bool first_frame = i == 0;
+ bool last_frame = i == frames.size() - 1;
const size_t frame_size = GetSerializedFrameLength(
- frames[i], max_plaintext_size - packet_size, i == 0);
+ frames[i], max_plaintext_size - packet_size, first_frame, last_frame,
+ header.public_header.sequence_number_length);
DCHECK(frame_size);
packet_size += frame_size;
}
@@ -303,7 +290,7 @@ SerializedPacket QuicFramer::BuildDataPacket(
QuicDataWriter writer(packet_size);
const SerializedPacket kNoPacket(
0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL);
- if (!WritePacketHeader(header, &writer)) {
+ if (!AppendPacketHeader(header, &writer)) {
return kNoPacket;
}
@@ -326,7 +313,8 @@ SerializedPacket QuicFramer::BuildDataPacket(
}
break;
case ACK_FRAME:
- if (!AppendAckFramePayload(*frame.ack_frame, &writer)) {
+ if (!AppendAckFramePayloadAndTypeByte(
+ header, *frame.ack_frame, &writer)) {
return kNoPacket;
}
break;
@@ -388,7 +376,7 @@ SerializedPacket QuicFramer::BuildFecPacket(const QuicPacketHeader& header,
QuicDataWriter writer(len);
const SerializedPacket kNoPacket(
0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL);
- if (!WritePacketHeader(header, &writer)) {
+ if (!AppendPacketHeader(header, &writer)) {
return kNoPacket;
}
@@ -465,8 +453,6 @@ QuicEncryptedPacket* QuicFramer::BuildVersionNegotiationPacket(
}
bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
- // TODO(satyamshekhar): Don't RaiseError (and close the connection) for
- // invalid (unauthenticated) packets.
DCHECK(!reader_.get());
reader_.reset(new QuicDataReader(packet.data(), packet.length()));
@@ -476,6 +462,7 @@ bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
QuicPacketPublicHeader public_header;
if (!ProcessPublicHeader(&public_header)) {
DLOG(WARNING) << "Unable to process public header.";
+ DCHECK_NE("", detailed_error_);
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
@@ -522,7 +509,6 @@ bool QuicFramer::ProcessDataPacket(
const QuicEncryptedPacket& packet) {
QuicPacketHeader header(public_header);
if (!ProcessPacketHeader(&header, packet)) {
- DCHECK_NE(QUIC_NO_ERROR, error_); // ProcessPacketHeader sets the error.
DLOG(WARNING) << "Unable to process data packet header.";
return false;
}
@@ -543,7 +529,7 @@ bool QuicFramer::ProcessDataPacket(
StringPiece payload = reader_->PeekRemainingPayload();
visitor_->OnFecProtectedPayload(payload);
}
- if (!ProcessFrameData()) {
+ if (!ProcessFrameData(header)) {
DCHECK_NE(QUIC_NO_ERROR, error_); // ProcessFrameData sets the error.
DLOG(WARNING) << "Unable to process frame data.";
return false;
@@ -594,7 +580,7 @@ bool QuicFramer::ProcessRevivedPacket(QuicPacketHeader* header,
}
reader_.reset(new QuicDataReader(payload.data(), payload.length()));
- if (!ProcessFrameData()) {
+ if (!ProcessFrameData(*header)) {
DCHECK_NE(QUIC_NO_ERROR, error_); // ProcessFrameData sets the error.
DLOG(WARNING) << "Unable to process frame data.";
return false;
@@ -605,8 +591,8 @@ bool QuicFramer::ProcessRevivedPacket(QuicPacketHeader* header,
return true;
}
-bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header,
- QuicDataWriter* writer) {
+bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
+ QuicDataWriter* writer) {
DCHECK(header.fec_group > 0 || header.is_in_fec_group == NOT_IN_FEC_GROUP);
uint8 public_flags = 0;
if (header.public_header.reset_flag) {
@@ -615,20 +601,10 @@ 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;
- }
+
+ public_flags |=
+ GetSequenceNumberFlags(header.public_header.sequence_number_length)
+ << kPublicHeaderSequenceNumberShift;
switch (header.public_header.guid_length) {
case PACKET_0BYTE_GUID:
@@ -641,7 +617,7 @@ bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header,
return false;
}
if (!writer->WriteUInt8(header.public_header.guid & k1ByteGuidMask)) {
- return false;
+ return false;
}
break;
case PACKET_4BYTE_GUID:
@@ -794,20 +770,9 @@ bool QuicFramer::ProcessPublicHeader(
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;
- }
+ public_header->sequence_number_length =
+ ReadSequenceNumberLength(
+ public_flags >> kPublicHeaderSequenceNumberShift);
// Read the version only if the packet is from the client.
// version flag from the server means version negotiation packet.
@@ -848,6 +813,91 @@ bool QuicFramer::ReadGuidFromPacket(const QuicEncryptedPacket& packet,
return reader.ReadUInt64(guid);
}
+// static
+QuicSequenceNumberLength QuicFramer::ReadSequenceNumberLength(uint8 flags) {
+ switch (flags & PACKET_FLAGS_6BYTE_SEQUENCE) {
+ case PACKET_FLAGS_6BYTE_SEQUENCE:
+ return PACKET_6BYTE_SEQUENCE_NUMBER;
+ case PACKET_FLAGS_4BYTE_SEQUENCE:
+ return PACKET_4BYTE_SEQUENCE_NUMBER;
+ case PACKET_FLAGS_2BYTE_SEQUENCE:
+ return PACKET_2BYTE_SEQUENCE_NUMBER;
+ case PACKET_FLAGS_1BYTE_SEQUENCE:
+ return PACKET_1BYTE_SEQUENCE_NUMBER;
+ default:
+ LOG(DFATAL) << "Unreachable case statement.";
+ return PACKET_6BYTE_SEQUENCE_NUMBER;
+ }
+}
+
+// static
+QuicSequenceNumberLength QuicFramer::GetMinSequenceNumberLength(
+ QuicPacketSequenceNumber sequence_number) {
+ if (sequence_number < 1 << (PACKET_1BYTE_SEQUENCE_NUMBER * 8)) {
+ return PACKET_1BYTE_SEQUENCE_NUMBER;
+ } else if (sequence_number < 1 << (PACKET_2BYTE_SEQUENCE_NUMBER * 8)) {
+ return PACKET_2BYTE_SEQUENCE_NUMBER;
+ } else if (sequence_number <
+ GG_UINT64_C(1) << (PACKET_4BYTE_SEQUENCE_NUMBER * 8)) {
+ return PACKET_4BYTE_SEQUENCE_NUMBER;
+ } else {
+ return PACKET_6BYTE_SEQUENCE_NUMBER;
+ }
+}
+
+// static
+uint8 QuicFramer::GetSequenceNumberFlags(
+ QuicSequenceNumberLength sequence_number_length) {
+ switch (sequence_number_length) {
+ case PACKET_1BYTE_SEQUENCE_NUMBER:
+ return PACKET_FLAGS_1BYTE_SEQUENCE;
+ case PACKET_2BYTE_SEQUENCE_NUMBER:
+ return PACKET_FLAGS_2BYTE_SEQUENCE;
+ case PACKET_4BYTE_SEQUENCE_NUMBER:
+ return PACKET_FLAGS_4BYTE_SEQUENCE;
+ case PACKET_6BYTE_SEQUENCE_NUMBER:
+ return PACKET_FLAGS_6BYTE_SEQUENCE;
+ default:
+ LOG(DFATAL) << "Unreachable case statement.";
+ return PACKET_FLAGS_6BYTE_SEQUENCE;
+ }
+}
+
+// static
+QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
+ const QuicAckFrame& frame) {
+ const ReceivedPacketInfo& received_info = frame.received_info;
+
+ AckFrameInfo ack_info;
+ if (!received_info.missing_packets.empty()) {
+ DCHECK_GE(received_info.largest_observed,
+ *received_info.missing_packets.rbegin());
+ size_t cur_range_length = 0;
+ SequenceNumberSet::const_iterator iter =
+ received_info.missing_packets.begin();
+ QuicPacketSequenceNumber last_missing = *iter;
+ ++iter;
+ for (; iter != received_info.missing_packets.end(); ++iter) {
+ if (cur_range_length != numeric_limits<uint8>::max() &&
+ *iter == (last_missing + 1)) {
+ ++cur_range_length;
+ } else {
+ ack_info.nack_ranges[last_missing - cur_range_length]
+ = cur_range_length;
+ cur_range_length = 0;
+ }
+ ack_info.max_delta = max(ack_info.max_delta, *iter - last_missing);
+ last_missing = *iter;
+ }
+ // Include the last nack range.
+ ack_info.nack_ranges[last_missing - cur_range_length] = cur_range_length;
+ // Include the range to the largest observed.
+ ack_info.max_delta = max(ack_info.max_delta,
+ received_info.largest_observed - last_missing);
+ }
+ return ack_info;
+}
+
bool QuicFramer::ProcessPacketHeader(
QuicPacketHeader* header,
const QuicEncryptedPacket& packet) {
@@ -862,6 +912,10 @@ bool QuicFramer::ProcessPacketHeader(
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
+ if (!visitor_->OnUnauthenticatedHeader(*header)) {
+ return false;
+ }
+
if (!DecryptPayload(*header, packet)) {
set_detailed_error("Unable to decrypt payload.");
return RaiseError(QUIC_DECRYPTION_FAILURE);
@@ -920,7 +974,7 @@ bool QuicFramer::ProcessPacketSequenceNumber(
return true;
}
-bool QuicFramer::ProcessFrameData() {
+bool QuicFramer::ProcessFrameData(const QuicPacketHeader& header) {
if (reader_->IsDoneReading()) {
set_detailed_error("Packet has no frames.");
return RaiseError(QUIC_MISSING_PAYLOAD);
@@ -932,223 +986,107 @@ bool QuicFramer::ProcessFrameData() {
return RaiseError(QUIC_INVALID_FRAME_DATA);
}
- // TODO(jri): Remove this entire if block when support for
- // QUIC version < 10 removed.
- if (version() < QUIC_VERSION_10) {
- // Special frame type processing for QUIC version < 10.
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
+ if (frame_type & kQuicFrameTypeSpecialMask) {
+ // Stream Frame
+ if (frame_type & kQuicFrameTypeStreamMask) {
QuicStreamFrame frame;
if (!ProcessStreamFrame(frame_type, &frame)) {
return RaiseError(QUIC_INVALID_STREAM_DATA);
}
if (!visitor_->OnStreamFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
+ DVLOG(1) << "Visitor asked to stop further processing.";
// Returning true since there was no parsing error.
return true;
}
continue;
}
- frame_type >>= 1;
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
+ // Ack Frame
+ if (frame_type & kQuicFrameTypeAckMask) {
QuicAckFrame frame;
- if (!ProcessAckFrame(&frame)) {
+ if (!ProcessAckFrame(header, frame_type, &frame)) {
return RaiseError(QUIC_INVALID_ACK_DATA);
}
if (!visitor_->OnAckFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
+ DVLOG(1) << "Visitor asked to stop further processing.";
// Returning true since there was no parsing error.
return true;
}
continue;
}
- frame_type >>= 1;
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
+ // Congestion Feedback Frame
+ if (frame_type & kQuicFrameTypeCongestionFeedbackMask) {
QuicCongestionFeedbackFrame frame;
if (!ProcessQuicCongestionFeedbackFrame(&frame)) {
return RaiseError(QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
}
if (!visitor_->OnCongestionFeedbackFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
+ DVLOG(1) << "Visitor asked to stop further processing.";
// Returning true since there was no parsing error.
return true;
}
continue;
}
- frame_type >>= 1;
- switch (frame_type) {
- // STREAM_FRAME, ACK_FRAME, and CONGESTION_FEEDBACK_FRAME are handled
- // above.
- case PADDING_FRAME_OLD:
- // We're done with the packet.
- return true;
-
- case RST_STREAM_FRAME_OLD: {
- QuicRstStreamFrame frame;
- if (!ProcessRstStreamFrame(&frame)) {
- return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
- }
- if (!visitor_->OnRstStreamFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case CONNECTION_CLOSE_FRAME_OLD: {
- QuicConnectionCloseFrame frame;
- if (!ProcessConnectionCloseFrame(&frame)) {
- return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
- }
+ // This was a special frame type that did not match any
+ // of the known ones. Error.
+ set_detailed_error("Illegal frame type.");
+ DLOG(WARNING) << "Illegal frame type: "
+ << static_cast<int>(frame_type);
+ return RaiseError(QUIC_INVALID_FRAME_DATA);
+ }
- if (!visitor_->OnAckFrame(frame.ack_frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
+ switch (frame_type) {
+ case PADDING_FRAME:
+ // We're done with the packet.
+ return true;
- if (!visitor_->OnConnectionCloseFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ case RST_STREAM_FRAME: {
+ QuicRstStreamFrame frame;
+ if (!ProcessRstStreamFrame(&frame)) {
+ return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
}
-
- case GOAWAY_FRAME_OLD: {
- QuicGoAwayFrame goaway_frame;
- if (!ProcessGoAwayFrame(&goaway_frame)) {
- return RaiseError(QUIC_INVALID_GOAWAY_DATA);
- }
- if (!visitor_->OnGoAwayFrame(goaway_frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ if (!visitor_->OnRstStreamFrame(frame)) {
+ DVLOG(1) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
}
-
- set_detailed_error("Illegal frame type.");
- DLOG(WARNING) << "Illegal frame type: "
- << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_DATA);
+ continue;
}
- } else {
- // TODO(jri): Retain this else block when support for
- // QUIC version < 10 removed. Remove above if block.
-
- // Special frame type processing for QUIC version >= 10.
- if (frame_type & kQuicFrameTypeSpecialMask) {
- // Stream Frame
- if (frame_type & kQuicFrameTypeStreamMask) {
- QuicStreamFrame frame;
- if (!ProcessStreamFrame(frame_type, &frame)) {
- return RaiseError(QUIC_INVALID_STREAM_DATA);
- }
- if (!visitor_->OnStreamFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+
+ case CONNECTION_CLOSE_FRAME: {
+ QuicConnectionCloseFrame frame;
+ if (!ProcessConnectionCloseFrame(&frame)) {
+ return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
}
- // Ack Frame
- if (frame_type & kQuicFrameTypeAckMask) {
- QuicAckFrame frame;
- if (!ProcessAckFrame(&frame)) {
- return RaiseError(QUIC_INVALID_ACK_DATA);
- }
- if (!visitor_->OnAckFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ if (!visitor_->OnConnectionCloseFrame(frame)) {
+ DVLOG(1) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
}
+ continue;
+ }
- // Congestion Feedback Frame
- if (frame_type & kQuicFrameTypeCongestionFeedbackMask) {
- QuicCongestionFeedbackFrame frame;
- if (!ProcessQuicCongestionFeedbackFrame(&frame)) {
- return RaiseError(QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
- }
- if (!visitor_->OnCongestionFeedbackFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ case GOAWAY_FRAME: {
+ QuicGoAwayFrame goaway_frame;
+ if (!ProcessGoAwayFrame(&goaway_frame)) {
+ return RaiseError(QUIC_INVALID_GOAWAY_DATA);
+ }
+ if (!visitor_->OnGoAwayFrame(goaway_frame)) {
+ DVLOG(1) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
}
+ continue;
+ }
- // This was a special frame type that did not match any
- // of the known ones. Error.
+ default:
set_detailed_error("Illegal frame type.");
DLOG(WARNING) << "Illegal frame type: "
<< static_cast<int>(frame_type);
return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
-
- switch (frame_type) {
- case PADDING_FRAME:
- // We're done with the packet.
- return true;
-
- case RST_STREAM_FRAME: {
- QuicRstStreamFrame frame;
- if (!ProcessRstStreamFrame(&frame)) {
- return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
- }
- if (!visitor_->OnRstStreamFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case CONNECTION_CLOSE_FRAME: {
- QuicConnectionCloseFrame frame;
- if (!ProcessConnectionCloseFrame(&frame)) {
- return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
- }
-
- if (!visitor_->OnAckFrame(frame.ack_frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
-
- if (!visitor_->OnConnectionCloseFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case GOAWAY_FRAME: {
- QuicGoAwayFrame goaway_frame;
- if (!ProcessGoAwayFrame(&goaway_frame)) {
- return RaiseError(QUIC_INVALID_GOAWAY_DATA);
- }
- if (!visitor_->OnGoAwayFrame(goaway_frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- default:
- set_detailed_error("Illegal frame type.");
- DLOG(WARNING) << "Illegal frame type: "
- << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
}
}
@@ -1159,12 +1097,7 @@ bool QuicFramer::ProcessStreamFrame(uint8 frame_type,
QuicStreamFrame* frame) {
uint8 stream_flags = frame_type;
- // TODO(jri): Remove if block after support for ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- stream_flags >>= 1;
- } else {
- stream_flags &= ~kQuicFrameTypeStreamMask;
- }
+ stream_flags &= ~kQuicFrameTypeStreamMask;
// Read from right to left: StreamID, Offset, Data Length, Fin.
const uint8 stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
@@ -1195,86 +1128,129 @@ bool QuicFramer::ProcessStreamFrame(uint8 frame_type,
return false;
}
+ StringPiece frame_data;
if (has_data_length) {
- if (!reader_->ReadStringPiece16(&frame->data)) {
+ if (!reader_->ReadStringPiece16(&frame_data)) {
set_detailed_error("Unable to read frame data.");
return false;
}
} else {
- if (!reader_->ReadStringPiece(&frame->data, reader_->BytesRemaining())) {
+ if (!reader_->ReadStringPiece(&frame_data, reader_->BytesRemaining())) {
set_detailed_error("Unable to read frame data.");
return false;
}
}
+ // Point frame to the right data.
+ frame->data.Clear();
+ if (!frame_data.empty()) {
+ frame->data.Append(const_cast<char*>(frame_data.data()), frame_data.size());
+ }
return true;
}
-bool QuicFramer::ProcessAckFrame(QuicAckFrame* frame) {
- if (!ProcessSentInfo(&frame->sent_info)) {
+bool QuicFramer::ProcessAckFrame(const QuicPacketHeader& header,
+ uint8 frame_type,
+ QuicAckFrame* frame) {
+ if (!ProcessSentInfo(header, &frame->sent_info)) {
return false;
}
- if (!ProcessReceivedInfo(&frame->received_info)) {
+ if (!ProcessReceivedInfo(frame_type, &frame->received_info)) {
return false;
}
return true;
}
-bool QuicFramer::ProcessReceivedInfo(ReceivedPacketInfo* received_info) {
+bool QuicFramer::ProcessReceivedInfo(uint8 frame_type,
+ ReceivedPacketInfo* received_info) {
+ // Determine the three lengths from the frame type: largest observed length,
+ // missing sequence number length, and missing range length.
+ const QuicSequenceNumberLength missing_sequence_number_length =
+ ReadSequenceNumberLength(frame_type);
+ frame_type >>= kQuicSequenceNumberLengthShift;
+ const QuicSequenceNumberLength largest_observed_sequence_number_length =
+ ReadSequenceNumberLength(frame_type);
+ frame_type >>= kQuicSequenceNumberLengthShift;
+ received_info->is_truncated = frame_type & kQuicAckTruncatedMask;
+ frame_type >>= kQuicAckTruncatedShift;
+ bool has_nacks = frame_type & kQuicHasNacksMask;
+
if (!reader_->ReadBytes(&received_info->entropy_hash, 1)) {
set_detailed_error("Unable to read entropy hash for received packets.");
return false;
}
- if (!ProcessPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
- &received_info->largest_observed)) {
- set_detailed_error("Unable to read largest observed.");
- return false;
+ if (!reader_->ReadBytes(&received_info->largest_observed,
+ largest_observed_sequence_number_length)) {
+ set_detailed_error("Unable to read largest observed.");
+ return false;
}
- uint32 delta_time_largest_observed_us;
- if (!reader_->ReadUInt32(&delta_time_largest_observed_us)) {
+ uint64 delta_time_largest_observed_us;
+ if (!reader_->ReadUFloat16(&delta_time_largest_observed_us)) {
set_detailed_error("Unable to read delta time largest observed.");
return false;
}
- if (delta_time_largest_observed_us == kInvalidDeltaTime) {
+ if (delta_time_largest_observed_us == kUFloat16MaxValue) {
received_info->delta_time_largest_observed = QuicTime::Delta::Infinite();
} else {
received_info->delta_time_largest_observed =
QuicTime::Delta::FromMicroseconds(delta_time_largest_observed_us);
}
- uint8 num_missing_packets;
- if (!reader_->ReadBytes(&num_missing_packets, 1)) {
- set_detailed_error("Unable to read num missing packets.");
+ if (!has_nacks) {
+ return true;
+ }
+
+ uint8 num_missing_ranges;
+ if (!reader_->ReadBytes(&num_missing_ranges, 1)) {
+ set_detailed_error("Unable to read num missing packet ranges.");
return false;
}
- for (int i = 0; i < num_missing_packets; ++i) {
- QuicPacketSequenceNumber sequence_number;
- if (!ProcessPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
- &sequence_number)) {
- set_detailed_error("Unable to read sequence number in missing packets.");
+ QuicPacketSequenceNumber last_sequence_number =
+ received_info->largest_observed;
+ for (size_t i = 0; i < num_missing_ranges; ++i) {
+ QuicPacketSequenceNumber missing_delta = 0;
+ if (!reader_->ReadBytes(&missing_delta, missing_sequence_number_length)) {
+ set_detailed_error("Unable to read missing sequence number delta.");
return false;
}
- received_info->missing_packets.insert(sequence_number);
+ last_sequence_number -= missing_delta;
+ QuicPacketSequenceNumber range_length = 0;
+ if (!reader_->ReadBytes(&range_length, PACKET_1BYTE_SEQUENCE_NUMBER)) {
+ set_detailed_error("Unable to read missing sequence number range.");
+ return false;
+ }
+ for (size_t i = 0; i <= range_length; ++i) {
+ received_info->missing_packets.insert(last_sequence_number - i);
+ }
+ // Subtract an extra 1 to ensure ranges are represented efficiently and
+ // can't overlap by 1 sequence number. This allows a missing_delta of 0
+ // to represent an adjacent nack range.
+ last_sequence_number -= (range_length + 1);
}
return true;
}
-bool QuicFramer::ProcessSentInfo(SentPacketInfo* sent_info) {
+bool QuicFramer::ProcessSentInfo(const QuicPacketHeader& header,
+ SentPacketInfo* sent_info) {
if (!reader_->ReadBytes(&sent_info->entropy_hash, 1)) {
set_detailed_error("Unable to read entropy hash for sent packets.");
return false;
}
- if (!ProcessPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
- &sent_info->least_unacked)) {
- set_detailed_error("Unable to read least unacked.");
+ QuicPacketSequenceNumber least_unacked_delta = 0;
+ if (!reader_->ReadBytes(&least_unacked_delta,
+ header.public_header.sequence_number_length)) {
+ set_detailed_error("Unable to read least unacked delta.");
return false;
}
+ DCHECK_GE(header.packet_sequence_number, least_unacked_delta);
+ sent_info->least_unacked =
+ header.packet_sequence_number - least_unacked_delta;
return true;
}
@@ -1324,7 +1300,7 @@ bool QuicFramer::ProcessQuicCongestionFeedbackFrame(
inter_arrival->received_packet_times.insert(
make_pair(smallest_received, time_received));
- for (int i = 0; i < num_received_packets - 1; ++i) {
+ for (uint8 i = 0; i < num_received_packets - 1; ++i) {
uint16 sequence_delta;
if (!reader_->ReadUInt16(&sequence_delta)) {
set_detailed_error(
@@ -1362,6 +1338,7 @@ bool QuicFramer::ProcessQuicCongestionFeedbackFrame(
"Unable to read accumulated number of lost packets.");
return false;
}
+ // TODO(ianswett): Remove receive window, since it's constant.
uint16 receive_window = 0;
if (!reader_->ReadUInt16(&receive_window)) {
set_detailed_error("Unable to read receive window.");
@@ -1433,11 +1410,6 @@ bool QuicFramer::ProcessConnectionCloseFrame(QuicConnectionCloseFrame* frame) {
}
frame->error_details = error_details.as_string();
- if (!ProcessAckFrame(&frame->ack_frame)) {
- DLOG(WARNING) << "Unable to process ack frame.";
- return false;
- }
-
return true;
}
@@ -1552,9 +1524,7 @@ QuicEncryptedPacket* QuicFramer::EncryptPacket(
size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) {
// In order to keep the code simple, we don't have the current encryption
- // level to hand. At the moment, the NullEncrypter has a tag length of 16
- // bytes and AES-GCM has a tag length of 12. We take the minimum plaintext
- // length just to be safe.
+ // level to hand. Both the NullEncrypter and AES-GCM have a tag length of 12.
size_t min_plaintext_size = ciphertext_size;
for (int i = ENCRYPTION_NONE; i < NUM_ENCRYPTION_LEVELS; i++) {
@@ -1613,19 +1583,36 @@ bool QuicFramer::DecryptPayload(const QuicPacketHeader& header,
return true;
}
-size_t QuicFramer::ComputeFrameLength(const QuicFrame& frame,
- bool last_frame_in_packet) {
+size_t QuicFramer::GetAckFrameSize(
+ const QuicAckFrame& ack,
+ QuicSequenceNumberLength sequence_number_length) {
+ AckFrameInfo ack_info = GetAckFrameInfo(ack);
+ QuicSequenceNumberLength largest_observed_length =
+ GetMinSequenceNumberLength(ack.received_info.largest_observed);
+ QuicSequenceNumberLength missing_sequence_number_length =
+ GetMinSequenceNumberLength(ack_info.max_delta);
+
+ return GetMinAckFrameSize(quic_version_,
+ sequence_number_length,
+ largest_observed_length) +
+ (ack_info.nack_ranges.empty() ? 0 : kNumberOfMissingPacketsSize) +
+ ack_info.nack_ranges.size() *
+ (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER);
+}
+
+size_t QuicFramer::ComputeFrameLength(
+ const QuicFrame& frame,
+ bool last_frame_in_packet,
+ QuicSequenceNumberLength sequence_number_length) {
switch (frame.type) {
case STREAM_FRAME:
return GetMinStreamFrameSize(quic_version_,
frame.stream_frame->stream_id,
frame.stream_frame->offset,
last_frame_in_packet) +
- frame.stream_frame->data.size();
+ frame.stream_frame->data.TotalBufferSize();
case ACK_FRAME: {
- const QuicAckFrame& ack = *frame.ack_frame;
- return GetMinAckFrameSize() + PACKET_6BYTE_SEQUENCE_NUMBER *
- ack.received_info.missing_packets.size();
+ return GetAckFrameSize(*frame.ack_frame, sequence_number_length);
}
case CONGESTION_FEEDBACK_FRAME: {
size_t len = kQuicFrameTypeSize;
@@ -1656,7 +1643,7 @@ size_t QuicFramer::ComputeFrameLength(const QuicFrame& frame,
break;
default:
set_detailed_error("Illegal feedback type.");
- DLOG(INFO) << "Illegal feedback type: " << congestion_feedback.type;
+ DVLOG(1) << "Illegal feedback type: " << congestion_feedback.type;
break;
}
return len;
@@ -1664,13 +1651,9 @@ size_t QuicFramer::ComputeFrameLength(const QuicFrame& frame,
case RST_STREAM_FRAME:
return GetMinRstStreamFrameSize() +
frame.rst_stream_frame->error_details.size();
- case CONNECTION_CLOSE_FRAME: {
- const QuicAckFrame& ack = frame.connection_close_frame->ack_frame;
+ case CONNECTION_CLOSE_FRAME:
return GetMinConnectionCloseFrameSize() +
- frame.connection_close_frame->error_details.size() +
- PACKET_6BYTE_SEQUENCE_NUMBER *
- ack.received_info.missing_packets.size();
- }
+ frame.connection_close_frame->error_details.size();
case GOAWAY_FRAME:
return GetMinGoAwayFrameSize() + frame.goaway_frame->reason_phrase.size();
case PADDING_FRAME:
@@ -1712,45 +1695,18 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
// stream id 2 bits.
type_byte <<= kQuicStreamIdShift;
type_byte |= GetStreamIdSize(frame.stream_frame->stream_id) - 1;
-
- // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- type_byte <<= 1; // Leaves the last bit as a 0.
- } else {
- type_byte |= kQuicFrameTypeStreamMask; // Set Stream Frame Type to 1.
- }
- break;
- }
- case ACK_FRAME: {
- // TODO(ianswett): Use extra 5 bits in the ack framing.
- // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- type_byte = 0x01;
- } else {
- type_byte = kQuicFrameTypeAckMask;
- }
+ type_byte |= kQuicFrameTypeStreamMask; // Set Stream Frame Type to 1.
break;
}
+ case ACK_FRAME:
+ return true;
case CONGESTION_FEEDBACK_FRAME: {
// TODO(ianswett): Use extra 5 bits in the congestion feedback framing.
- // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- type_byte = 0x03;
- } else {
- type_byte = kQuicFrameTypeCongestionFeedbackMask;
- }
+ type_byte = kQuicFrameTypeCongestionFeedbackMask;
break;
}
default:
type_byte = frame.type;
- // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- if (type_byte > 0) {
- type_byte += 3;
- }
- type_byte = (type_byte << kQuicDefaultFrameTypeShift) |
- kQuicDefaultFrameTypeMask;
- }
break;
}
@@ -1801,16 +1757,24 @@ bool QuicFramer::AppendStreamFramePayload(
return false;
}
if (!last_frame_in_packet) {
- if (!writer->WriteUInt16(frame.data.size())) {
+ if (!writer->WriteUInt16(frame.data.TotalBufferSize())) {
return false;
}
}
- if (!writer->WriteBytes(frame.data.data(), frame.data.size())) {
+
+ if (!writer->WriteIOVector(frame.data)) {
return false;
}
return true;
}
+// static
+bool QuicFramer::HasVersionFlag(const QuicEncryptedPacket& packet) {
+ return packet.length() > 0 &&
+ (packet.data()[0] & PACKET_PUBLIC_FLAGS_VERSION) != 0;
+}
+
+// static
QuicPacketSequenceNumber QuicFramer::CalculateLargestObserved(
const SequenceNumberSet& missing_packets,
SequenceNumberSet::const_iterator largest_written) {
@@ -1828,77 +1792,143 @@ QuicPacketSequenceNumber QuicFramer::CalculateLargestObserved(
return *largest_written;
}
-// TODO(ianswett): Use varints or another more compact approach for all deltas.
-bool QuicFramer::AppendAckFramePayload(
+void QuicFramer::set_version(const QuicVersion version) {
+ DCHECK(IsSupportedVersion(version));
+ quic_version_ = version;
+}
+
+bool QuicFramer::AppendAckFramePayloadAndTypeByte(
+ const QuicPacketHeader& header,
const QuicAckFrame& frame,
QuicDataWriter* writer) {
+ AckFrameInfo ack_info = GetAckFrameInfo(frame);
+ QuicPacketSequenceNumber ack_largest_observed =
+ frame.received_info.largest_observed;
+ QuicSequenceNumberLength largest_observed_length =
+ GetMinSequenceNumberLength(ack_largest_observed);
+ QuicSequenceNumberLength missing_sequence_number_length =
+ GetMinSequenceNumberLength(ack_info.max_delta);
+ // Determine whether we need to truncate ranges.
+ size_t available_range_bytes = writer->capacity() - writer->length() -
+ GetMinAckFrameSize(quic_version_,
+ header.public_header.sequence_number_length,
+ largest_observed_length);
+ size_t max_num_ranges = available_range_bytes /
+ (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER);
+ max_num_ranges =
+ min(static_cast<size_t>(numeric_limits<uint8>::max()), max_num_ranges);
+ bool truncated = ack_info.nack_ranges.size() > max_num_ranges;
+ DVLOG_IF(1, truncated) << "Truncating ack from "
+ << ack_info.nack_ranges.size() << " ranges to "
+ << max_num_ranges;
+
+ // Write out the type byte by setting the low order bits and doing shifts
+ // to make room for the next bit flags to be set.
+ // Whether there are any nacks.
+ uint8 type_byte = ack_info.nack_ranges.empty() ? 0 : kQuicHasNacksMask;
+
+ // truncating bit.
+ type_byte <<= kQuicAckTruncatedShift;
+ type_byte |= truncated ? kQuicAckTruncatedMask : 0;
+
+ // Largest observed sequence number length.
+ type_byte <<= kQuicSequenceNumberLengthShift;
+ type_byte |= GetSequenceNumberFlags(largest_observed_length);
+
+ // Missing sequence number length.
+ type_byte <<= kQuicSequenceNumberLengthShift;
+ type_byte |= GetSequenceNumberFlags(missing_sequence_number_length);
+
+ type_byte |= kQuicFrameTypeAckMask;
+
+ if (!writer->WriteUInt8(type_byte)) {
+ return false;
+ }
+
// TODO(satyamshekhar): Decide how often we really should send this
// entropy_hash update.
if (!writer->WriteUInt8(frame.sent_info.entropy_hash)) {
return false;
}
- if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
- frame.sent_info.least_unacked, writer)) {
+ DCHECK_GE(header.packet_sequence_number, frame.sent_info.least_unacked);
+ const QuicPacketSequenceNumber least_unacked_delta =
+ header.packet_sequence_number - frame.sent_info.least_unacked;
+ if (!AppendPacketSequenceNumber(header.public_header.sequence_number_length,
+ least_unacked_delta, writer)) {
return false;
}
- size_t received_entropy_offset = writer->length();
- if (!writer->WriteUInt8(frame.received_info.entropy_hash)) {
+ const ReceivedPacketInfo& received_info = frame.received_info;
+ QuicPacketEntropyHash ack_entropy_hash = received_info.entropy_hash;
+ NackRangeMap::reverse_iterator ack_iter = ack_info.nack_ranges.rbegin();
+ if (truncated) {
+ // Skip the nack ranges which the truncated ack won't include and set
+ // a correct largest observed for the truncated ack.
+ for (size_t i = 1; i < (ack_info.nack_ranges.size() - max_num_ranges);
+ ++i) {
+ ++ack_iter;
+ }
+ // If the last range is followed by acks, include them.
+ // If the last range is followed by another range, specify the end of the
+ // range as the largest_observed.
+ ack_largest_observed = ack_iter->first - 1;
+ // Also update the entropy so it matches the largest observed.
+ ack_entropy_hash = entropy_calculator_->EntropyHash(ack_largest_observed);
+ ++ack_iter;
+ }
+
+ if (!writer->WriteUInt8(ack_entropy_hash)) {
return false;
}
- size_t largest_observed_offset = writer->length();
- if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
- frame.received_info.largest_observed,
- writer)) {
+ if (!AppendPacketSequenceNumber(largest_observed_length,
+ ack_largest_observed, writer)) {
return false;
}
- uint32 delta_time_largest_observed_us = kInvalidDeltaTime;
- if (!frame.received_info.delta_time_largest_observed.IsInfinite()) {
+
+ uint64 delta_time_largest_observed_us = kUFloat16MaxValue;
+ if (!received_info.delta_time_largest_observed.IsInfinite()) {
+ DCHECK_LE(0u,
+ frame.received_info.delta_time_largest_observed.ToMicroseconds());
delta_time_largest_observed_us =
- frame.received_info.delta_time_largest_observed.ToMicroseconds();
+ received_info.delta_time_largest_observed.ToMicroseconds();
}
- size_t delta_time_largest_observed_offset = writer->length();
- if (!writer->WriteUInt32(delta_time_largest_observed_us)) {
+ if (!writer->WriteUFloat16(delta_time_largest_observed_us)) {
return false;
}
- // We don't check for overflowing uint8 here, because we only can fit 192 acks
- // per packet, so if we overflow we will be truncated.
- uint8 num_missing_packets = frame.received_info.missing_packets.size();
- size_t num_missing_packets_offset = writer->length();
- if (!writer->WriteBytes(&num_missing_packets, 1)) {
+ if (ack_info.nack_ranges.empty()) {
+ return true;
+ }
+
+ const uint8 num_missing_ranges =
+ min(ack_info.nack_ranges.size(), max_num_ranges);
+ if (!writer->WriteBytes(&num_missing_ranges, 1)) {
return false;
}
- SequenceNumberSet::const_iterator it =
- frame.received_info.missing_packets.begin();
- int num_missing_packets_written = 0;
- for (; it != frame.received_info.missing_packets.end(); ++it) {
- if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
- *it, writer)) {
- // We are truncating.
- QuicPacketSequenceNumber largest_observed =
- CalculateLargestObserved(frame.received_info.missing_packets, --it);
- // Overwrite entropy hash for received packets.
- writer->WriteUInt8ToOffset(
- entropy_calculator_->EntropyHash(largest_observed),
- received_entropy_offset);
- // Overwrite largest_observed.
- writer->WriteUInt48ToOffset(largest_observed & k6ByteSequenceNumberMask,
- largest_observed_offset);
- writer->WriteUInt32ToOffset(kInvalidDeltaTime,
- delta_time_largest_observed_offset);
- writer->WriteUInt8ToOffset(num_missing_packets_written,
- num_missing_packets_offset);
- return true;
+ int num_ranges_written = 0;
+ QuicPacketSequenceNumber last_sequence_written = ack_largest_observed;
+ for (; ack_iter != ack_info.nack_ranges.rend(); ++ack_iter) {
+ // Calculate the delta to the last number in the range.
+ QuicPacketSequenceNumber missing_delta =
+ last_sequence_written - (ack_iter->first + ack_iter->second);
+ if (!AppendPacketSequenceNumber(missing_sequence_number_length,
+ missing_delta, writer)) {
+ return false;
+ }
+ if (!AppendPacketSequenceNumber(PACKET_1BYTE_SEQUENCE_NUMBER,
+ ack_iter->second, writer)) {
+ return false;
}
- ++num_missing_packets_written;
- DCHECK_GE(numeric_limits<uint8>::max(), num_missing_packets_written);
+ // Subtract 1 so a missing_delta of 0 means an adjacent range.
+ last_sequence_written = ack_iter->first - 1;
+ ++num_ranges_written;
}
+ DCHECK_EQ(num_missing_ranges, num_ranges_written);
return true;
}
@@ -2020,7 +2050,6 @@ bool QuicFramer::AppendConnectionCloseFramePayload(
if (!writer->WriteStringPiece16(frame.error_details)) {
return false;
}
- AppendAckFramePayload(frame.ack_frame, writer);
return true;
}
@@ -2041,7 +2070,7 @@ bool QuicFramer::AppendGoAwayFramePayload(const QuicGoAwayFrame& frame,
}
bool QuicFramer::RaiseError(QuicErrorCode error) {
- DLOG(INFO) << detailed_error_;
+ DVLOG(1) << detailed_error_;
set_error(error);
visitor_->OnError(this);
reader_.reset(NULL);