| Index: net/quic/quic_framer.cc
|
| diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
|
| index 90d9a89b829ab59946dd2797bb42ad2748e40af3..28491db7d1ba9846506ecbe8b190ab617a55d3ff 100644
|
| --- a/net/quic/quic_framer.cc
|
| +++ b/net/quic/quic_framer.cc
|
| @@ -198,6 +198,13 @@ size_t QuicFramer::GetMinAckFrameSize(
|
| }
|
|
|
| // static
|
| +size_t QuicFramer::GetStopWaitingFrameSize(
|
| + QuicSequenceNumberLength sequence_number_length) {
|
| + return kQuicFrameTypeSize + kQuicEntropyHashSize +
|
| + sequence_number_length;
|
| +}
|
| +
|
| +// static
|
| size_t QuicFramer::GetMinRstStreamFrameSize(QuicVersion quic_version) {
|
| if (quic_version > QUIC_VERSION_13) {
|
| return kQuicFrameTypeSize + kQuicMaxStreamIdSize +
|
| @@ -374,9 +381,21 @@ SerializedPacket QuicFramer::BuildDataPacket(
|
| }
|
| break;
|
| case CONGESTION_FEEDBACK_FRAME:
|
| - if (!AppendQuicCongestionFeedbackFrame(
|
| + if (!AppendCongestionFeedbackFrame(
|
| *frame.congestion_feedback_frame, &writer)) {
|
| - LOG(DFATAL) << "AppendQuicCongestionFeedbackFrame failed";
|
| + LOG(DFATAL) << "AppendCongestionFeedbackFrame failed";
|
| + return kNoPacket;
|
| + }
|
| + break;
|
| + case STOP_WAITING_FRAME:
|
| + if (quic_version_ <= QUIC_VERSION_15) {
|
| + LOG(DFATAL) << "Attempt to add a StopWaitingFrame in "
|
| + << QuicVersionToString(quic_version_);
|
| + return kNoPacket;
|
| + }
|
| + if (!AppendStopWaitingFrame(
|
| + header, *frame.stop_waiting_frame, &writer)) {
|
| + LOG(DFATAL) << "AppendStopWaitingFrame failed";
|
| return kNoPacket;
|
| }
|
| break;
|
| @@ -1228,6 +1247,24 @@ bool QuicFramer::ProcessFrameData(const QuicPacketHeader& header) {
|
| continue;
|
| }
|
|
|
| + case STOP_WAITING_FRAME: {
|
| + if (quic_version_ <= QUIC_VERSION_15) {
|
| + LOG(DFATAL) << "Trying to read a StopWaiting in "
|
| + << QuicVersionToString(quic_version_);
|
| + return RaiseError(QUIC_INTERNAL_ERROR);
|
| + }
|
| + QuicStopWaitingFrame stop_waiting_frame;
|
| + if (!ProcessStopWaitingFrame(header, &stop_waiting_frame)) {
|
| + return RaiseError(QUIC_INVALID_STOP_WAITING_DATA);
|
| + }
|
| + if (!visitor_->OnStopWaitingFrame(stop_waiting_frame)) {
|
| + DVLOG(1) << "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: "
|
| @@ -1298,8 +1335,10 @@ bool QuicFramer::ProcessStreamFrame(uint8 frame_type,
|
| bool QuicFramer::ProcessAckFrame(const QuicPacketHeader& header,
|
| uint8 frame_type,
|
| QuicAckFrame* frame) {
|
| - if (!ProcessSentInfo(header, &frame->sent_info)) {
|
| - return false;
|
| + if (quic_version_ <= QUIC_VERSION_15) {
|
| + if (!ProcessStopWaitingFrame(header, &frame->sent_info)) {
|
| + return false;
|
| + }
|
| }
|
| if (!ProcessReceivedInfo(frame_type, &frame->received_info)) {
|
| return false;
|
| @@ -1401,9 +1440,9 @@ bool QuicFramer::ProcessReceivedInfo(uint8 frame_type,
|
| return true;
|
| }
|
|
|
| -bool QuicFramer::ProcessSentInfo(const QuicPacketHeader& header,
|
| - SentPacketInfo* sent_info) {
|
| - if (!reader_->ReadBytes(&sent_info->entropy_hash, 1)) {
|
| +bool QuicFramer::ProcessStopWaitingFrame(const QuicPacketHeader& header,
|
| + QuicStopWaitingFrame* stop_waiting) {
|
| + if (!reader_->ReadBytes(&stop_waiting->entropy_hash, 1)) {
|
| set_detailed_error("Unable to read entropy hash for sent packets.");
|
| return false;
|
| }
|
| @@ -1415,7 +1454,7 @@ bool QuicFramer::ProcessSentInfo(const QuicPacketHeader& header,
|
| return false;
|
| }
|
| DCHECK_GE(header.packet_sequence_number, least_unacked_delta);
|
| - sent_info->least_unacked =
|
| + stop_waiting->least_unacked =
|
| header.packet_sequence_number - least_unacked_delta;
|
|
|
| return true;
|
| @@ -1861,6 +1900,8 @@ size_t QuicFramer::ComputeFrameLength(
|
| }
|
| return len;
|
| }
|
| + case STOP_WAITING_FRAME:
|
| + return GetStopWaitingFrameSize(sequence_number_length);
|
| case RST_STREAM_FRAME:
|
| return GetMinRstStreamFrameSize(quic_version_) +
|
| frame.rst_stream_frame->error_details.size();
|
| @@ -1987,7 +2028,7 @@ bool QuicFramer::AppendStreamFrame(
|
|
|
| // static
|
| void QuicFramer::set_version(const QuicVersion version) {
|
| - DCHECK(IsSupportedVersion(version));
|
| + DCHECK(IsSupportedVersion(version)) << QuicVersionToString(version);
|
| quic_version_ = version;
|
| }
|
|
|
| @@ -2040,27 +2081,10 @@ bool QuicFramer::AppendAckFrameAndTypeByte(
|
| 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;
|
| - }
|
| -
|
| - 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;
|
| - const QuicPacketSequenceNumber length_shift =
|
| - header.public_header.sequence_number_length * 8;
|
| - if (least_unacked_delta >> length_shift > 0) {
|
| - LOG(DFATAL) << "sequence_number_length "
|
| - << header.public_header.sequence_number_length
|
| - << " is too small for least_unacked_delta: "
|
| - << least_unacked_delta;
|
| - return false;
|
| - }
|
| - if (!AppendPacketSequenceNumber(header.public_header.sequence_number_length,
|
| - least_unacked_delta, writer)) {
|
| - return false;
|
| + if (quic_version_ <= QUIC_VERSION_15) {
|
| + if (!AppendStopWaitingFrame(header, frame.sent_info, writer)) {
|
| + return false;
|
| + }
|
| }
|
|
|
| const ReceivedPacketInfo& received_info = frame.received_info;
|
| @@ -2160,7 +2184,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte(
|
| return true;
|
| }
|
|
|
| -bool QuicFramer::AppendQuicCongestionFeedbackFrame(
|
| +bool QuicFramer::AppendCongestionFeedbackFrame(
|
| const QuicCongestionFeedbackFrame& frame,
|
| QuicDataWriter* writer) {
|
| if (!writer->WriteBytes(&frame.type, 1)) {
|
| @@ -2255,6 +2279,37 @@ bool QuicFramer::AppendQuicCongestionFeedbackFrame(
|
| return true;
|
| }
|
|
|
| +bool QuicFramer::AppendStopWaitingFrame(
|
| + const QuicPacketHeader& header,
|
| + const QuicStopWaitingFrame& frame,
|
| + QuicDataWriter* writer) {
|
| + DCHECK_GE(header.packet_sequence_number, frame.least_unacked);
|
| + const QuicPacketSequenceNumber least_unacked_delta =
|
| + header.packet_sequence_number - frame.least_unacked;
|
| + const QuicPacketSequenceNumber length_shift =
|
| + header.public_header.sequence_number_length * 8;
|
| + if (!writer->WriteUInt8(frame.entropy_hash)) {
|
| + LOG(DFATAL) << " hash failed";
|
| + return false;
|
| + }
|
| +
|
| + if (least_unacked_delta >> length_shift > 0) {
|
| + LOG(DFATAL) << "sequence_number_length "
|
| + << header.public_header.sequence_number_length
|
| + << " is too small for least_unacked_delta: "
|
| + << least_unacked_delta;
|
| + return false;
|
| + }
|
| + if (!AppendPacketSequenceNumber(header.public_header.sequence_number_length,
|
| + least_unacked_delta, writer)) {
|
| + LOG(DFATAL) << " seq failed: "
|
| + << header.public_header.sequence_number_length;
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| bool QuicFramer::AppendRstStreamFrame(
|
| const QuicRstStreamFrame& frame,
|
| QuicDataWriter* writer) {
|
|
|