1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/quic/quic_protocol.h"
7 #include "base/stl_util.h"
8 #include "net/quic/quic_utils.h"
10 using base::StringPiece
;
12 using std::numeric_limits
;
18 size_t GetPacketHeaderSize(QuicPacketHeader header
) {
19 return GetPacketHeaderSize(header
.public_header
.guid_length
,
20 header
.public_header
.version_flag
,
21 header
.public_header
.sequence_number_length
,
22 header
.is_in_fec_group
);
25 size_t GetPacketHeaderSize(QuicGuidLength guid_length
,
27 QuicSequenceNumberLength sequence_number_length
,
28 InFecGroup is_in_fec_group
) {
29 return kPublicFlagsSize
+ guid_length
+
30 (include_version
? kQuicVersionSize
: 0) + sequence_number_length
+
31 kPrivateFlagsSize
+ (is_in_fec_group
== IN_FEC_GROUP
? kFecGroupSize
: 0);
34 size_t GetPublicResetPacketSize() {
35 return kPublicFlagsSize
+ PACKET_8BYTE_GUID
+ kPublicResetNonceSize
+
36 PACKET_6BYTE_SEQUENCE_NUMBER
;
39 size_t GetStartOfFecProtectedData(
40 QuicGuidLength guid_length
,
42 QuicSequenceNumberLength sequence_number_length
) {
43 return GetPacketHeaderSize(
44 guid_length
, include_version
, sequence_number_length
, IN_FEC_GROUP
);
47 size_t GetStartOfEncryptedData(
48 QuicGuidLength guid_length
,
50 QuicSequenceNumberLength sequence_number_length
) {
51 // Don't include the fec size, since encryption starts before private flags.
52 return GetPacketHeaderSize(
53 guid_length
, include_version
, sequence_number_length
, NOT_IN_FEC_GROUP
) -
57 QuicPacketPublicHeader::QuicPacketPublicHeader()
59 guid_length(PACKET_8BYTE_GUID
),
62 sequence_number_length(PACKET_6BYTE_SEQUENCE_NUMBER
) {
65 QuicPacketPublicHeader::QuicPacketPublicHeader(
66 const QuicPacketPublicHeader
& other
)
68 guid_length(other
.guid_length
),
69 reset_flag(other
.reset_flag
),
70 version_flag(other
.version_flag
),
71 sequence_number_length(other
.sequence_number_length
),
72 versions(other
.versions
) {
75 QuicPacketPublicHeader::~QuicPacketPublicHeader() {}
77 QuicPacketHeader::QuicPacketHeader()
81 packet_sequence_number(0),
82 is_in_fec_group(NOT_IN_FEC_GROUP
),
86 QuicPacketHeader::QuicPacketHeader(const QuicPacketPublicHeader
& header
)
87 : public_header(header
),
91 packet_sequence_number(0),
92 is_in_fec_group(NOT_IN_FEC_GROUP
),
96 QuicStreamFrame::QuicStreamFrame() {}
98 QuicStreamFrame::QuicStreamFrame(const QuicStreamFrame
& frame
)
99 : stream_id(frame
.stream_id
),
101 offset(frame
.offset
),
103 notifier(frame
.notifier
) {
106 QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id
,
108 QuicStreamOffset offset
,
110 : stream_id(stream_id
),
117 string
* QuicStreamFrame::GetDataAsString() const {
118 string
* data_string
= new string();
119 data_string
->reserve(data
.TotalBufferSize());
120 for (size_t i
= 0; i
< data
.Size(); ++i
) {
121 data_string
->append(static_cast<char*>(data
.iovec()[i
].iov_base
),
122 data
.iovec()[i
].iov_len
);
124 DCHECK_EQ(data_string
->size(), data
.TotalBufferSize());
128 uint32
MakeQuicTag(char a
, char b
, char c
, char d
) {
129 return static_cast<uint32
>(a
) |
130 static_cast<uint32
>(b
) << 8 |
131 static_cast<uint32
>(c
) << 16 |
132 static_cast<uint32
>(d
) << 24;
135 QuicVersionVector
QuicSupportedVersions() {
136 QuicVersionVector supported_versions
;
137 for (size_t i
= 0; i
< arraysize(kSupportedQuicVersions
); ++i
) {
138 supported_versions
.push_back(kSupportedQuicVersions
[i
]);
140 return supported_versions
;
143 QuicTag
QuicVersionToQuicTag(const QuicVersion version
) {
145 case QUIC_VERSION_12
:
146 return MakeQuicTag('Q', '0', '1', '2');
147 case QUIC_VERSION_13
:
148 return MakeQuicTag('Q', '0', '1', '3');
150 // This shold be an ERROR because we should never attempt to convert an
151 // invalid QuicVersion to be written to the wire.
152 LOG(ERROR
) << "Unsupported QuicVersion: " << version
;
157 QuicVersion
QuicTagToQuicVersion(const QuicTag version_tag
) {
158 for (size_t i
= 0; i
< arraysize(kSupportedQuicVersions
); ++i
) {
159 if (version_tag
== QuicVersionToQuicTag(kSupportedQuicVersions
[i
])) {
160 return kSupportedQuicVersions
[i
];
163 // Reading from the client so this should not be considered an ERROR.
164 DVLOG(1) << "Unsupported QuicTag version: "
165 << QuicUtils::TagToString(version_tag
);
166 return QUIC_VERSION_UNSUPPORTED
;
169 #define RETURN_STRING_LITERAL(x) \
173 string
QuicVersionToString(const QuicVersion version
) {
175 RETURN_STRING_LITERAL(QUIC_VERSION_12
);
176 RETURN_STRING_LITERAL(QUIC_VERSION_13
);
178 return "QUIC_VERSION_UNSUPPORTED";
182 string
QuicVersionVectorToString(const QuicVersionVector
& versions
) {
184 for (size_t i
= 0; i
< versions
.size(); ++i
) {
188 result
.append(QuicVersionToString(versions
[i
]));
193 ostream
& operator<<(ostream
& os
, const QuicPacketHeader
& header
) {
194 os
<< "{ guid: " << header
.public_header
.guid
195 << ", guid_length:" << header
.public_header
.guid_length
196 << ", sequence_number_length:"
197 << header
.public_header
.sequence_number_length
198 << ", reset_flag: " << header
.public_header
.reset_flag
199 << ", version_flag: " << header
.public_header
.version_flag
;
200 if (header
.public_header
.version_flag
) {
202 for (size_t i
= 0; i
< header
.public_header
.versions
.size(); ++i
) {
203 os
<< header
.public_header
.versions
[0] << " ";
206 os
<< ", fec_flag: " << header
.fec_flag
207 << ", entropy_flag: " << header
.entropy_flag
208 << ", entropy hash: " << static_cast<int>(header
.entropy_hash
)
209 << ", sequence_number: " << header
.packet_sequence_number
210 << ", is_in_fec_group:" << header
.is_in_fec_group
211 << ", fec_group: " << header
.fec_group
<< "}\n";
215 ReceivedPacketInfo::ReceivedPacketInfo()
218 delta_time_largest_observed(QuicTime::Delta::Infinite()),
219 is_truncated(false) {}
221 ReceivedPacketInfo::~ReceivedPacketInfo() {}
223 bool IsAwaitingPacket(const ReceivedPacketInfo
& received_info
,
224 QuicPacketSequenceNumber sequence_number
) {
225 return sequence_number
> received_info
.largest_observed
||
226 ContainsKey(received_info
.missing_packets
, sequence_number
);
229 void InsertMissingPacketsBetween(ReceivedPacketInfo
* received_info
,
230 QuicPacketSequenceNumber lower
,
231 QuicPacketSequenceNumber higher
) {
232 for (QuicPacketSequenceNumber i
= lower
; i
< higher
; ++i
) {
233 received_info
->missing_packets
.insert(i
);
237 SentPacketInfo::SentPacketInfo()
241 SentPacketInfo::~SentPacketInfo() {}
243 // Testing convenience method.
244 QuicAckFrame::QuicAckFrame(QuicPacketSequenceNumber largest_observed
,
245 QuicTime largest_observed_receive_time
,
246 QuicPacketSequenceNumber least_unacked
) {
247 received_info
.largest_observed
= largest_observed
;
248 received_info
.entropy_hash
= 0;
249 sent_info
.least_unacked
= least_unacked
;
250 sent_info
.entropy_hash
= 0;
253 ostream
& operator<<(ostream
& os
, const SentPacketInfo
& sent_info
) {
254 os
<< "entropy_hash: " << static_cast<int>(sent_info
.entropy_hash
)
255 << " least_unacked: " << sent_info
.least_unacked
;
259 ostream
& operator<<(ostream
& os
, const ReceivedPacketInfo
& received_info
) {
260 os
<< "entropy_hash: " << static_cast<int>(received_info
.entropy_hash
)
261 << " largest_observed: " << received_info
.largest_observed
262 << " missing_packets: [ ";
263 for (SequenceNumberSet::const_iterator it
=
264 received_info
.missing_packets
.begin();
265 it
!= received_info
.missing_packets
.end(); ++it
) {
272 QuicCongestionFeedbackFrame::QuicCongestionFeedbackFrame() {
275 QuicCongestionFeedbackFrame::~QuicCongestionFeedbackFrame() {
278 ostream
& operator<<(ostream
& os
,
279 const QuicCongestionFeedbackFrame
& congestion_frame
) {
280 os
<< "type: " << congestion_frame
.type
;
281 switch (congestion_frame
.type
) {
282 case kInterArrival
: {
283 const CongestionFeedbackMessageInterArrival
& inter_arrival
=
284 congestion_frame
.inter_arrival
;
285 os
<< " accumulated_number_of_lost_packets: "
286 << inter_arrival
.accumulated_number_of_lost_packets
;
287 os
<< " received packets: [ ";
288 for (TimeMap::const_iterator it
=
289 inter_arrival
.received_packet_times
.begin();
290 it
!= inter_arrival
.received_packet_times
.end(); ++it
) {
291 os
<< it
->first
<< "@" << it
->second
.ToDebuggingValue() << " ";
297 os
<< " bitrate_in_bytes_per_second: "
298 << congestion_frame
.fix_rate
.bitrate
.ToBytesPerSecond();
302 const CongestionFeedbackMessageTCP
& tcp
= congestion_frame
.tcp
;
303 os
<< " accumulated_number_of_lost_packets: "
304 << congestion_frame
.tcp
.accumulated_number_of_lost_packets
;
305 os
<< " receive_window: " << tcp
.receive_window
;
312 ostream
& operator<<(ostream
& os
, const QuicAckFrame
& ack_frame
) {
313 os
<< "sent info { " << ack_frame
.sent_info
<< " } "
314 << "received info { " << ack_frame
.received_info
<< " }\n";
318 CongestionFeedbackMessageFixRate::CongestionFeedbackMessageFixRate()
319 : bitrate(QuicBandwidth::Zero()) {
322 CongestionFeedbackMessageInterArrival::
323 CongestionFeedbackMessageInterArrival() {}
325 CongestionFeedbackMessageInterArrival::
326 ~CongestionFeedbackMessageInterArrival() {}
328 QuicGoAwayFrame::QuicGoAwayFrame(QuicErrorCode error_code
,
329 QuicStreamId last_good_stream_id
,
330 const string
& reason
)
331 : error_code(error_code
),
332 last_good_stream_id(last_good_stream_id
),
333 reason_phrase(reason
) {
334 DCHECK_LE(error_code
, numeric_limits
<uint8
>::max());
337 QuicFecData::QuicFecData() {}
339 QuicData::~QuicData() {
341 delete [] const_cast<char*>(buffer_
);
345 StringPiece
QuicPacket::FecProtectedData() const {
346 const size_t start_of_fec
= GetStartOfFecProtectedData(
347 guid_length_
, includes_version_
, sequence_number_length_
);
348 return StringPiece(data() + start_of_fec
, length() - start_of_fec
);
351 StringPiece
QuicPacket::AssociatedData() const {
353 data() + kStartOfHashData
,
354 GetStartOfEncryptedData(
355 guid_length_
, includes_version_
, sequence_number_length_
) -
359 StringPiece
QuicPacket::BeforePlaintext() const {
360 return StringPiece(data(), GetStartOfEncryptedData(guid_length_
,
362 sequence_number_length_
));
365 StringPiece
QuicPacket::Plaintext() const {
366 const size_t start_of_encrypted_data
=
367 GetStartOfEncryptedData(
368 guid_length_
, includes_version_
, sequence_number_length_
);
369 return StringPiece(data() + start_of_encrypted_data
,
370 length() - start_of_encrypted_data
);
373 RetransmittableFrames::RetransmittableFrames()
374 : encryption_level_(NUM_ENCRYPTION_LEVELS
) {
377 RetransmittableFrames::~RetransmittableFrames() {
378 for (QuicFrames::iterator it
= frames_
.begin(); it
!= frames_
.end(); ++it
) {
381 delete it
->padding_frame
;
384 delete it
->stream_frame
;
387 delete it
->ack_frame
;
389 case CONGESTION_FEEDBACK_FRAME
:
390 delete it
->congestion_feedback_frame
;
392 case RST_STREAM_FRAME
:
393 delete it
->rst_stream_frame
;
395 case CONNECTION_CLOSE_FRAME
:
396 delete it
->connection_close_frame
;
399 delete it
->goaway_frame
;
401 case NUM_FRAME_TYPES
:
402 DCHECK(false) << "Cannot delete type: " << it
->type
;
405 STLDeleteElements(&stream_data_
);
408 const QuicFrame
& RetransmittableFrames::AddStreamFrame(
409 QuicStreamFrame
* stream_frame
) {
410 // Make an owned copy of the stream frame's data.
411 stream_data_
.push_back(stream_frame
->GetDataAsString());
412 // Ensure the stream frame's IOVector points to the owned copy of the data.
413 stream_frame
->data
.Clear();
414 stream_frame
->data
.Append(const_cast<char*>(stream_data_
.back()->data()),
415 stream_data_
.back()->size());
416 frames_
.push_back(QuicFrame(stream_frame
));
417 return frames_
.back();
420 const QuicFrame
& RetransmittableFrames::AddNonStreamFrame(
421 const QuicFrame
& frame
) {
422 DCHECK_NE(frame
.type
, STREAM_FRAME
);
423 frames_
.push_back(frame
);
424 return frames_
.back();
427 IsHandshake
RetransmittableFrames::HasCryptoHandshake() const {
428 for (size_t i
= 0; i
< frames().size(); ++i
) {
429 if (frames()[i
].type
== STREAM_FRAME
&&
430 frames()[i
].stream_frame
->stream_id
== kCryptoStreamId
) {
434 return NOT_HANDSHAKE
;
437 void RetransmittableFrames::set_encryption_level(EncryptionLevel level
) {
438 encryption_level_
= level
;
441 SerializedPacket::SerializedPacket(
442 QuicPacketSequenceNumber sequence_number
,
443 QuicSequenceNumberLength sequence_number_length
,
445 QuicPacketEntropyHash entropy_hash
,
446 RetransmittableFrames
* retransmittable_frames
)
447 : sequence_number(sequence_number
),
448 sequence_number_length(sequence_number_length
),
450 entropy_hash(entropy_hash
),
451 retransmittable_frames(retransmittable_frames
) {
454 SerializedPacket::~SerializedPacket() {}
456 QuicEncryptedPacket
* QuicEncryptedPacket::Clone() const {
457 char* buffer
= new char[this->length()];
458 memcpy(buffer
, this->data(), this->length());
459 return new QuicEncryptedPacket(buffer
, this->length(), true);
462 ostream
& operator<<(ostream
& os
, const QuicEncryptedPacket
& s
) {
463 os
<< s
.length() << "-byte data";
467 ostream
& operator<<(ostream
& os
, const QuicConsumedData
& s
) {
468 os
<< "bytes_consumed: " << s
.bytes_consumed
469 << " fin_consumed: " << s
.fin_consumed
;