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

Unified Diff: net/quic/quic_framer.cc

Issue 23464033: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix valgrind error Created 7 years, 3 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
« no previous file with comments | « net/quic/quic_crypto_client_stream.cc ('k') | net/quic/quic_framer_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_framer.cc
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index 6004e3bf7615a2f9cfabda47bc915b5a5e4a5856..4160ddcb944d26dbed814b1b37f040618d44d33a 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -20,6 +20,19 @@ 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);
@@ -33,8 +46,36 @@ const QuicPacketSequenceNumber k1ByteSequenceNumberMask =
const QuicGuid k1ByteGuidMask = GG_UINT64_C(0x00000000000000FF);
const QuicGuid k4ByteGuidMask = GG_UINT64_C(0x00000000FFFFFFFF);
+// 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.
+//
+// Regular Frame Types use the Frame Type byte simply. Currently defined
+// Regular Frame Types are:
+// Padding : 0b 00000000 (0x00)
+// ResetStream : 0b 00000001 (0x01)
+// ConnectionClose : 0b 00000010 (0x02)
+// GoAway : 0b 00000011 (0x03)
+//
+// Special Frame Types encode both a Frame Type and corresponding flags
+// all in the Frame Type byte. Currently defined Special Frame Types are:
+// Stream : 0b 1xxxxxxx
+// Ack : 0b 01xxxxxx
+// CongestionFeedback : 0b 001xxxxx
+//
+// Semantics of the flag bits above (the x bits) depends on the frame type.
+
+// Masks to determine if the frame type is a special use
+// and for specific special frame types.
+const uint8 kQuicFrameTypeSpecialMask = 0xE0; // 0b 11100000
+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.
@@ -891,62 +932,16 @@ bool QuicFramer::ProcessFrameData() {
return RaiseError(QUIC_INVALID_FRAME_DATA);
}
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
- 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;
- }
-
- frame_type >>= 1;
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
- 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;
- }
-
- frame_type >>= 1;
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
- 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;
- }
-
- frame_type >>= 1;
-
- switch (frame_type) {
- // STREAM_FRAME, ACK_FRAME, and CONGESTION_FEEDBACK_FRAME are handled
- // above.
- 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);
+ // 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) {
+ QuicStreamFrame frame;
+ if (!ProcessStreamFrame(frame_type, &frame)) {
+ return RaiseError(QUIC_INVALID_STREAM_DATA);
}
- if (!visitor_->OnRstStreamFrame(frame)) {
+ if (!visitor_->OnStreamFrame(frame)) {
DLOG(INFO) << "Visitor asked to stop further processing.";
// Returning true since there was no parsing error.
return true;
@@ -954,19 +949,27 @@ bool QuicFramer::ProcessFrameData() {
continue;
}
- case CONNECTION_CLOSE_FRAME: {
- QuicConnectionCloseFrame frame;
- if (!ProcessConnectionCloseFrame(&frame)) {
- return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
+ frame_type >>= 1;
+ if ((frame_type & kQuicFrameType0BitMask) == 0) {
+ QuicAckFrame frame;
+ if (!ProcessAckFrame(&frame)) {
+ return RaiseError(QUIC_INVALID_ACK_DATA);
}
-
- if (!visitor_->OnAckFrame(frame.ack_frame)) {
+ 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)) {
+ frame_type >>= 1;
+ if ((frame_type & kQuicFrameType0BitMask) == 0) {
+ 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;
@@ -974,23 +977,178 @@ bool QuicFramer::ProcessFrameData() {
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.
+ 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;
}
- continue;
+
+ case CONNECTION_CLOSE_FRAME_OLD: {
+ 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_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;
+ }
+
+ set_detailed_error("Illegal frame type.");
+ DLOG(WARNING) << "Illegal frame type: "
+ << static_cast<int>(frame_type);
+ return RaiseError(QUIC_INVALID_FRAME_DATA);
}
+ } 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;
+ }
- set_detailed_error("Illegal frame type.");
- DLOG(WARNING) << "Illegal frame type: "
- << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_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;
+ }
+
+ // 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;
+ }
+
+ // 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);
+ }
+
+ 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);
+ }
}
}
@@ -999,7 +1157,15 @@ bool QuicFramer::ProcessFrameData() {
bool QuicFramer::ProcessStreamFrame(uint8 frame_type,
QuicStreamFrame* frame) {
- uint8 stream_flags = frame_type >> 1;
+ 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;
+ }
+
// Read from right to left: StreamID, Offset, Data Length, Fin.
const uint8 stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
stream_flags >>= kQuicStreamIdShift;
@@ -1547,22 +1713,44 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
type_byte <<= kQuicStreamIdShift;
type_byte |= GetStreamIdSize(frame.stream_frame->stream_id) - 1;
- type_byte <<= 1; // Leaves the last bit as a 0.
+ // 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.
- type_byte = 0x01;
+ // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
+ if (version() < QUIC_VERSION_10) {
+ type_byte = 0x01;
+ } else {
+ type_byte = kQuicFrameTypeAckMask;
+ }
break;
}
case CONGESTION_FEEDBACK_FRAME: {
// TODO(ianswett): Use extra 5 bits in the congestion feedback framing.
- type_byte = 0x03;
+ // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
+ if (version() < QUIC_VERSION_10) {
+ type_byte = 0x03;
+ } else {
+ type_byte = kQuicFrameTypeCongestionFeedbackMask;
+ }
break;
}
default:
- type_byte =
- frame.type << kQuicDefaultFrameTypeShift | kQuicDefaultFrameTypeMask;
+ 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;
}
« no previous file with comments | « net/quic/quic_crypto_client_stream.cc ('k') | net/quic/quic_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698