| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "net/quic/quic_framer.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <map> | |
| 9 #include <string> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/containers/hash_tables.h" | |
| 13 #include "base/logging.h" | |
| 14 #include "base/memory/scoped_ptr.h" | |
| 15 #include "base/port.h" | |
| 16 #include "base/stl_util.h" | |
| 17 #include "net/quic/crypto/quic_decrypter.h" | |
| 18 #include "net/quic/crypto/quic_encrypter.h" | |
| 19 #include "net/quic/quic_protocol.h" | |
| 20 #include "net/quic/quic_utils.h" | |
| 21 #include "net/quic/test_tools/quic_framer_peer.h" | |
| 22 #include "net/quic/test_tools/quic_test_utils.h" | |
| 23 #include "net/test/gtest_util.h" | |
| 24 | |
| 25 using base::hash_set; | |
| 26 using base::StringPiece; | |
| 27 using std::make_pair; | |
| 28 using std::map; | |
| 29 using std::numeric_limits; | |
| 30 using std::pair; | |
| 31 using std::string; | |
| 32 using std::vector; | |
| 33 using testing::Return; | |
| 34 using testing::_; | |
| 35 | |
| 36 namespace net { | |
| 37 namespace test { | |
| 38 | |
| 39 const QuicPacketSequenceNumber kEpoch = GG_UINT64_C(1) << 48; | |
| 40 const QuicPacketSequenceNumber kMask = kEpoch - 1; | |
| 41 | |
| 42 // Index into the connection_id offset in the header. | |
| 43 const size_t kConnectionIdOffset = kPublicFlagsSize; | |
| 44 // Index into the version string in the header. (if present). | |
| 45 const size_t kVersionOffset = kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID; | |
| 46 | |
| 47 // Size in bytes of the stream frame fields for an arbitrary StreamID and | |
| 48 // offset and the last frame in a packet. | |
| 49 size_t GetMinStreamFrameSize() { | |
| 50 return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize; | |
| 51 } | |
| 52 | |
| 53 // Index into the sequence number offset in the header. | |
| 54 size_t GetSequenceNumberOffset(QuicConnectionIdLength connection_id_length, | |
| 55 bool include_version) { | |
| 56 return kConnectionIdOffset + connection_id_length + | |
| 57 (include_version ? kQuicVersionSize : 0); | |
| 58 } | |
| 59 | |
| 60 size_t GetSequenceNumberOffset(bool include_version) { | |
| 61 return GetSequenceNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version); | |
| 62 } | |
| 63 | |
| 64 // Index into the private flags offset in the data packet header. | |
| 65 size_t GetPrivateFlagsOffset(QuicConnectionIdLength connection_id_length, | |
| 66 bool include_version) { | |
| 67 return GetSequenceNumberOffset(connection_id_length, include_version) + | |
| 68 PACKET_6BYTE_SEQUENCE_NUMBER; | |
| 69 } | |
| 70 | |
| 71 size_t GetPrivateFlagsOffset(bool include_version) { | |
| 72 return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version); | |
| 73 } | |
| 74 | |
| 75 size_t GetPrivateFlagsOffset(bool include_version, | |
| 76 QuicSequenceNumberLength sequence_number_length) { | |
| 77 return GetSequenceNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version) + | |
| 78 sequence_number_length; | |
| 79 } | |
| 80 | |
| 81 // Index into the fec group offset in the header. | |
| 82 size_t GetFecGroupOffset(QuicConnectionIdLength connection_id_length, | |
| 83 bool include_version) { | |
| 84 return GetPrivateFlagsOffset(connection_id_length, include_version) + | |
| 85 kPrivateFlagsSize; | |
| 86 } | |
| 87 | |
| 88 size_t GetFecGroupOffset(bool include_version) { | |
| 89 return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version) + | |
| 90 kPrivateFlagsSize; | |
| 91 } | |
| 92 | |
| 93 size_t GetFecGroupOffset(bool include_version, | |
| 94 QuicSequenceNumberLength sequence_number_length) { | |
| 95 return GetPrivateFlagsOffset(include_version, sequence_number_length) + | |
| 96 kPrivateFlagsSize; | |
| 97 } | |
| 98 | |
| 99 // Index into the message tag of the public reset packet. | |
| 100 // Public resets always have full connection_ids. | |
| 101 const size_t kPublicResetPacketMessageTagOffset = | |
| 102 kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID; | |
| 103 | |
| 104 class TestEncrypter : public QuicEncrypter { | |
| 105 public: | |
| 106 ~TestEncrypter() override {} | |
| 107 bool SetKey(StringPiece key) override { return true; } | |
| 108 bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; } | |
| 109 bool Encrypt(StringPiece nonce, | |
| 110 StringPiece associated_data, | |
| 111 StringPiece plaintext, | |
| 112 unsigned char* output) override { | |
| 113 CHECK(false) << "Not implemented"; | |
| 114 return false; | |
| 115 } | |
| 116 bool EncryptPacket(QuicPacketSequenceNumber sequence_number, | |
| 117 StringPiece associated_data, | |
| 118 StringPiece plaintext, | |
| 119 char* output, | |
| 120 size_t* output_length, | |
| 121 size_t max_output_length) override { | |
| 122 sequence_number_ = sequence_number; | |
| 123 associated_data_ = associated_data.as_string(); | |
| 124 plaintext_ = plaintext.as_string(); | |
| 125 memcpy(output, plaintext.data(), plaintext.length()); | |
| 126 *output_length = plaintext.length(); | |
| 127 return true; | |
| 128 } | |
| 129 size_t GetKeySize() const override { return 0; } | |
| 130 size_t GetNoncePrefixSize() const override { return 0; } | |
| 131 size_t GetMaxPlaintextSize(size_t ciphertext_size) const override { | |
| 132 return ciphertext_size; | |
| 133 } | |
| 134 size_t GetCiphertextSize(size_t plaintext_size) const override { | |
| 135 return plaintext_size; | |
| 136 } | |
| 137 StringPiece GetKey() const override { return StringPiece(); } | |
| 138 StringPiece GetNoncePrefix() const override { return StringPiece(); } | |
| 139 QuicPacketSequenceNumber sequence_number_; | |
| 140 string associated_data_; | |
| 141 string plaintext_; | |
| 142 }; | |
| 143 | |
| 144 class TestDecrypter : public QuicDecrypter { | |
| 145 public: | |
| 146 ~TestDecrypter() override {} | |
| 147 bool SetKey(StringPiece key) override { return true; } | |
| 148 bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; } | |
| 149 bool DecryptPacket(QuicPacketSequenceNumber sequence_number, | |
| 150 const StringPiece& associated_data, | |
| 151 const StringPiece& ciphertext, | |
| 152 char* output, | |
| 153 size_t* output_length, | |
| 154 size_t max_output_length) override { | |
| 155 sequence_number_ = sequence_number; | |
| 156 associated_data_ = associated_data.as_string(); | |
| 157 ciphertext_ = ciphertext.as_string(); | |
| 158 memcpy(output, ciphertext.data(), ciphertext.length()); | |
| 159 *output_length = ciphertext.length(); | |
| 160 return true; | |
| 161 } | |
| 162 StringPiece GetKey() const override { return StringPiece(); } | |
| 163 StringPiece GetNoncePrefix() const override { return StringPiece(); } | |
| 164 QuicPacketSequenceNumber sequence_number_; | |
| 165 string associated_data_; | |
| 166 string ciphertext_; | |
| 167 }; | |
| 168 | |
| 169 class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { | |
| 170 public: | |
| 171 TestQuicVisitor() | |
| 172 : error_count_(0), | |
| 173 version_mismatch_(0), | |
| 174 packet_count_(0), | |
| 175 frame_count_(0), | |
| 176 fec_count_(0), | |
| 177 complete_packets_(0), | |
| 178 revived_packets_(0), | |
| 179 accept_packet_(true), | |
| 180 accept_public_header_(true) { | |
| 181 } | |
| 182 | |
| 183 ~TestQuicVisitor() override { | |
| 184 STLDeleteElements(&stream_frames_); | |
| 185 STLDeleteElements(&ack_frames_); | |
| 186 STLDeleteElements(&stop_waiting_frames_); | |
| 187 STLDeleteElements(&ping_frames_); | |
| 188 STLDeleteElements(&fec_data_); | |
| 189 STLDeleteElements(&stream_data_); | |
| 190 STLDeleteElements(&fec_data_redundancy_); | |
| 191 } | |
| 192 | |
| 193 void OnError(QuicFramer* f) override { | |
| 194 DVLOG(1) << "QuicFramer Error: " << QuicUtils::ErrorToString(f->error()) | |
| 195 << " (" << f->error() << ")"; | |
| 196 ++error_count_; | |
| 197 } | |
| 198 | |
| 199 void OnPacket() override {} | |
| 200 | |
| 201 void OnPublicResetPacket(const QuicPublicResetPacket& packet) override { | |
| 202 public_reset_packet_.reset(new QuicPublicResetPacket(packet)); | |
| 203 } | |
| 204 | |
| 205 void OnVersionNegotiationPacket( | |
| 206 const QuicVersionNegotiationPacket& packet) override { | |
| 207 version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet)); | |
| 208 } | |
| 209 | |
| 210 void OnRevivedPacket() override { ++revived_packets_; } | |
| 211 | |
| 212 bool OnProtocolVersionMismatch(QuicVersion version) override { | |
| 213 DVLOG(1) << "QuicFramer Version Mismatch, version: " << version; | |
| 214 ++version_mismatch_; | |
| 215 return true; | |
| 216 } | |
| 217 | |
| 218 bool OnUnauthenticatedPublicHeader( | |
| 219 const QuicPacketPublicHeader& header) override { | |
| 220 public_header_.reset(new QuicPacketPublicHeader(header)); | |
| 221 return accept_public_header_; | |
| 222 } | |
| 223 | |
| 224 bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override { | |
| 225 return true; | |
| 226 } | |
| 227 | |
| 228 void OnDecryptedPacket(EncryptionLevel level) override {} | |
| 229 | |
| 230 bool OnPacketHeader(const QuicPacketHeader& header) override { | |
| 231 ++packet_count_; | |
| 232 header_.reset(new QuicPacketHeader(header)); | |
| 233 return accept_packet_; | |
| 234 } | |
| 235 | |
| 236 bool OnStreamFrame(const QuicStreamFrame& frame) override { | |
| 237 ++frame_count_; | |
| 238 // Save a copy of the data so it is valid after the packet is processed. | |
| 239 stream_data_.push_back(frame.GetDataAsString()); | |
| 240 QuicStreamFrame* stream_frame = new QuicStreamFrame(frame); | |
| 241 // Make sure that the stream frame points to this data. | |
| 242 stream_frame->data.Clear(); | |
| 243 stream_frame->data.Append(const_cast<char*>(stream_data_.back()->data()), | |
| 244 stream_data_.back()->size()); | |
| 245 stream_frames_.push_back(stream_frame); | |
| 246 return true; | |
| 247 } | |
| 248 | |
| 249 void OnFecProtectedPayload(StringPiece payload) override { | |
| 250 fec_protected_payload_ = payload.as_string(); | |
| 251 } | |
| 252 | |
| 253 bool OnAckFrame(const QuicAckFrame& frame) override { | |
| 254 ++frame_count_; | |
| 255 ack_frames_.push_back(new QuicAckFrame(frame)); | |
| 256 return true; | |
| 257 } | |
| 258 | |
| 259 bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override { | |
| 260 ++frame_count_; | |
| 261 stop_waiting_frames_.push_back(new QuicStopWaitingFrame(frame)); | |
| 262 return true; | |
| 263 } | |
| 264 | |
| 265 bool OnPingFrame(const QuicPingFrame& frame) override { | |
| 266 ++frame_count_; | |
| 267 ping_frames_.push_back(new QuicPingFrame(frame)); | |
| 268 return true; | |
| 269 } | |
| 270 | |
| 271 void OnFecData(const QuicFecData& fec) override { | |
| 272 ++fec_count_; | |
| 273 QuicFecData* fec_data = new QuicFecData(); | |
| 274 fec_data->fec_group = fec.fec_group; | |
| 275 // Save a copy of the data so it is valid after the packet is processed. | |
| 276 string* redundancy = new string(fec.redundancy.as_string()); | |
| 277 fec_data_redundancy_.push_back(redundancy); | |
| 278 fec_data->redundancy = StringPiece(*redundancy); | |
| 279 fec_data_.push_back(fec_data); | |
| 280 } | |
| 281 | |
| 282 void OnPacketComplete() override { ++complete_packets_; } | |
| 283 | |
| 284 bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override { | |
| 285 rst_stream_frame_ = frame; | |
| 286 return true; | |
| 287 } | |
| 288 | |
| 289 bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override { | |
| 290 connection_close_frame_ = frame; | |
| 291 return true; | |
| 292 } | |
| 293 | |
| 294 bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override { | |
| 295 goaway_frame_ = frame; | |
| 296 return true; | |
| 297 } | |
| 298 | |
| 299 bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override { | |
| 300 window_update_frame_ = frame; | |
| 301 return true; | |
| 302 } | |
| 303 | |
| 304 bool OnBlockedFrame(const QuicBlockedFrame& frame) override { | |
| 305 blocked_frame_ = frame; | |
| 306 return true; | |
| 307 } | |
| 308 | |
| 309 // Counters from the visitor_ callbacks. | |
| 310 int error_count_; | |
| 311 int version_mismatch_; | |
| 312 int packet_count_; | |
| 313 int frame_count_; | |
| 314 int fec_count_; | |
| 315 int complete_packets_; | |
| 316 int revived_packets_; | |
| 317 bool accept_packet_; | |
| 318 bool accept_public_header_; | |
| 319 | |
| 320 scoped_ptr<QuicPacketHeader> header_; | |
| 321 scoped_ptr<QuicPacketPublicHeader> public_header_; | |
| 322 scoped_ptr<QuicPublicResetPacket> public_reset_packet_; | |
| 323 scoped_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_; | |
| 324 vector<QuicStreamFrame*> stream_frames_; | |
| 325 vector<QuicAckFrame*> ack_frames_; | |
| 326 vector<QuicStopWaitingFrame*> stop_waiting_frames_; | |
| 327 vector<QuicPingFrame*> ping_frames_; | |
| 328 vector<QuicFecData*> fec_data_; | |
| 329 string fec_protected_payload_; | |
| 330 QuicRstStreamFrame rst_stream_frame_; | |
| 331 QuicConnectionCloseFrame connection_close_frame_; | |
| 332 QuicGoAwayFrame goaway_frame_; | |
| 333 QuicWindowUpdateFrame window_update_frame_; | |
| 334 QuicBlockedFrame blocked_frame_; | |
| 335 vector<string*> stream_data_; | |
| 336 vector<string*> fec_data_redundancy_; | |
| 337 }; | |
| 338 | |
| 339 class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> { | |
| 340 public: | |
| 341 QuicFramerTest() | |
| 342 : encrypter_(new test::TestEncrypter()), | |
| 343 decrypter_(new test::TestDecrypter()), | |
| 344 start_(QuicTime::Zero().Add(QuicTime::Delta::FromMicroseconds(0x10))), | |
| 345 framer_(QuicSupportedVersions(), start_, true) { | |
| 346 version_ = GetParam(); | |
| 347 framer_.set_version(version_); | |
| 348 framer_.SetDecrypter(decrypter_, ENCRYPTION_NONE); | |
| 349 framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_); | |
| 350 framer_.set_visitor(&visitor_); | |
| 351 framer_.set_received_entropy_calculator(&entropy_calculator_); | |
| 352 } | |
| 353 | |
| 354 // Helper function to get unsigned char representation of digit in the | |
| 355 // units place of the current QUIC version number. | |
| 356 unsigned char GetQuicVersionDigitOnes() { | |
| 357 return static_cast<unsigned char> ('0' + version_%10); | |
| 358 } | |
| 359 | |
| 360 // Helper function to get unsigned char representation of digit in the | |
| 361 // tens place of the current QUIC version number. | |
| 362 unsigned char GetQuicVersionDigitTens() { | |
| 363 return static_cast<unsigned char> ('0' + (version_/10)%10); | |
| 364 } | |
| 365 | |
| 366 bool CheckEncryption(QuicPacketSequenceNumber sequence_number, | |
| 367 QuicPacket* packet) { | |
| 368 if (sequence_number != encrypter_->sequence_number_) { | |
| 369 LOG(ERROR) << "Encrypted incorrect packet sequence number. expected " | |
| 370 << sequence_number << " actual: " | |
| 371 << encrypter_->sequence_number_; | |
| 372 return false; | |
| 373 } | |
| 374 if (packet->AssociatedData() != encrypter_->associated_data_) { | |
| 375 LOG(ERROR) << "Encrypted incorrect associated data. expected " | |
| 376 << packet->AssociatedData() << " actual: " | |
| 377 << encrypter_->associated_data_; | |
| 378 return false; | |
| 379 } | |
| 380 if (packet->Plaintext() != encrypter_->plaintext_) { | |
| 381 LOG(ERROR) << "Encrypted incorrect plaintext data. expected " | |
| 382 << packet->Plaintext() << " actual: " | |
| 383 << encrypter_->plaintext_; | |
| 384 return false; | |
| 385 } | |
| 386 return true; | |
| 387 } | |
| 388 | |
| 389 bool CheckDecryption(const QuicEncryptedPacket& encrypted, | |
| 390 bool includes_version) { | |
| 391 if (visitor_.header_->packet_sequence_number != | |
| 392 decrypter_->sequence_number_) { | |
| 393 LOG(ERROR) << "Decrypted incorrect packet sequence number. expected " | |
| 394 << visitor_.header_->packet_sequence_number << " actual: " | |
| 395 << decrypter_->sequence_number_; | |
| 396 return false; | |
| 397 } | |
| 398 if (QuicFramer::GetAssociatedDataFromEncryptedPacket( | |
| 399 encrypted, PACKET_8BYTE_CONNECTION_ID, | |
| 400 includes_version, PACKET_6BYTE_SEQUENCE_NUMBER) != | |
| 401 decrypter_->associated_data_) { | |
| 402 LOG(ERROR) << "Decrypted incorrect associated data. expected " | |
| 403 << QuicFramer::GetAssociatedDataFromEncryptedPacket( | |
| 404 encrypted, PACKET_8BYTE_CONNECTION_ID, | |
| 405 includes_version, PACKET_6BYTE_SEQUENCE_NUMBER) | |
| 406 << " actual: " << decrypter_->associated_data_; | |
| 407 return false; | |
| 408 } | |
| 409 StringPiece ciphertext(encrypted.AsStringPiece().substr( | |
| 410 GetStartOfEncryptedData(PACKET_8BYTE_CONNECTION_ID, includes_version, | |
| 411 PACKET_6BYTE_SEQUENCE_NUMBER))); | |
| 412 if (ciphertext != decrypter_->ciphertext_) { | |
| 413 LOG(ERROR) << "Decrypted incorrect ciphertext data. expected " | |
| 414 << ciphertext << " actual: " | |
| 415 << decrypter_->ciphertext_; | |
| 416 return false; | |
| 417 } | |
| 418 return true; | |
| 419 } | |
| 420 | |
| 421 char* AsChars(unsigned char* data) { | |
| 422 return reinterpret_cast<char*>(data); | |
| 423 } | |
| 424 | |
| 425 void CheckProcessingFails(unsigned char* packet, | |
| 426 size_t len, | |
| 427 string expected_error, | |
| 428 QuicErrorCode error_code) { | |
| 429 QuicEncryptedPacket encrypted(AsChars(packet), len, false); | |
| 430 EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len; | |
| 431 EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len; | |
| 432 EXPECT_EQ(error_code, framer_.error()) << "len: " << len; | |
| 433 } | |
| 434 | |
| 435 // Checks if the supplied string matches data in the supplied StreamFrame. | |
| 436 void CheckStreamFrameData(string str, QuicStreamFrame* frame) { | |
| 437 scoped_ptr<string> frame_data(frame->GetDataAsString()); | |
| 438 EXPECT_EQ(str, *frame_data); | |
| 439 } | |
| 440 | |
| 441 void CheckStreamFrameBoundaries(unsigned char* packet, | |
| 442 size_t stream_id_size, | |
| 443 bool include_version) { | |
| 444 // Now test framing boundaries. | |
| 445 for (size_t i = kQuicFrameTypeSize; i < GetMinStreamFrameSize(); ++i) { | |
| 446 string expected_error; | |
| 447 if (i < kQuicFrameTypeSize + stream_id_size) { | |
| 448 expected_error = "Unable to read stream_id."; | |
| 449 } else if (i < kQuicFrameTypeSize + stream_id_size + | |
| 450 kQuicMaxStreamOffsetSize) { | |
| 451 expected_error = "Unable to read offset."; | |
| 452 } else { | |
| 453 expected_error = "Unable to read frame data."; | |
| 454 } | |
| 455 CheckProcessingFails( | |
| 456 packet, | |
| 457 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, include_version, | |
| 458 PACKET_6BYTE_SEQUENCE_NUMBER, | |
| 459 NOT_IN_FEC_GROUP), | |
| 460 expected_error, QUIC_INVALID_STREAM_DATA); | |
| 461 } | |
| 462 } | |
| 463 | |
| 464 void CheckCalculatePacketSequenceNumber( | |
| 465 QuicPacketSequenceNumber expected_sequence_number, | |
| 466 QuicPacketSequenceNumber last_sequence_number) { | |
| 467 QuicPacketSequenceNumber wire_sequence_number = | |
| 468 expected_sequence_number & kMask; | |
| 469 QuicFramerPeer::SetLastSequenceNumber(&framer_, last_sequence_number); | |
| 470 EXPECT_EQ(expected_sequence_number, | |
| 471 QuicFramerPeer::CalculatePacketSequenceNumberFromWire( | |
| 472 &framer_, PACKET_6BYTE_SEQUENCE_NUMBER, wire_sequence_number)) | |
| 473 << "last_sequence_number: " << last_sequence_number | |
| 474 << " wire_sequence_number: " << wire_sequence_number; | |
| 475 } | |
| 476 | |
| 477 QuicPacket* BuildDataPacket(const QuicPacketHeader& header, | |
| 478 const QuicFrames& frames) { | |
| 479 return BuildUnsizedDataPacket(&framer_, header, frames); | |
| 480 } | |
| 481 | |
| 482 QuicPacket* BuildDataPacket(const QuicPacketHeader& header, | |
| 483 const QuicFrames& frames, | |
| 484 size_t packet_size) { | |
| 485 return BuildUnsizedDataPacket(&framer_, header, frames, packet_size); | |
| 486 } | |
| 487 | |
| 488 test::TestEncrypter* encrypter_; | |
| 489 test::TestDecrypter* decrypter_; | |
| 490 QuicVersion version_; | |
| 491 QuicTime start_; | |
| 492 QuicFramer framer_; | |
| 493 test::TestQuicVisitor visitor_; | |
| 494 test::TestEntropyCalculator entropy_calculator_; | |
| 495 }; | |
| 496 | |
| 497 // Run all framer tests with all supported versions of QUIC. | |
| 498 INSTANTIATE_TEST_CASE_P(QuicFramerTests, | |
| 499 QuicFramerTest, | |
| 500 ::testing::ValuesIn(kSupportedQuicVersions)); | |
| 501 | |
| 502 TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochStart) { | |
| 503 // A few quick manual sanity checks | |
| 504 CheckCalculatePacketSequenceNumber(GG_UINT64_C(1), GG_UINT64_C(0)); | |
| 505 CheckCalculatePacketSequenceNumber(kEpoch + 1, kMask); | |
| 506 CheckCalculatePacketSequenceNumber(kEpoch, kMask); | |
| 507 | |
| 508 // Cases where the last number was close to the start of the range | |
| 509 for (uint64 last = 0; last < 10; last++) { | |
| 510 // Small numbers should not wrap (even if they're out of order). | |
| 511 for (uint64 j = 0; j < 10; j++) { | |
| 512 CheckCalculatePacketSequenceNumber(j, last); | |
| 513 } | |
| 514 | |
| 515 // Large numbers should not wrap either (because we're near 0 already). | |
| 516 for (uint64 j = 0; j < 10; j++) { | |
| 517 CheckCalculatePacketSequenceNumber(kEpoch - 1 - j, last); | |
| 518 } | |
| 519 } | |
| 520 } | |
| 521 | |
| 522 TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochEnd) { | |
| 523 // Cases where the last number was close to the end of the range | |
| 524 for (uint64 i = 0; i < 10; i++) { | |
| 525 QuicPacketSequenceNumber last = kEpoch - i; | |
| 526 | |
| 527 // Small numbers should wrap. | |
| 528 for (uint64 j = 0; j < 10; j++) { | |
| 529 CheckCalculatePacketSequenceNumber(kEpoch + j, last); | |
| 530 } | |
| 531 | |
| 532 // Large numbers should not (even if they're out of order). | |
| 533 for (uint64 j = 0; j < 10; j++) { | |
| 534 CheckCalculatePacketSequenceNumber(kEpoch - 1 - j, last); | |
| 535 } | |
| 536 } | |
| 537 } | |
| 538 | |
| 539 // Next check where we're in a non-zero epoch to verify we handle | |
| 540 // reverse wrapping, too. | |
| 541 TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearPrevEpoch) { | |
| 542 const uint64 prev_epoch = 1 * kEpoch; | |
| 543 const uint64 cur_epoch = 2 * kEpoch; | |
| 544 // Cases where the last number was close to the start of the range | |
| 545 for (uint64 i = 0; i < 10; i++) { | |
| 546 uint64 last = cur_epoch + i; | |
| 547 // Small number should not wrap (even if they're out of order). | |
| 548 for (uint64 j = 0; j < 10; j++) { | |
| 549 CheckCalculatePacketSequenceNumber(cur_epoch + j, last); | |
| 550 } | |
| 551 | |
| 552 // But large numbers should reverse wrap. | |
| 553 for (uint64 j = 0; j < 10; j++) { | |
| 554 uint64 num = kEpoch - 1 - j; | |
| 555 CheckCalculatePacketSequenceNumber(prev_epoch + num, last); | |
| 556 } | |
| 557 } | |
| 558 } | |
| 559 | |
| 560 TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextEpoch) { | |
| 561 const uint64 cur_epoch = 2 * kEpoch; | |
| 562 const uint64 next_epoch = 3 * kEpoch; | |
| 563 // Cases where the last number was close to the end of the range | |
| 564 for (uint64 i = 0; i < 10; i++) { | |
| 565 QuicPacketSequenceNumber last = next_epoch - 1 - i; | |
| 566 | |
| 567 // Small numbers should wrap. | |
| 568 for (uint64 j = 0; j < 10; j++) { | |
| 569 CheckCalculatePacketSequenceNumber(next_epoch + j, last); | |
| 570 } | |
| 571 | |
| 572 // but large numbers should not (even if they're out of order). | |
| 573 for (uint64 j = 0; j < 10; j++) { | |
| 574 uint64 num = kEpoch - 1 - j; | |
| 575 CheckCalculatePacketSequenceNumber(cur_epoch + num, last); | |
| 576 } | |
| 577 } | |
| 578 } | |
| 579 | |
| 580 TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextMax) { | |
| 581 const uint64 max_number = numeric_limits<uint64>::max(); | |
| 582 const uint64 max_epoch = max_number & ~kMask; | |
| 583 | |
| 584 // Cases where the last number was close to the end of the range | |
| 585 for (uint64 i = 0; i < 10; i++) { | |
| 586 // Subtract 1, because the expected next sequence number is 1 more than the | |
| 587 // last sequence number. | |
| 588 QuicPacketSequenceNumber last = max_number - i - 1; | |
| 589 | |
| 590 // Small numbers should not wrap, because they have nowhere to go. | |
| 591 for (uint64 j = 0; j < 10; j++) { | |
| 592 CheckCalculatePacketSequenceNumber(max_epoch + j, last); | |
| 593 } | |
| 594 | |
| 595 // Large numbers should not wrap either. | |
| 596 for (uint64 j = 0; j < 10; j++) { | |
| 597 uint64 num = kEpoch - 1 - j; | |
| 598 CheckCalculatePacketSequenceNumber(max_epoch + num, last); | |
| 599 } | |
| 600 } | |
| 601 } | |
| 602 | |
| 603 TEST_P(QuicFramerTest, EmptyPacket) { | |
| 604 char packet[] = { 0x00 }; | |
| 605 QuicEncryptedPacket encrypted(packet, 0, false); | |
| 606 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 607 EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); | |
| 608 } | |
| 609 | |
| 610 TEST_P(QuicFramerTest, LargePacket) { | |
| 611 unsigned char packet[kMaxPacketSize + 1] = { | |
| 612 // public flags (8 byte connection_id) | |
| 613 0x3C, | |
| 614 // connection_id | |
| 615 0x10, | |
| 616 0x32, | |
| 617 0x54, | |
| 618 0x76, | |
| 619 0x98, | |
| 620 0xBA, | |
| 621 0xDC, | |
| 622 0xFE, | |
| 623 // packet sequence number | |
| 624 0xBC, | |
| 625 0x9A, | |
| 626 0x78, | |
| 627 0x56, | |
| 628 0x34, | |
| 629 0x12, | |
| 630 // private flags | |
| 631 0x00, | |
| 632 }; | |
| 633 | |
| 634 memset(packet + GetPacketHeaderSize( | |
| 635 PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 636 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), 0, | |
| 637 kMaxPacketSize - GetPacketHeaderSize( | |
| 638 PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 639 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP) + 1); | |
| 640 | |
| 641 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 642 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 643 | |
| 644 ASSERT_TRUE(visitor_.header_.get()); | |
| 645 // Make sure we've parsed the packet header, so we can send an error. | |
| 646 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 647 visitor_.header_->public_header.connection_id); | |
| 648 // Make sure the correct error is propagated. | |
| 649 EXPECT_EQ(QUIC_PACKET_TOO_LARGE, framer_.error()); | |
| 650 } | |
| 651 | |
| 652 TEST_P(QuicFramerTest, PacketHeader) { | |
| 653 unsigned char packet[] = { | |
| 654 // public flags (8 byte connection_id) | |
| 655 0x3C, | |
| 656 // connection_id | |
| 657 0x10, 0x32, 0x54, 0x76, | |
| 658 0x98, 0xBA, 0xDC, 0xFE, | |
| 659 // packet sequence number | |
| 660 0xBC, 0x9A, 0x78, 0x56, | |
| 661 0x34, 0x12, | |
| 662 // private flags | |
| 663 0x00, | |
| 664 }; | |
| 665 | |
| 666 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 667 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 668 EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); | |
| 669 ASSERT_TRUE(visitor_.header_.get()); | |
| 670 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 671 visitor_.header_->public_header.connection_id); | |
| 672 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 673 EXPECT_FALSE(visitor_.header_->public_header.version_flag); | |
| 674 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 675 EXPECT_FALSE(visitor_.header_->entropy_flag); | |
| 676 EXPECT_EQ(0, visitor_.header_->entropy_hash); | |
| 677 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 678 visitor_.header_->packet_sequence_number); | |
| 679 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 680 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 681 | |
| 682 // Now test framing boundaries. | |
| 683 for (size_t i = 0; | |
| 684 i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 685 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 686 ++i) { | |
| 687 string expected_error; | |
| 688 if (i < kConnectionIdOffset) { | |
| 689 expected_error = "Unable to read public flags."; | |
| 690 } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) { | |
| 691 expected_error = "Unable to read ConnectionId."; | |
| 692 } else if (i < GetPrivateFlagsOffset(!kIncludeVersion)) { | |
| 693 expected_error = "Unable to read sequence number."; | |
| 694 } else if (i < GetFecGroupOffset(!kIncludeVersion)) { | |
| 695 expected_error = "Unable to read private flags."; | |
| 696 } else { | |
| 697 expected_error = "Unable to read first fec protected packet offset."; | |
| 698 } | |
| 699 CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); | |
| 700 } | |
| 701 } | |
| 702 | |
| 703 TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) { | |
| 704 QuicFramerPeer::SetLastSerializedConnectionId( | |
| 705 &framer_, GG_UINT64_C(0xFEDCBA9876543210)); | |
| 706 | |
| 707 unsigned char packet[] = { | |
| 708 // public flags (4 byte connection_id) | |
| 709 0x38, | |
| 710 // connection_id | |
| 711 0x10, 0x32, 0x54, 0x76, | |
| 712 // packet sequence number | |
| 713 0xBC, 0x9A, 0x78, 0x56, | |
| 714 0x34, 0x12, | |
| 715 // private flags | |
| 716 0x00, | |
| 717 }; | |
| 718 | |
| 719 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 720 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 721 EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); | |
| 722 ASSERT_TRUE(visitor_.header_.get()); | |
| 723 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 724 visitor_.header_->public_header.connection_id); | |
| 725 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 726 EXPECT_FALSE(visitor_.header_->public_header.version_flag); | |
| 727 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 728 EXPECT_FALSE(visitor_.header_->entropy_flag); | |
| 729 EXPECT_EQ(0, visitor_.header_->entropy_hash); | |
| 730 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 731 visitor_.header_->packet_sequence_number); | |
| 732 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 733 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 734 | |
| 735 // Now test framing boundaries. | |
| 736 for (size_t i = 0; | |
| 737 i < GetPacketHeaderSize(PACKET_4BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 738 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 739 ++i) { | |
| 740 string expected_error; | |
| 741 if (i < kConnectionIdOffset) { | |
| 742 expected_error = "Unable to read public flags."; | |
| 743 } else if (i < GetSequenceNumberOffset(PACKET_4BYTE_CONNECTION_ID, | |
| 744 !kIncludeVersion)) { | |
| 745 expected_error = "Unable to read ConnectionId."; | |
| 746 } else if (i < GetPrivateFlagsOffset(PACKET_4BYTE_CONNECTION_ID, | |
| 747 !kIncludeVersion)) { | |
| 748 expected_error = "Unable to read sequence number."; | |
| 749 } else if (i < GetFecGroupOffset(PACKET_4BYTE_CONNECTION_ID, | |
| 750 !kIncludeVersion)) { | |
| 751 expected_error = "Unable to read private flags."; | |
| 752 } else { | |
| 753 expected_error = "Unable to read first fec protected packet offset."; | |
| 754 } | |
| 755 CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); | |
| 756 } | |
| 757 } | |
| 758 | |
| 759 TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) { | |
| 760 QuicFramerPeer::SetLastSerializedConnectionId( | |
| 761 &framer_, GG_UINT64_C(0xFEDCBA9876543210)); | |
| 762 | |
| 763 unsigned char packet[] = { | |
| 764 // public flags (1 byte connection_id) | |
| 765 0x34, | |
| 766 // connection_id | |
| 767 0x10, | |
| 768 // packet sequence number | |
| 769 0xBC, 0x9A, 0x78, 0x56, | |
| 770 0x34, 0x12, | |
| 771 // private flags | |
| 772 0x00, | |
| 773 }; | |
| 774 | |
| 775 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 776 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 777 EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); | |
| 778 ASSERT_TRUE(visitor_.header_.get()); | |
| 779 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 780 visitor_.header_->public_header.connection_id); | |
| 781 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 782 EXPECT_FALSE(visitor_.header_->public_header.version_flag); | |
| 783 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 784 EXPECT_FALSE(visitor_.header_->entropy_flag); | |
| 785 EXPECT_EQ(0, visitor_.header_->entropy_hash); | |
| 786 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 787 visitor_.header_->packet_sequence_number); | |
| 788 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 789 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 790 | |
| 791 // Now test framing boundaries. | |
| 792 for (size_t i = 0; | |
| 793 i < GetPacketHeaderSize(PACKET_1BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 794 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 795 ++i) { | |
| 796 string expected_error; | |
| 797 if (i < kConnectionIdOffset) { | |
| 798 expected_error = "Unable to read public flags."; | |
| 799 } else if (i < GetSequenceNumberOffset(PACKET_1BYTE_CONNECTION_ID, | |
| 800 !kIncludeVersion)) { | |
| 801 expected_error = "Unable to read ConnectionId."; | |
| 802 } else if (i < GetPrivateFlagsOffset(PACKET_1BYTE_CONNECTION_ID, | |
| 803 !kIncludeVersion)) { | |
| 804 expected_error = "Unable to read sequence number."; | |
| 805 } else if (i < GetFecGroupOffset(PACKET_1BYTE_CONNECTION_ID, | |
| 806 !kIncludeVersion)) { | |
| 807 expected_error = "Unable to read private flags."; | |
| 808 } else { | |
| 809 expected_error = "Unable to read first fec protected packet offset."; | |
| 810 } | |
| 811 CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); | |
| 812 } | |
| 813 } | |
| 814 | |
| 815 TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) { | |
| 816 QuicFramerPeer::SetLastSerializedConnectionId( | |
| 817 &framer_, GG_UINT64_C(0xFEDCBA9876543210)); | |
| 818 | |
| 819 unsigned char packet[] = { | |
| 820 // public flags (0 byte connection_id) | |
| 821 0x30, | |
| 822 // connection_id | |
| 823 // packet sequence number | |
| 824 0xBC, 0x9A, 0x78, 0x56, | |
| 825 0x34, 0x12, | |
| 826 // private flags | |
| 827 0x00, | |
| 828 }; | |
| 829 | |
| 830 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 831 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 832 EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); | |
| 833 ASSERT_TRUE(visitor_.header_.get()); | |
| 834 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 835 visitor_.header_->public_header.connection_id); | |
| 836 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 837 EXPECT_FALSE(visitor_.header_->public_header.version_flag); | |
| 838 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 839 EXPECT_FALSE(visitor_.header_->entropy_flag); | |
| 840 EXPECT_EQ(0, visitor_.header_->entropy_hash); | |
| 841 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 842 visitor_.header_->packet_sequence_number); | |
| 843 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 844 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 845 | |
| 846 // Now test framing boundaries. | |
| 847 for (size_t i = 0; | |
| 848 i < GetPacketHeaderSize(PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 849 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 850 ++i) { | |
| 851 string expected_error; | |
| 852 if (i < kConnectionIdOffset) { | |
| 853 expected_error = "Unable to read public flags."; | |
| 854 } else if (i < GetSequenceNumberOffset(PACKET_0BYTE_CONNECTION_ID, | |
| 855 !kIncludeVersion)) { | |
| 856 expected_error = "Unable to read ConnectionId."; | |
| 857 } else if (i < GetPrivateFlagsOffset(PACKET_0BYTE_CONNECTION_ID, | |
| 858 !kIncludeVersion)) { | |
| 859 expected_error = "Unable to read sequence number."; | |
| 860 } else if (i < GetFecGroupOffset(PACKET_0BYTE_CONNECTION_ID, | |
| 861 !kIncludeVersion)) { | |
| 862 expected_error = "Unable to read private flags."; | |
| 863 } else { | |
| 864 expected_error = "Unable to read first fec protected packet offset."; | |
| 865 } | |
| 866 CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); | |
| 867 } | |
| 868 } | |
| 869 | |
| 870 TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) { | |
| 871 unsigned char packet[] = { | |
| 872 // public flags (version) | |
| 873 0x3D, | |
| 874 // connection_id | |
| 875 0x10, 0x32, 0x54, 0x76, | |
| 876 0x98, 0xBA, 0xDC, 0xFE, | |
| 877 // version tag | |
| 878 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), | |
| 879 // packet sequence number | |
| 880 0xBC, 0x9A, 0x78, 0x56, | |
| 881 0x34, 0x12, | |
| 882 // private flags | |
| 883 0x00, | |
| 884 }; | |
| 885 | |
| 886 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 887 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 888 EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); | |
| 889 ASSERT_TRUE(visitor_.header_.get()); | |
| 890 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 891 visitor_.header_->public_header.connection_id); | |
| 892 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 893 EXPECT_TRUE(visitor_.header_->public_header.version_flag); | |
| 894 EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]); | |
| 895 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 896 EXPECT_FALSE(visitor_.header_->entropy_flag); | |
| 897 EXPECT_EQ(0, visitor_.header_->entropy_hash); | |
| 898 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 899 visitor_.header_->packet_sequence_number); | |
| 900 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 901 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 902 | |
| 903 // Now test framing boundaries. | |
| 904 for (size_t i = 0; | |
| 905 i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, | |
| 906 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 907 ++i) { | |
| 908 string expected_error; | |
| 909 if (i < kConnectionIdOffset) { | |
| 910 expected_error = "Unable to read public flags."; | |
| 911 } else if (i < kVersionOffset) { | |
| 912 expected_error = "Unable to read ConnectionId."; | |
| 913 } else if (i < GetSequenceNumberOffset(kIncludeVersion)) { | |
| 914 expected_error = "Unable to read protocol version."; | |
| 915 } else if (i < GetPrivateFlagsOffset(kIncludeVersion)) { | |
| 916 expected_error = "Unable to read sequence number."; | |
| 917 } else if (i < GetFecGroupOffset(kIncludeVersion)) { | |
| 918 expected_error = "Unable to read private flags."; | |
| 919 } else { | |
| 920 expected_error = "Unable to read first fec protected packet offset."; | |
| 921 } | |
| 922 CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); | |
| 923 } | |
| 924 } | |
| 925 | |
| 926 TEST_P(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) { | |
| 927 QuicFramerPeer::SetLastSequenceNumber(&framer_, | |
| 928 GG_UINT64_C(0x123456789ABA)); | |
| 929 | |
| 930 unsigned char packet[] = { | |
| 931 // public flags (8 byte connection_id and 4 byte sequence number) | |
| 932 0x2C, | |
| 933 // connection_id | |
| 934 0x10, 0x32, 0x54, 0x76, | |
| 935 0x98, 0xBA, 0xDC, 0xFE, | |
| 936 // packet sequence number | |
| 937 0xBC, 0x9A, 0x78, 0x56, | |
| 938 // private flags | |
| 939 0x00, | |
| 940 }; | |
| 941 | |
| 942 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 943 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 944 EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); | |
| 945 ASSERT_TRUE(visitor_.header_.get()); | |
| 946 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 947 visitor_.header_->public_header.connection_id); | |
| 948 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 949 EXPECT_FALSE(visitor_.header_->public_header.version_flag); | |
| 950 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 951 EXPECT_FALSE(visitor_.header_->entropy_flag); | |
| 952 EXPECT_EQ(0, visitor_.header_->entropy_hash); | |
| 953 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 954 visitor_.header_->packet_sequence_number); | |
| 955 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 956 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 957 | |
| 958 // Now test framing boundaries. | |
| 959 for (size_t i = 0; | |
| 960 i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 961 PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 962 ++i) { | |
| 963 string expected_error; | |
| 964 if (i < kConnectionIdOffset) { | |
| 965 expected_error = "Unable to read public flags."; | |
| 966 } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) { | |
| 967 expected_error = "Unable to read ConnectionId."; | |
| 968 } else if (i < GetPrivateFlagsOffset(!kIncludeVersion, | |
| 969 PACKET_4BYTE_SEQUENCE_NUMBER)) { | |
| 970 expected_error = "Unable to read sequence number."; | |
| 971 } else if (i < GetFecGroupOffset(!kIncludeVersion, | |
| 972 PACKET_4BYTE_SEQUENCE_NUMBER)) { | |
| 973 expected_error = "Unable to read private flags."; | |
| 974 } else { | |
| 975 expected_error = "Unable to read first fec protected packet offset."; | |
| 976 } | |
| 977 CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); | |
| 978 } | |
| 979 } | |
| 980 | |
| 981 TEST_P(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) { | |
| 982 QuicFramerPeer::SetLastSequenceNumber(&framer_, | |
| 983 GG_UINT64_C(0x123456789ABA)); | |
| 984 | |
| 985 unsigned char packet[] = { | |
| 986 // public flags (8 byte connection_id and 2 byte sequence number) | |
| 987 0x1C, | |
| 988 // connection_id | |
| 989 0x10, 0x32, 0x54, 0x76, | |
| 990 0x98, 0xBA, 0xDC, 0xFE, | |
| 991 // packet sequence number | |
| 992 0xBC, 0x9A, | |
| 993 // private flags | |
| 994 0x00, | |
| 995 }; | |
| 996 | |
| 997 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 998 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 999 EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); | |
| 1000 ASSERT_TRUE(visitor_.header_.get()); | |
| 1001 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 1002 visitor_.header_->public_header.connection_id); | |
| 1003 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 1004 EXPECT_FALSE(visitor_.header_->public_header.version_flag); | |
| 1005 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 1006 EXPECT_FALSE(visitor_.header_->entropy_flag); | |
| 1007 EXPECT_EQ(0, visitor_.header_->entropy_hash); | |
| 1008 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 1009 visitor_.header_->packet_sequence_number); | |
| 1010 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 1011 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 1012 | |
| 1013 // Now test framing boundaries. | |
| 1014 for (size_t i = 0; | |
| 1015 i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 1016 PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 1017 ++i) { | |
| 1018 string expected_error; | |
| 1019 if (i < kConnectionIdOffset) { | |
| 1020 expected_error = "Unable to read public flags."; | |
| 1021 } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) { | |
| 1022 expected_error = "Unable to read ConnectionId."; | |
| 1023 } else if (i < GetPrivateFlagsOffset(!kIncludeVersion, | |
| 1024 PACKET_2BYTE_SEQUENCE_NUMBER)) { | |
| 1025 expected_error = "Unable to read sequence number."; | |
| 1026 } else if (i < GetFecGroupOffset(!kIncludeVersion, | |
| 1027 PACKET_2BYTE_SEQUENCE_NUMBER)) { | |
| 1028 expected_error = "Unable to read private flags."; | |
| 1029 } else { | |
| 1030 expected_error = "Unable to read first fec protected packet offset."; | |
| 1031 } | |
| 1032 CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); | |
| 1033 } | |
| 1034 } | |
| 1035 | |
| 1036 TEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) { | |
| 1037 QuicFramerPeer::SetLastSequenceNumber(&framer_, | |
| 1038 GG_UINT64_C(0x123456789ABA)); | |
| 1039 | |
| 1040 unsigned char packet[] = { | |
| 1041 // public flags (8 byte connection_id and 1 byte sequence number) | |
| 1042 0x0C, | |
| 1043 // connection_id | |
| 1044 0x10, 0x32, 0x54, 0x76, | |
| 1045 0x98, 0xBA, 0xDC, 0xFE, | |
| 1046 // packet sequence number | |
| 1047 0xBC, | |
| 1048 // private flags | |
| 1049 0x00, | |
| 1050 }; | |
| 1051 | |
| 1052 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1053 EXPECT_FALSE(framer_.ProcessPacket(encrypted)); | |
| 1054 EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); | |
| 1055 ASSERT_TRUE(visitor_.header_.get()); | |
| 1056 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 1057 visitor_.header_->public_header.connection_id); | |
| 1058 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 1059 EXPECT_FALSE(visitor_.header_->public_header.version_flag); | |
| 1060 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 1061 EXPECT_FALSE(visitor_.header_->entropy_flag); | |
| 1062 EXPECT_EQ(0, visitor_.header_->entropy_hash); | |
| 1063 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 1064 visitor_.header_->packet_sequence_number); | |
| 1065 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 1066 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 1067 | |
| 1068 // Now test framing boundaries. | |
| 1069 for (size_t i = 0; | |
| 1070 i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 1071 PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 1072 ++i) { | |
| 1073 string expected_error; | |
| 1074 if (i < kConnectionIdOffset) { | |
| 1075 expected_error = "Unable to read public flags."; | |
| 1076 } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) { | |
| 1077 expected_error = "Unable to read ConnectionId."; | |
| 1078 } else if (i < GetPrivateFlagsOffset(!kIncludeVersion, | |
| 1079 PACKET_1BYTE_SEQUENCE_NUMBER)) { | |
| 1080 expected_error = "Unable to read sequence number."; | |
| 1081 } else if (i < GetFecGroupOffset(!kIncludeVersion, | |
| 1082 PACKET_1BYTE_SEQUENCE_NUMBER)) { | |
| 1083 expected_error = "Unable to read private flags."; | |
| 1084 } else { | |
| 1085 expected_error = "Unable to read first fec protected packet offset."; | |
| 1086 } | |
| 1087 CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); | |
| 1088 } | |
| 1089 } | |
| 1090 | |
| 1091 TEST_P(QuicFramerTest, InvalidPublicFlag) { | |
| 1092 unsigned char packet[] = { | |
| 1093 // public flags: all flags set but the public reset flag and version flag. | |
| 1094 0xFC, | |
| 1095 // connection_id | |
| 1096 0x10, 0x32, 0x54, 0x76, | |
| 1097 0x98, 0xBA, 0xDC, 0xFE, | |
| 1098 // packet sequence number | |
| 1099 0xBC, 0x9A, 0x78, 0x56, | |
| 1100 0x34, 0x12, | |
| 1101 // private flags | |
| 1102 0x00, | |
| 1103 | |
| 1104 // frame type (padding) | |
| 1105 0x00, | |
| 1106 0x00, 0x00, 0x00, 0x00 | |
| 1107 }; | |
| 1108 CheckProcessingFails(packet, | |
| 1109 arraysize(packet), | |
| 1110 "Illegal public flags value.", | |
| 1111 QUIC_INVALID_PACKET_HEADER); | |
| 1112 | |
| 1113 // Now turn off validation. | |
| 1114 framer_.set_validate_flags(false); | |
| 1115 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1116 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1117 }; | |
| 1118 | |
| 1119 TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) { | |
| 1120 unsigned char packet[] = { | |
| 1121 // public flags (8 byte connection_id and version flag and an unknown flag) | |
| 1122 0x4D, | |
| 1123 // connection_id | |
| 1124 0x10, 0x32, 0x54, 0x76, | |
| 1125 0x98, 0xBA, 0xDC, 0xFE, | |
| 1126 // version tag | |
| 1127 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), | |
| 1128 // packet sequence number | |
| 1129 0xBC, 0x9A, 0x78, 0x56, | |
| 1130 0x34, 0x12, | |
| 1131 // private flags | |
| 1132 0x00, | |
| 1133 | |
| 1134 // frame type (padding) | |
| 1135 0x00, | |
| 1136 0x00, 0x00, 0x00, 0x00 | |
| 1137 }; | |
| 1138 CheckProcessingFails(packet, | |
| 1139 arraysize(packet), | |
| 1140 "Illegal public flags value.", | |
| 1141 QUIC_INVALID_PACKET_HEADER); | |
| 1142 }; | |
| 1143 | |
| 1144 TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) { | |
| 1145 unsigned char packet[] = { | |
| 1146 // public flags (8 byte connection_id, version flag and an unknown flag) | |
| 1147 0x7D, | |
| 1148 // connection_id | |
| 1149 0x10, 0x32, 0x54, 0x76, | |
| 1150 0x98, 0xBA, 0xDC, 0xFE, | |
| 1151 // version tag | |
| 1152 'Q', '0', '0', '0', | |
| 1153 // packet sequence number | |
| 1154 0xBC, 0x9A, 0x78, 0x56, | |
| 1155 0x34, 0x12, | |
| 1156 // private flags | |
| 1157 0x00, | |
| 1158 | |
| 1159 // frame type (padding frame) | |
| 1160 0x00, | |
| 1161 0x00, 0x00, 0x00, 0x00 | |
| 1162 }; | |
| 1163 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1164 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1165 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1166 ASSERT_TRUE(visitor_.header_.get()); | |
| 1167 EXPECT_EQ(0, visitor_.frame_count_); | |
| 1168 EXPECT_EQ(1, visitor_.version_mismatch_); | |
| 1169 }; | |
| 1170 | |
| 1171 TEST_P(QuicFramerTest, InvalidPrivateFlag) { | |
| 1172 unsigned char packet[] = { | |
| 1173 // public flags (8 byte connection_id) | |
| 1174 0x3C, | |
| 1175 // connection_id | |
| 1176 0x10, 0x32, 0x54, 0x76, | |
| 1177 0x98, 0xBA, 0xDC, 0xFE, | |
| 1178 // packet sequence number | |
| 1179 0xBC, 0x9A, 0x78, 0x56, | |
| 1180 0x34, 0x12, | |
| 1181 // private flags | |
| 1182 0x10, | |
| 1183 | |
| 1184 // frame type (padding) | |
| 1185 0x00, | |
| 1186 0x00, 0x00, 0x00, 0x00 | |
| 1187 }; | |
| 1188 CheckProcessingFails(packet, | |
| 1189 arraysize(packet), | |
| 1190 "Illegal private flags value.", | |
| 1191 QUIC_INVALID_PACKET_HEADER); | |
| 1192 }; | |
| 1193 | |
| 1194 TEST_P(QuicFramerTest, InvalidFECGroupOffset) { | |
| 1195 unsigned char packet[] = { | |
| 1196 // public flags (8 byte connection_id) | |
| 1197 0x3C, | |
| 1198 // connection_id | |
| 1199 0x10, 0x32, 0x54, 0x76, | |
| 1200 0x98, 0xBA, 0xDC, 0xFE, | |
| 1201 // packet sequence number | |
| 1202 0x01, 0x00, 0x00, 0x00, | |
| 1203 0x00, 0x00, | |
| 1204 // private flags (fec group) | |
| 1205 0x02, | |
| 1206 // first fec protected packet offset | |
| 1207 0x10 | |
| 1208 }; | |
| 1209 CheckProcessingFails(packet, | |
| 1210 arraysize(packet), | |
| 1211 "First fec protected packet offset must be less " | |
| 1212 "than the sequence number.", | |
| 1213 QUIC_INVALID_PACKET_HEADER); | |
| 1214 }; | |
| 1215 | |
| 1216 TEST_P(QuicFramerTest, PaddingFrame) { | |
| 1217 unsigned char packet[] = { | |
| 1218 // public flags (8 byte connection_id) | |
| 1219 0x3C, | |
| 1220 // connection_id | |
| 1221 0x10, 0x32, 0x54, 0x76, | |
| 1222 0x98, 0xBA, 0xDC, 0xFE, | |
| 1223 // packet sequence number | |
| 1224 0xBC, 0x9A, 0x78, 0x56, | |
| 1225 0x34, 0x12, | |
| 1226 // private flags | |
| 1227 0x00, | |
| 1228 | |
| 1229 // frame type (padding frame) | |
| 1230 0x00, | |
| 1231 // Ignored data (which in this case is a stream frame) | |
| 1232 // frame type (stream frame with fin) | |
| 1233 0xFF, | |
| 1234 // stream id | |
| 1235 0x04, 0x03, 0x02, 0x01, | |
| 1236 // offset | |
| 1237 0x54, 0x76, 0x10, 0x32, | |
| 1238 0xDC, 0xFE, 0x98, 0xBA, | |
| 1239 // data length | |
| 1240 0x0c, 0x00, | |
| 1241 // data | |
| 1242 'h', 'e', 'l', 'l', | |
| 1243 'o', ' ', 'w', 'o', | |
| 1244 'r', 'l', 'd', '!', | |
| 1245 }; | |
| 1246 | |
| 1247 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1248 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1249 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1250 ASSERT_TRUE(visitor_.header_.get()); | |
| 1251 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1252 | |
| 1253 ASSERT_EQ(0u, visitor_.stream_frames_.size()); | |
| 1254 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1255 // A packet with no frames is not acceptable. | |
| 1256 CheckProcessingFails( | |
| 1257 packet, | |
| 1258 GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 1259 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 1260 "Packet has no frames.", QUIC_MISSING_PAYLOAD); | |
| 1261 } | |
| 1262 | |
| 1263 TEST_P(QuicFramerTest, StreamFrame) { | |
| 1264 unsigned char packet[] = { | |
| 1265 // public flags (8 byte connection_id) | |
| 1266 0x3C, | |
| 1267 // connection_id | |
| 1268 0x10, 0x32, 0x54, 0x76, | |
| 1269 0x98, 0xBA, 0xDC, 0xFE, | |
| 1270 // packet sequence number | |
| 1271 0xBC, 0x9A, 0x78, 0x56, | |
| 1272 0x34, 0x12, | |
| 1273 // private flags | |
| 1274 0x00, | |
| 1275 | |
| 1276 // frame type (stream frame with fin) | |
| 1277 0xFF, | |
| 1278 // stream id | |
| 1279 0x04, 0x03, 0x02, 0x01, | |
| 1280 // offset | |
| 1281 0x54, 0x76, 0x10, 0x32, | |
| 1282 0xDC, 0xFE, 0x98, 0xBA, | |
| 1283 // data length | |
| 1284 0x0c, 0x00, | |
| 1285 // data | |
| 1286 'h', 'e', 'l', 'l', | |
| 1287 'o', ' ', 'w', 'o', | |
| 1288 'r', 'l', 'd', '!', | |
| 1289 }; | |
| 1290 | |
| 1291 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1292 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1293 | |
| 1294 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1295 ASSERT_TRUE(visitor_.header_.get()); | |
| 1296 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1297 | |
| 1298 ASSERT_EQ(1u, visitor_.stream_frames_.size()); | |
| 1299 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1300 EXPECT_EQ(static_cast<uint64>(0x01020304), | |
| 1301 visitor_.stream_frames_[0]->stream_id); | |
| 1302 EXPECT_TRUE(visitor_.stream_frames_[0]->fin); | |
| 1303 EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654), | |
| 1304 visitor_.stream_frames_[0]->offset); | |
| 1305 CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); | |
| 1306 | |
| 1307 // Now test framing boundaries. | |
| 1308 CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, !kIncludeVersion); | |
| 1309 } | |
| 1310 | |
| 1311 TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) { | |
| 1312 unsigned char packet[] = { | |
| 1313 // public flags (8 byte connection_id) | |
| 1314 0x3C, | |
| 1315 // connection_id | |
| 1316 0x10, 0x32, 0x54, 0x76, | |
| 1317 0x98, 0xBA, 0xDC, 0xFE, | |
| 1318 // packet sequence number | |
| 1319 0xBC, 0x9A, 0x78, 0x56, | |
| 1320 0x34, 0x12, | |
| 1321 // private flags | |
| 1322 0x00, | |
| 1323 | |
| 1324 // frame type (stream frame with fin) | |
| 1325 0xFE, | |
| 1326 // stream id | |
| 1327 0x04, 0x03, 0x02, | |
| 1328 // offset | |
| 1329 0x54, 0x76, 0x10, 0x32, | |
| 1330 0xDC, 0xFE, 0x98, 0xBA, | |
| 1331 // data length | |
| 1332 0x0c, 0x00, | |
| 1333 // data | |
| 1334 'h', 'e', 'l', 'l', | |
| 1335 'o', ' ', 'w', 'o', | |
| 1336 'r', 'l', 'd', '!', | |
| 1337 }; | |
| 1338 | |
| 1339 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1340 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1341 | |
| 1342 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1343 ASSERT_TRUE(visitor_.header_.get()); | |
| 1344 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1345 | |
| 1346 ASSERT_EQ(1u, visitor_.stream_frames_.size()); | |
| 1347 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1348 EXPECT_EQ(GG_UINT64_C(0x00020304), visitor_.stream_frames_[0]->stream_id); | |
| 1349 EXPECT_TRUE(visitor_.stream_frames_[0]->fin); | |
| 1350 EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654), | |
| 1351 visitor_.stream_frames_[0]->offset); | |
| 1352 CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); | |
| 1353 | |
| 1354 // Now test framing boundaries. | |
| 1355 const size_t stream_id_size = 3; | |
| 1356 CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion); | |
| 1357 } | |
| 1358 | |
| 1359 TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) { | |
| 1360 unsigned char packet[] = { | |
| 1361 // public flags (8 byte connection_id) | |
| 1362 0x3C, | |
| 1363 // connection_id | |
| 1364 0x10, 0x32, 0x54, 0x76, | |
| 1365 0x98, 0xBA, 0xDC, 0xFE, | |
| 1366 // packet sequence number | |
| 1367 0xBC, 0x9A, 0x78, 0x56, | |
| 1368 0x34, 0x12, | |
| 1369 // private flags | |
| 1370 0x00, | |
| 1371 | |
| 1372 // frame type (stream frame with fin) | |
| 1373 0xFD, | |
| 1374 // stream id | |
| 1375 0x04, 0x03, | |
| 1376 // offset | |
| 1377 0x54, 0x76, 0x10, 0x32, | |
| 1378 0xDC, 0xFE, 0x98, 0xBA, | |
| 1379 // data length | |
| 1380 0x0c, 0x00, | |
| 1381 // data | |
| 1382 'h', 'e', 'l', 'l', | |
| 1383 'o', ' ', 'w', 'o', | |
| 1384 'r', 'l', 'd', '!', | |
| 1385 }; | |
| 1386 | |
| 1387 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1388 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1389 | |
| 1390 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1391 ASSERT_TRUE(visitor_.header_.get()); | |
| 1392 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1393 | |
| 1394 ASSERT_EQ(1u, visitor_.stream_frames_.size()); | |
| 1395 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1396 EXPECT_EQ(static_cast<uint64>(0x00000304), | |
| 1397 visitor_.stream_frames_[0]->stream_id); | |
| 1398 EXPECT_TRUE(visitor_.stream_frames_[0]->fin); | |
| 1399 EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654), | |
| 1400 visitor_.stream_frames_[0]->offset); | |
| 1401 CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); | |
| 1402 | |
| 1403 // Now test framing boundaries. | |
| 1404 const size_t stream_id_size = 2; | |
| 1405 CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion); | |
| 1406 } | |
| 1407 | |
| 1408 TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) { | |
| 1409 unsigned char packet[] = { | |
| 1410 // public flags (8 byte connection_id) | |
| 1411 0x3C, | |
| 1412 // connection_id | |
| 1413 0x10, 0x32, 0x54, 0x76, | |
| 1414 0x98, 0xBA, 0xDC, 0xFE, | |
| 1415 // packet sequence number | |
| 1416 0xBC, 0x9A, 0x78, 0x56, | |
| 1417 0x34, 0x12, | |
| 1418 // private flags | |
| 1419 0x00, | |
| 1420 | |
| 1421 // frame type (stream frame with fin) | |
| 1422 0xFC, | |
| 1423 // stream id | |
| 1424 0x04, | |
| 1425 // offset | |
| 1426 0x54, 0x76, 0x10, 0x32, | |
| 1427 0xDC, 0xFE, 0x98, 0xBA, | |
| 1428 // data length | |
| 1429 0x0c, 0x00, | |
| 1430 // data | |
| 1431 'h', 'e', 'l', 'l', | |
| 1432 'o', ' ', 'w', 'o', | |
| 1433 'r', 'l', 'd', '!', | |
| 1434 }; | |
| 1435 | |
| 1436 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1437 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1438 | |
| 1439 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1440 ASSERT_TRUE(visitor_.header_.get()); | |
| 1441 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1442 | |
| 1443 ASSERT_EQ(1u, visitor_.stream_frames_.size()); | |
| 1444 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1445 EXPECT_EQ(static_cast<uint64>(0x00000004), | |
| 1446 visitor_.stream_frames_[0]->stream_id); | |
| 1447 EXPECT_TRUE(visitor_.stream_frames_[0]->fin); | |
| 1448 EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654), | |
| 1449 visitor_.stream_frames_[0]->offset); | |
| 1450 CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); | |
| 1451 | |
| 1452 // Now test framing boundaries. | |
| 1453 const size_t stream_id_size = 1; | |
| 1454 CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion); | |
| 1455 } | |
| 1456 | |
| 1457 TEST_P(QuicFramerTest, StreamFrameWithVersion) { | |
| 1458 unsigned char packet[] = { | |
| 1459 // public flags (version, 8 byte connection_id) | |
| 1460 0x3D, | |
| 1461 // connection_id | |
| 1462 0x10, 0x32, 0x54, 0x76, | |
| 1463 0x98, 0xBA, 0xDC, 0xFE, | |
| 1464 // version tag | |
| 1465 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), | |
| 1466 // packet sequence number | |
| 1467 0xBC, 0x9A, 0x78, 0x56, | |
| 1468 0x34, 0x12, | |
| 1469 // private flags | |
| 1470 0x00, | |
| 1471 | |
| 1472 // frame type (stream frame with fin) | |
| 1473 0xFF, | |
| 1474 // stream id | |
| 1475 0x04, 0x03, 0x02, 0x01, | |
| 1476 // offset | |
| 1477 0x54, 0x76, 0x10, 0x32, | |
| 1478 0xDC, 0xFE, 0x98, 0xBA, | |
| 1479 // data length | |
| 1480 0x0c, 0x00, | |
| 1481 // data | |
| 1482 'h', 'e', 'l', 'l', | |
| 1483 'o', ' ', 'w', 'o', | |
| 1484 'r', 'l', 'd', '!', | |
| 1485 }; | |
| 1486 | |
| 1487 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1488 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1489 | |
| 1490 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1491 ASSERT_TRUE(visitor_.header_.get()); | |
| 1492 EXPECT_TRUE(visitor_.header_->public_header.version_flag); | |
| 1493 EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]); | |
| 1494 EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion)); | |
| 1495 | |
| 1496 ASSERT_EQ(1u, visitor_.stream_frames_.size()); | |
| 1497 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1498 EXPECT_EQ(static_cast<uint64>(0x01020304), | |
| 1499 visitor_.stream_frames_[0]->stream_id); | |
| 1500 EXPECT_TRUE(visitor_.stream_frames_[0]->fin); | |
| 1501 EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654), | |
| 1502 visitor_.stream_frames_[0]->offset); | |
| 1503 CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); | |
| 1504 | |
| 1505 // Now test framing boundaries. | |
| 1506 CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, kIncludeVersion); | |
| 1507 } | |
| 1508 | |
| 1509 TEST_P(QuicFramerTest, RejectPacket) { | |
| 1510 visitor_.accept_packet_ = false; | |
| 1511 | |
| 1512 unsigned char packet[] = { | |
| 1513 // public flags (8 byte connection_id) | |
| 1514 0x3C, | |
| 1515 // connection_id | |
| 1516 0x10, 0x32, 0x54, 0x76, | |
| 1517 0x98, 0xBA, 0xDC, 0xFE, | |
| 1518 // packet sequence number | |
| 1519 0xBC, 0x9A, 0x78, 0x56, | |
| 1520 0x34, 0x12, | |
| 1521 // private flags | |
| 1522 0x00, | |
| 1523 | |
| 1524 // frame type (stream frame with fin) | |
| 1525 0xFF, | |
| 1526 // stream id | |
| 1527 0x04, 0x03, 0x02, 0x01, | |
| 1528 // offset | |
| 1529 0x54, 0x76, 0x10, 0x32, | |
| 1530 0xDC, 0xFE, 0x98, 0xBA, | |
| 1531 // data length | |
| 1532 0x0c, 0x00, | |
| 1533 // data | |
| 1534 'h', 'e', 'l', 'l', | |
| 1535 'o', ' ', 'w', 'o', | |
| 1536 'r', 'l', 'd', '!', | |
| 1537 }; | |
| 1538 | |
| 1539 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1540 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1541 | |
| 1542 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1543 ASSERT_TRUE(visitor_.header_.get()); | |
| 1544 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1545 | |
| 1546 ASSERT_EQ(0u, visitor_.stream_frames_.size()); | |
| 1547 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1548 } | |
| 1549 | |
| 1550 TEST_P(QuicFramerTest, RejectPublicHeader) { | |
| 1551 visitor_.accept_public_header_ = false; | |
| 1552 | |
| 1553 unsigned char packet[] = { | |
| 1554 // public flags (8 byte connection_id) | |
| 1555 0x3C, | |
| 1556 // connection_id | |
| 1557 0x10, 0x32, 0x54, 0x76, | |
| 1558 0x98, 0xBA, 0xDC, 0xFE, | |
| 1559 }; | |
| 1560 | |
| 1561 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1562 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1563 | |
| 1564 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1565 ASSERT_TRUE(visitor_.public_header_.get()); | |
| 1566 ASSERT_FALSE(visitor_.header_.get()); | |
| 1567 } | |
| 1568 | |
| 1569 TEST_P(QuicFramerTest, RevivedStreamFrame) { | |
| 1570 unsigned char payload[] = { | |
| 1571 // frame type (stream frame with fin) | |
| 1572 0xFF, | |
| 1573 // stream id | |
| 1574 0x04, 0x03, 0x02, 0x01, | |
| 1575 // offset | |
| 1576 0x54, 0x76, 0x10, 0x32, | |
| 1577 0xDC, 0xFE, 0x98, 0xBA, | |
| 1578 // data length | |
| 1579 0x0c, 0x00, | |
| 1580 // data | |
| 1581 'h', 'e', 'l', 'l', | |
| 1582 'o', ' ', 'w', 'o', | |
| 1583 'r', 'l', 'd', '!', | |
| 1584 }; | |
| 1585 | |
| 1586 QuicPacketHeader header; | |
| 1587 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 1588 header.public_header.reset_flag = false; | |
| 1589 header.public_header.version_flag = false; | |
| 1590 header.fec_flag = true; | |
| 1591 header.entropy_flag = true; | |
| 1592 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 1593 header.fec_group = 0; | |
| 1594 | |
| 1595 // Do not encrypt the payload because the revived payload is post-encryption. | |
| 1596 EXPECT_TRUE(framer_.ProcessRevivedPacket(&header, | |
| 1597 StringPiece(AsChars(payload), | |
| 1598 arraysize(payload)))); | |
| 1599 | |
| 1600 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1601 ASSERT_EQ(1, visitor_.revived_packets_); | |
| 1602 ASSERT_TRUE(visitor_.header_.get()); | |
| 1603 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 1604 visitor_.header_->public_header.connection_id); | |
| 1605 EXPECT_FALSE(visitor_.header_->public_header.reset_flag); | |
| 1606 EXPECT_FALSE(visitor_.header_->public_header.version_flag); | |
| 1607 EXPECT_TRUE(visitor_.header_->fec_flag); | |
| 1608 EXPECT_TRUE(visitor_.header_->entropy_flag); | |
| 1609 EXPECT_EQ(1 << (header.packet_sequence_number % 8), | |
| 1610 visitor_.header_->entropy_hash); | |
| 1611 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 1612 visitor_.header_->packet_sequence_number); | |
| 1613 EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 1614 EXPECT_EQ(0x00u, visitor_.header_->fec_group); | |
| 1615 | |
| 1616 ASSERT_EQ(1u, visitor_.stream_frames_.size()); | |
| 1617 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1618 EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.stream_frames_[0]->stream_id); | |
| 1619 EXPECT_TRUE(visitor_.stream_frames_[0]->fin); | |
| 1620 EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654), | |
| 1621 visitor_.stream_frames_[0]->offset); | |
| 1622 CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); | |
| 1623 } | |
| 1624 | |
| 1625 TEST_P(QuicFramerTest, StreamFrameInFecGroup) { | |
| 1626 unsigned char packet[] = { | |
| 1627 // public flags (8 byte connection_id) | |
| 1628 0x3C, | |
| 1629 // connection_id | |
| 1630 0x10, 0x32, 0x54, 0x76, | |
| 1631 0x98, 0xBA, 0xDC, 0xFE, | |
| 1632 // packet sequence number | |
| 1633 0xBC, 0x9A, 0x78, 0x56, | |
| 1634 0x12, 0x34, | |
| 1635 // private flags (fec group) | |
| 1636 0x02, | |
| 1637 // first fec protected packet offset | |
| 1638 0x02, | |
| 1639 | |
| 1640 // frame type (stream frame with fin) | |
| 1641 0xFF, | |
| 1642 // stream id | |
| 1643 0x04, 0x03, 0x02, 0x01, | |
| 1644 // offset | |
| 1645 0x54, 0x76, 0x10, 0x32, | |
| 1646 0xDC, 0xFE, 0x98, 0xBA, | |
| 1647 // data length | |
| 1648 0x0c, 0x00, | |
| 1649 // data | |
| 1650 'h', 'e', 'l', 'l', | |
| 1651 'o', ' ', 'w', 'o', | |
| 1652 'r', 'l', 'd', '!', | |
| 1653 }; | |
| 1654 | |
| 1655 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1656 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1657 | |
| 1658 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1659 ASSERT_TRUE(visitor_.header_.get()); | |
| 1660 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1661 EXPECT_EQ(IN_FEC_GROUP, visitor_.header_->is_in_fec_group); | |
| 1662 EXPECT_EQ(GG_UINT64_C(0x341256789ABA), | |
| 1663 visitor_.header_->fec_group); | |
| 1664 const size_t fec_offset = | |
| 1665 GetStartOfFecProtectedData(PACKET_8BYTE_CONNECTION_ID, | |
| 1666 !kIncludeVersion, | |
| 1667 PACKET_6BYTE_SEQUENCE_NUMBER); | |
| 1668 EXPECT_EQ( | |
| 1669 string(AsChars(packet) + fec_offset, arraysize(packet) - fec_offset), | |
| 1670 visitor_.fec_protected_payload_); | |
| 1671 | |
| 1672 ASSERT_EQ(1u, visitor_.stream_frames_.size()); | |
| 1673 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 1674 EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.stream_frames_[0]->stream_id); | |
| 1675 EXPECT_TRUE(visitor_.stream_frames_[0]->fin); | |
| 1676 EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654), | |
| 1677 visitor_.stream_frames_[0]->offset); | |
| 1678 CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); | |
| 1679 } | |
| 1680 | |
| 1681 TEST_P(QuicFramerTest, AckFrameTwoTimestamp) { | |
| 1682 unsigned char packet[] = { | |
| 1683 // public flags (8 byte connection_id) | |
| 1684 0x3C, | |
| 1685 // connection_id | |
| 1686 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 1687 // packet sequence number | |
| 1688 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 1689 // private flags (entropy) | |
| 1690 0x01, | |
| 1691 | |
| 1692 // frame type (ack frame) | |
| 1693 // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) | |
| 1694 0x6C, | |
| 1695 // entropy hash of all received packets. | |
| 1696 0xBA, | |
| 1697 // largest observed packet sequence number | |
| 1698 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 1699 // Zero delta time. | |
| 1700 0x00, 0x00, | |
| 1701 // Number of timestamps. | |
| 1702 0x02, | |
| 1703 // Delta from largest observed. | |
| 1704 0x01, | |
| 1705 // Delta time. | |
| 1706 0x10, 0x32, 0x54, 0x76, | |
| 1707 // Delta from largest observed. | |
| 1708 0x02, | |
| 1709 // Delta time. | |
| 1710 0x10, 0x32, | |
| 1711 // num missing packets | |
| 1712 0x01, | |
| 1713 // missing packet delta | |
| 1714 0x01, | |
| 1715 // 0 more missing packets in range. | |
| 1716 0x00, | |
| 1717 // Number of revived packets. | |
| 1718 0x00, | |
| 1719 }; | |
| 1720 | |
| 1721 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1722 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1723 | |
| 1724 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1725 ASSERT_TRUE(visitor_.header_.get()); | |
| 1726 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1727 | |
| 1728 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 1729 ASSERT_EQ(1u, visitor_.ack_frames_.size()); | |
| 1730 const QuicAckFrame& frame = *visitor_.ack_frames_[0]; | |
| 1731 EXPECT_EQ(0xBA, frame.entropy_hash); | |
| 1732 EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed); | |
| 1733 ASSERT_EQ(1u, frame.missing_packets.size()); | |
| 1734 ASSERT_EQ(2u, frame.received_packet_times.size()); | |
| 1735 SequenceNumberSet::const_iterator missing_iter = | |
| 1736 frame.missing_packets.begin(); | |
| 1737 EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter); | |
| 1738 | |
| 1739 const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; | |
| 1740 const size_t kLargestObservedOffset = kReceivedEntropyOffset + | |
| 1741 kQuicEntropyHashSize; | |
| 1742 const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + | |
| 1743 PACKET_6BYTE_SEQUENCE_NUMBER; | |
| 1744 const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset + | |
| 1745 kQuicDeltaTimeLargestObservedSize; | |
| 1746 const size_t kTimestampDeltaLargestObserved1 = kNumTimestampsOffset + | |
| 1747 kQuicNumTimestampsSize; | |
| 1748 const size_t kTimestampTimeDeltaLargestObserved1 = | |
| 1749 kTimestampDeltaLargestObserved1 + 1; | |
| 1750 const size_t kTimestampDeltaLargestObserved2 = | |
| 1751 kTimestampTimeDeltaLargestObserved1 + 4; | |
| 1752 const size_t kTimestampTimeDeltaLargestObserved2 = | |
| 1753 kTimestampDeltaLargestObserved2 + 1; | |
| 1754 const size_t kNumMissingPacketOffset = | |
| 1755 kTimestampTimeDeltaLargestObserved2 + 2; | |
| 1756 const size_t kMissingPacketsOffset = kNumMissingPacketOffset + | |
| 1757 kNumberOfNackRangesSize; | |
| 1758 const size_t kMissingPacketsRange = kMissingPacketsOffset + | |
| 1759 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1760 const size_t kRevivedPacketsLength = kMissingPacketsRange + | |
| 1761 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1762 // Now test framing boundaries. | |
| 1763 const size_t ack_frame_size = kRevivedPacketsLength + | |
| 1764 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1765 for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { | |
| 1766 string expected_error; | |
| 1767 if (i < kLargestObservedOffset) { | |
| 1768 expected_error = "Unable to read entropy hash for received packets."; | |
| 1769 } else if (i < kMissingDeltaTimeOffset) { | |
| 1770 expected_error = "Unable to read largest observed."; | |
| 1771 } else if (i < kNumTimestampsOffset) { | |
| 1772 expected_error = "Unable to read delta time largest observed."; | |
| 1773 } else if (i < kTimestampDeltaLargestObserved1) { | |
| 1774 expected_error = "Unable to read num received packets."; | |
| 1775 } else if (i < kTimestampTimeDeltaLargestObserved1) { | |
| 1776 expected_error = "Unable to read sequence delta in received packets."; | |
| 1777 } else if (i < kTimestampDeltaLargestObserved2) { | |
| 1778 expected_error = "Unable to read time delta in received packets."; | |
| 1779 } else if (i < kTimestampTimeDeltaLargestObserved2) { | |
| 1780 expected_error = "Unable to read sequence delta in received packets."; | |
| 1781 } else if (i < kNumMissingPacketOffset) { | |
| 1782 expected_error = | |
| 1783 "Unable to read incremental time delta in received packets."; | |
| 1784 } else if (i < kMissingPacketsOffset) { | |
| 1785 expected_error = "Unable to read num missing packet ranges."; | |
| 1786 } else if (i < kMissingPacketsRange) { | |
| 1787 expected_error = "Unable to read missing sequence number delta."; | |
| 1788 } else if (i < kRevivedPacketsLength) { | |
| 1789 expected_error = "Unable to read missing sequence number range."; | |
| 1790 } else { | |
| 1791 expected_error = "Unable to read num revived packets."; | |
| 1792 } | |
| 1793 CheckProcessingFails( | |
| 1794 packet, | |
| 1795 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 1796 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 1797 expected_error, QUIC_INVALID_ACK_DATA); | |
| 1798 } | |
| 1799 } | |
| 1800 | |
| 1801 | |
| 1802 TEST_P(QuicFramerTest, AckFrameOneTimestamp) { | |
| 1803 unsigned char packet[] = { | |
| 1804 // public flags (8 byte connection_id) | |
| 1805 0x3C, | |
| 1806 // connection_id | |
| 1807 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 1808 // packet sequence number | |
| 1809 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 1810 // private flags (entropy) | |
| 1811 0x01, | |
| 1812 | |
| 1813 // frame type (ack frame) | |
| 1814 // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) | |
| 1815 0x6C, | |
| 1816 // entropy hash of all received packets. | |
| 1817 0xBA, | |
| 1818 // largest observed packet sequence number | |
| 1819 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 1820 // Zero delta time. | |
| 1821 0x00, 0x00, | |
| 1822 // Number of timestamps. | |
| 1823 0x01, | |
| 1824 // Delta from largest observed. | |
| 1825 0x01, | |
| 1826 // Delta time. | |
| 1827 0x10, 0x32, 0x54, 0x76, | |
| 1828 // num missing packets | |
| 1829 0x01, | |
| 1830 // missing packet delta | |
| 1831 0x01, | |
| 1832 // 0 more missing packets in range. | |
| 1833 0x00, | |
| 1834 // Number of revived packets. | |
| 1835 0x00, | |
| 1836 }; | |
| 1837 | |
| 1838 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1839 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1840 | |
| 1841 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1842 ASSERT_TRUE(visitor_.header_.get()); | |
| 1843 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1844 | |
| 1845 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 1846 ASSERT_EQ(1u, visitor_.ack_frames_.size()); | |
| 1847 const QuicAckFrame& frame = *visitor_.ack_frames_[0]; | |
| 1848 EXPECT_EQ(0xBA, frame.entropy_hash); | |
| 1849 EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed); | |
| 1850 ASSERT_EQ(1u, frame.missing_packets.size()); | |
| 1851 ASSERT_EQ(1u, frame.received_packet_times.size()); | |
| 1852 SequenceNumberSet::const_iterator missing_iter = | |
| 1853 frame.missing_packets.begin(); | |
| 1854 EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter); | |
| 1855 | |
| 1856 const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; | |
| 1857 const size_t kLargestObservedOffset = kReceivedEntropyOffset + | |
| 1858 kQuicEntropyHashSize; | |
| 1859 const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + | |
| 1860 PACKET_6BYTE_SEQUENCE_NUMBER; | |
| 1861 const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset + | |
| 1862 kQuicDeltaTimeLargestObservedSize; | |
| 1863 const size_t kTimestampDeltaLargestObserved = kNumTimestampsOffset + | |
| 1864 kQuicNumTimestampsSize; | |
| 1865 const size_t kTimestampTimeDeltaLargestObserved = | |
| 1866 kTimestampDeltaLargestObserved + 1; | |
| 1867 const size_t kNumMissingPacketOffset = kTimestampTimeDeltaLargestObserved + 4; | |
| 1868 const size_t kMissingPacketsOffset = kNumMissingPacketOffset + | |
| 1869 kNumberOfNackRangesSize; | |
| 1870 const size_t kMissingPacketsRange = kMissingPacketsOffset + | |
| 1871 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1872 const size_t kRevivedPacketsLength = kMissingPacketsRange + | |
| 1873 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1874 // Now test framing boundaries. | |
| 1875 const size_t ack_frame_size = kRevivedPacketsLength + | |
| 1876 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1877 for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { | |
| 1878 string expected_error; | |
| 1879 if (i < kLargestObservedOffset) { | |
| 1880 expected_error = "Unable to read entropy hash for received packets."; | |
| 1881 } else if (i < kMissingDeltaTimeOffset) { | |
| 1882 expected_error = "Unable to read largest observed."; | |
| 1883 } else if (i < kNumTimestampsOffset) { | |
| 1884 expected_error = "Unable to read delta time largest observed."; | |
| 1885 } else if (i < kTimestampDeltaLargestObserved) { | |
| 1886 expected_error = "Unable to read num received packets."; | |
| 1887 } else if (i < kTimestampTimeDeltaLargestObserved) { | |
| 1888 expected_error = "Unable to read sequence delta in received packets."; | |
| 1889 } else if (i < kNumMissingPacketOffset) { | |
| 1890 expected_error = "Unable to read time delta in received packets."; | |
| 1891 } else if (i < kMissingPacketsOffset) { | |
| 1892 expected_error = "Unable to read num missing packet ranges."; | |
| 1893 } else if (i < kMissingPacketsRange) { | |
| 1894 expected_error = "Unable to read missing sequence number delta."; | |
| 1895 } else if (i < kRevivedPacketsLength) { | |
| 1896 expected_error = "Unable to read missing sequence number range."; | |
| 1897 } else { | |
| 1898 expected_error = "Unable to read num revived packets."; | |
| 1899 } | |
| 1900 CheckProcessingFails( | |
| 1901 packet, | |
| 1902 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 1903 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 1904 expected_error, QUIC_INVALID_ACK_DATA); | |
| 1905 } | |
| 1906 } | |
| 1907 | |
| 1908 | |
| 1909 TEST_P(QuicFramerTest, AckFrame) { | |
| 1910 unsigned char packet[] = { | |
| 1911 // public flags (8 byte connection_id) | |
| 1912 0x3C, | |
| 1913 // connection_id | |
| 1914 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 1915 // packet sequence number | |
| 1916 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 1917 // private flags (entropy) | |
| 1918 0x01, | |
| 1919 | |
| 1920 // frame type (ack frame) | |
| 1921 // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) | |
| 1922 0x6C, | |
| 1923 // entropy hash of all received packets. | |
| 1924 0xBA, | |
| 1925 // largest observed packet sequence number | |
| 1926 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 1927 // Zero delta time. | |
| 1928 0x00, 0x00, | |
| 1929 // Number of timestamps. | |
| 1930 0x00, | |
| 1931 // num missing packets | |
| 1932 0x01, | |
| 1933 // missing packet delta | |
| 1934 0x01, | |
| 1935 // 0 more missing packets in range. | |
| 1936 0x00, | |
| 1937 // Number of revived packets. | |
| 1938 0x00, | |
| 1939 }; | |
| 1940 | |
| 1941 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 1942 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 1943 | |
| 1944 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 1945 ASSERT_TRUE(visitor_.header_.get()); | |
| 1946 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 1947 | |
| 1948 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 1949 ASSERT_EQ(1u, visitor_.ack_frames_.size()); | |
| 1950 const QuicAckFrame& frame = *visitor_.ack_frames_[0]; | |
| 1951 EXPECT_EQ(0xBA, frame.entropy_hash); | |
| 1952 EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed); | |
| 1953 ASSERT_EQ(1u, frame.missing_packets.size()); | |
| 1954 SequenceNumberSet::const_iterator missing_iter = | |
| 1955 frame.missing_packets.begin(); | |
| 1956 EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter); | |
| 1957 | |
| 1958 const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; | |
| 1959 const size_t kLargestObservedOffset = kReceivedEntropyOffset + | |
| 1960 kQuicEntropyHashSize; | |
| 1961 const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + | |
| 1962 PACKET_6BYTE_SEQUENCE_NUMBER; | |
| 1963 const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset + | |
| 1964 kQuicDeltaTimeLargestObservedSize; | |
| 1965 const size_t kNumMissingPacketOffset = kNumTimestampsOffset + | |
| 1966 kQuicNumTimestampsSize; | |
| 1967 const size_t kMissingPacketsOffset = kNumMissingPacketOffset + | |
| 1968 kNumberOfNackRangesSize; | |
| 1969 const size_t kMissingPacketsRange = kMissingPacketsOffset + | |
| 1970 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1971 const size_t kRevivedPacketsLength = kMissingPacketsRange + | |
| 1972 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1973 // Now test framing boundaries. | |
| 1974 const size_t ack_frame_size = kRevivedPacketsLength + | |
| 1975 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 1976 for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { | |
| 1977 string expected_error; | |
| 1978 if (i < kLargestObservedOffset) { | |
| 1979 expected_error = "Unable to read entropy hash for received packets."; | |
| 1980 } else if (i < kMissingDeltaTimeOffset) { | |
| 1981 expected_error = "Unable to read largest observed."; | |
| 1982 } else if (i < kNumTimestampsOffset) { | |
| 1983 expected_error = "Unable to read delta time largest observed."; | |
| 1984 } else if (i < kNumMissingPacketOffset) { | |
| 1985 expected_error = "Unable to read num received packets."; | |
| 1986 } else if (i < kMissingPacketsOffset) { | |
| 1987 expected_error = "Unable to read num missing packet ranges."; | |
| 1988 } else if (i < kMissingPacketsRange) { | |
| 1989 expected_error = "Unable to read missing sequence number delta."; | |
| 1990 } else if (i < kRevivedPacketsLength) { | |
| 1991 expected_error = "Unable to read missing sequence number range."; | |
| 1992 } else { | |
| 1993 expected_error = "Unable to read num revived packets."; | |
| 1994 } | |
| 1995 CheckProcessingFails( | |
| 1996 packet, | |
| 1997 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 1998 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 1999 expected_error, QUIC_INVALID_ACK_DATA); | |
| 2000 } | |
| 2001 } | |
| 2002 | |
| 2003 TEST_P(QuicFramerTest, AckFrameRevivedPackets) { | |
| 2004 unsigned char packet[] = { | |
| 2005 // public flags (8 byte connection_id) | |
| 2006 0x3C, | |
| 2007 // connection_id | |
| 2008 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 2009 // packet sequence number | |
| 2010 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 2011 // private flags (entropy) | |
| 2012 0x01, | |
| 2013 | |
| 2014 // frame type (ack frame) | |
| 2015 // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) | |
| 2016 0x6C, | |
| 2017 // entropy hash of all received packets. | |
| 2018 0xBA, | |
| 2019 // largest observed packet sequence number | |
| 2020 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 2021 // Zero delta time. | |
| 2022 0x00, 0x00, | |
| 2023 // num received packets. | |
| 2024 0x00, | |
| 2025 // num missing packets | |
| 2026 0x01, | |
| 2027 // missing packet delta | |
| 2028 0x01, | |
| 2029 // 0 more missing packets in range. | |
| 2030 0x00, | |
| 2031 // Number of revived packets. | |
| 2032 0x01, | |
| 2033 // Revived packet sequence number. | |
| 2034 0xBE, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 2035 // Number of revived packets. | |
| 2036 0x00, | |
| 2037 }; | |
| 2038 | |
| 2039 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2040 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2041 | |
| 2042 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2043 ASSERT_TRUE(visitor_.header_.get()); | |
| 2044 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2045 | |
| 2046 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 2047 ASSERT_EQ(1u, visitor_.ack_frames_.size()); | |
| 2048 const QuicAckFrame& frame = *visitor_.ack_frames_[0]; | |
| 2049 EXPECT_EQ(0xBA, frame.entropy_hash); | |
| 2050 EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed); | |
| 2051 ASSERT_EQ(1u, frame.missing_packets.size()); | |
| 2052 SequenceNumberSet::const_iterator missing_iter = | |
| 2053 frame.missing_packets.begin(); | |
| 2054 EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter); | |
| 2055 | |
| 2056 const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; | |
| 2057 const size_t kLargestObservedOffset = kReceivedEntropyOffset + | |
| 2058 kQuicEntropyHashSize; | |
| 2059 const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + | |
| 2060 PACKET_6BYTE_SEQUENCE_NUMBER; | |
| 2061 const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset + | |
| 2062 kQuicDeltaTimeLargestObservedSize; | |
| 2063 const size_t kNumMissingPacketOffset = kNumTimestampsOffset + | |
| 2064 kQuicNumTimestampsSize; | |
| 2065 const size_t kMissingPacketsOffset = kNumMissingPacketOffset + | |
| 2066 kNumberOfNackRangesSize; | |
| 2067 const size_t kMissingPacketsRange = kMissingPacketsOffset + | |
| 2068 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 2069 const size_t kRevivedPacketsLength = kMissingPacketsRange + | |
| 2070 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 2071 const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength + | |
| 2072 PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 2073 // Now test framing boundaries. | |
| 2074 const size_t ack_frame_size = kRevivedPacketSequenceNumberLength + | |
| 2075 PACKET_6BYTE_SEQUENCE_NUMBER; | |
| 2076 for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { | |
| 2077 string expected_error; | |
| 2078 if (i < kReceivedEntropyOffset) { | |
| 2079 expected_error = "Unable to read least unacked delta."; | |
| 2080 } else if (i < kLargestObservedOffset) { | |
| 2081 expected_error = "Unable to read entropy hash for received packets."; | |
| 2082 } else if (i < kMissingDeltaTimeOffset) { | |
| 2083 expected_error = "Unable to read largest observed."; | |
| 2084 } else if (i < kNumTimestampsOffset) { | |
| 2085 expected_error = "Unable to read delta time largest observed."; | |
| 2086 } else if (i < kNumMissingPacketOffset) { | |
| 2087 expected_error = "Unable to read num received packets."; | |
| 2088 } else if (i < kMissingPacketsOffset) { | |
| 2089 expected_error = "Unable to read num missing packet ranges."; | |
| 2090 } else if (i < kMissingPacketsRange) { | |
| 2091 expected_error = "Unable to read missing sequence number delta."; | |
| 2092 } else if (i < kRevivedPacketsLength) { | |
| 2093 expected_error = "Unable to read missing sequence number range."; | |
| 2094 } else if (i < kRevivedPacketSequenceNumberLength) { | |
| 2095 expected_error = "Unable to read num revived packets."; | |
| 2096 } else { | |
| 2097 expected_error = "Unable to read revived packet."; | |
| 2098 } | |
| 2099 CheckProcessingFails( | |
| 2100 packet, | |
| 2101 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2102 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 2103 expected_error, QUIC_INVALID_ACK_DATA); | |
| 2104 } | |
| 2105 } | |
| 2106 | |
| 2107 TEST_P(QuicFramerTest, AckFrameNoNacks) { | |
| 2108 unsigned char packet[] = { | |
| 2109 // public flags (8 byte connection_id) | |
| 2110 0x3C, | |
| 2111 // connection_id | |
| 2112 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 2113 // packet sequence number | |
| 2114 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 2115 // private flags (entropy) | |
| 2116 0x01, | |
| 2117 | |
| 2118 // frame type (ack frame) | |
| 2119 // (no nacks, not truncated, 6 byte largest observed, 1 byte delta) | |
| 2120 0x4C, | |
| 2121 // entropy hash of all received packets. | |
| 2122 0xBA, | |
| 2123 // largest observed packet sequence number | |
| 2124 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 2125 // Zero delta time. | |
| 2126 0x00, 0x00, | |
| 2127 // Number of received packets. | |
| 2128 0x00, | |
| 2129 }; | |
| 2130 | |
| 2131 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2132 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2133 | |
| 2134 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2135 ASSERT_TRUE(visitor_.header_.get()); | |
| 2136 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2137 | |
| 2138 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 2139 ASSERT_EQ(1u, visitor_.ack_frames_.size()); | |
| 2140 QuicAckFrame* frame = visitor_.ack_frames_[0]; | |
| 2141 EXPECT_EQ(0xBA, frame->entropy_hash); | |
| 2142 EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed); | |
| 2143 ASSERT_EQ(0u, frame->missing_packets.size()); | |
| 2144 | |
| 2145 // Verify that the packet re-serializes identically. | |
| 2146 QuicFrames frames; | |
| 2147 frames.push_back(QuicFrame(frame)); | |
| 2148 scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames)); | |
| 2149 ASSERT_TRUE(data != nullptr); | |
| 2150 | |
| 2151 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
| 2152 data->length(), AsChars(packet), | |
| 2153 arraysize(packet)); | |
| 2154 } | |
| 2155 | |
| 2156 TEST_P(QuicFramerTest, AckFrame500Nacks) { | |
| 2157 unsigned char packet[] = { | |
| 2158 // public flags (8 byte connection_id) | |
| 2159 0x3C, | |
| 2160 // connection_id | |
| 2161 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 2162 // packet sequence number | |
| 2163 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 2164 // private flags (entropy) | |
| 2165 0x01, | |
| 2166 | |
| 2167 // frame type (ack frame) | |
| 2168 // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) | |
| 2169 0x6C, | |
| 2170 // entropy hash of all received packets. | |
| 2171 0xBA, | |
| 2172 // largest observed packet sequence number | |
| 2173 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 2174 // Zero delta time. | |
| 2175 0x00, 0x00, | |
| 2176 // No received packets. | |
| 2177 0x00, | |
| 2178 // num missing packet ranges | |
| 2179 0x02, | |
| 2180 // missing packet delta | |
| 2181 0x01, | |
| 2182 // 243 more missing packets in range. | |
| 2183 // The ranges are listed in this order so the re-constructed packet | |
| 2184 // matches. | |
| 2185 0xF3, | |
| 2186 // No gap between ranges | |
| 2187 0x00, | |
| 2188 // 255 more missing packets in range. | |
| 2189 0xFF, | |
| 2190 // No revived packets. | |
| 2191 0x00, | |
| 2192 }; | |
| 2193 | |
| 2194 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2195 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2196 | |
| 2197 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2198 ASSERT_TRUE(visitor_.header_.get()); | |
| 2199 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2200 | |
| 2201 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 2202 ASSERT_EQ(1u, visitor_.ack_frames_.size()); | |
| 2203 QuicAckFrame* frame = visitor_.ack_frames_[0]; | |
| 2204 EXPECT_EQ(0xBA, frame->entropy_hash); | |
| 2205 EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed); | |
| 2206 EXPECT_EQ(0u, frame->revived_packets.size()); | |
| 2207 ASSERT_EQ(500u, frame->missing_packets.size()); | |
| 2208 SequenceNumberSet::const_iterator first_missing_iter = | |
| 2209 frame->missing_packets.begin(); | |
| 2210 EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter); | |
| 2211 SequenceNumberSet::const_reverse_iterator last_missing_iter = | |
| 2212 frame->missing_packets.rbegin(); | |
| 2213 EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter); | |
| 2214 | |
| 2215 // Verify that the packet re-serializes identically. | |
| 2216 QuicFrames frames; | |
| 2217 frames.push_back(QuicFrame(frame)); | |
| 2218 scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames)); | |
| 2219 ASSERT_TRUE(data != nullptr); | |
| 2220 | |
| 2221 test::CompareCharArraysWithHexError("constructed packet", | |
| 2222 data->data(), data->length(), | |
| 2223 AsChars(packet), arraysize(packet)); | |
| 2224 } | |
| 2225 | |
| 2226 TEST_P(QuicFramerTest, StopWaitingFrame) { | |
| 2227 unsigned char packet[] = { | |
| 2228 // public flags (8 byte connection_id) | |
| 2229 0x3C, | |
| 2230 // connection_id | |
| 2231 0x10, 0x32, 0x54, 0x76, | |
| 2232 0x98, 0xBA, 0xDC, 0xFE, | |
| 2233 // packet sequence number | |
| 2234 0xA8, 0x9A, 0x78, 0x56, | |
| 2235 0x34, 0x12, | |
| 2236 // private flags (entropy) | |
| 2237 0x01, | |
| 2238 | |
| 2239 // frame type (ack frame) | |
| 2240 // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) | |
| 2241 0x06, | |
| 2242 // entropy hash of sent packets till least awaiting - 1. | |
| 2243 0xAB, | |
| 2244 // least packet sequence number awaiting an ack, delta from sequence number. | |
| 2245 0x08, 0x00, 0x00, 0x00, | |
| 2246 0x00, 0x00, | |
| 2247 }; | |
| 2248 | |
| 2249 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2250 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2251 | |
| 2252 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2253 ASSERT_TRUE(visitor_.header_.get()); | |
| 2254 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2255 | |
| 2256 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 2257 ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size()); | |
| 2258 const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0]; | |
| 2259 EXPECT_EQ(0xAB, frame.entropy_hash); | |
| 2260 EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.least_unacked); | |
| 2261 | |
| 2262 const size_t kSentEntropyOffset = kQuicFrameTypeSize; | |
| 2263 const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize; | |
| 2264 const size_t frame_size = 7; | |
| 2265 for (size_t i = kQuicFrameTypeSize; i < frame_size; ++i) { | |
| 2266 string expected_error; | |
| 2267 if (i < kLeastUnackedOffset) { | |
| 2268 expected_error = "Unable to read entropy hash for sent packets."; | |
| 2269 } else { | |
| 2270 expected_error = "Unable to read least unacked delta."; | |
| 2271 } | |
| 2272 CheckProcessingFails( | |
| 2273 packet, | |
| 2274 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2275 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 2276 expected_error, QUIC_INVALID_STOP_WAITING_DATA); | |
| 2277 } | |
| 2278 } | |
| 2279 | |
| 2280 TEST_P(QuicFramerTest, RstStreamFrameQuic) { | |
| 2281 unsigned char packet[] = { | |
| 2282 // public flags (8 byte connection_id) | |
| 2283 0x3C, | |
| 2284 // connection_id | |
| 2285 0x10, 0x32, 0x54, 0x76, | |
| 2286 0x98, 0xBA, 0xDC, 0xFE, | |
| 2287 // packet sequence number | |
| 2288 0xBC, 0x9A, 0x78, 0x56, | |
| 2289 0x34, 0x12, | |
| 2290 // private flags | |
| 2291 0x00, | |
| 2292 | |
| 2293 // frame type (rst stream frame) | |
| 2294 0x01, | |
| 2295 // stream id | |
| 2296 0x04, 0x03, 0x02, 0x01, | |
| 2297 | |
| 2298 // sent byte offset | |
| 2299 0x01, 0x02, 0x03, 0x04, | |
| 2300 0x05, 0x06, 0x07, 0x08, | |
| 2301 | |
| 2302 // error code | |
| 2303 0x01, 0x00, 0x00, 0x00, | |
| 2304 | |
| 2305 // error details length | |
| 2306 0x0d, 0x00, | |
| 2307 // error details | |
| 2308 'b', 'e', 'c', 'a', | |
| 2309 'u', 's', 'e', ' ', | |
| 2310 'I', ' ', 'c', 'a', | |
| 2311 'n', | |
| 2312 }; | |
| 2313 | |
| 2314 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2315 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2316 | |
| 2317 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2318 ASSERT_TRUE(visitor_.header_.get()); | |
| 2319 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2320 | |
| 2321 EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.rst_stream_frame_.stream_id); | |
| 2322 EXPECT_EQ(0x01, visitor_.rst_stream_frame_.error_code); | |
| 2323 EXPECT_EQ("because I can", visitor_.rst_stream_frame_.error_details); | |
| 2324 EXPECT_EQ(GG_UINT64_C(0x0807060504030201), | |
| 2325 visitor_.rst_stream_frame_.byte_offset); | |
| 2326 | |
| 2327 // Now test framing boundaries. | |
| 2328 for (size_t i = kQuicFrameTypeSize; | |
| 2329 i < QuicFramer::GetMinRstStreamFrameSize(); ++i) { | |
| 2330 string expected_error; | |
| 2331 if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) { | |
| 2332 expected_error = "Unable to read stream_id."; | |
| 2333 } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize + | |
| 2334 + kQuicMaxStreamOffsetSize) { | |
| 2335 expected_error = "Unable to read rst stream sent byte offset."; | |
| 2336 } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize + | |
| 2337 + kQuicMaxStreamOffsetSize + kQuicErrorCodeSize) { | |
| 2338 expected_error = "Unable to read rst stream error code."; | |
| 2339 } else { | |
| 2340 expected_error = "Unable to read rst stream error details."; | |
| 2341 } | |
| 2342 CheckProcessingFails( | |
| 2343 packet, | |
| 2344 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2345 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 2346 expected_error, QUIC_INVALID_RST_STREAM_DATA); | |
| 2347 } | |
| 2348 } | |
| 2349 | |
| 2350 TEST_P(QuicFramerTest, ConnectionCloseFrame) { | |
| 2351 unsigned char packet[] = { | |
| 2352 // public flags (8 byte connection_id) | |
| 2353 0x3C, | |
| 2354 // connection_id | |
| 2355 0x10, 0x32, 0x54, 0x76, | |
| 2356 0x98, 0xBA, 0xDC, 0xFE, | |
| 2357 // packet sequence number | |
| 2358 0xBC, 0x9A, 0x78, 0x56, | |
| 2359 0x34, 0x12, | |
| 2360 // private flags | |
| 2361 0x00, | |
| 2362 | |
| 2363 // frame type (connection close frame) | |
| 2364 0x02, | |
| 2365 // error code | |
| 2366 0x11, 0x00, 0x00, 0x00, | |
| 2367 | |
| 2368 // error details length | |
| 2369 0x0d, 0x00, | |
| 2370 // error details | |
| 2371 'b', 'e', 'c', 'a', | |
| 2372 'u', 's', 'e', ' ', | |
| 2373 'I', ' ', 'c', 'a', | |
| 2374 'n', | |
| 2375 }; | |
| 2376 | |
| 2377 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2378 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2379 | |
| 2380 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2381 ASSERT_TRUE(visitor_.header_.get()); | |
| 2382 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2383 | |
| 2384 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 2385 | |
| 2386 EXPECT_EQ(0x11, visitor_.connection_close_frame_.error_code); | |
| 2387 EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details); | |
| 2388 | |
| 2389 ASSERT_EQ(0u, visitor_.ack_frames_.size()); | |
| 2390 | |
| 2391 // Now test framing boundaries. | |
| 2392 for (size_t i = kQuicFrameTypeSize; | |
| 2393 i < QuicFramer::GetMinConnectionCloseFrameSize(); ++i) { | |
| 2394 string expected_error; | |
| 2395 if (i < kQuicFrameTypeSize + kQuicErrorCodeSize) { | |
| 2396 expected_error = "Unable to read connection close error code."; | |
| 2397 } else { | |
| 2398 expected_error = "Unable to read connection close error details."; | |
| 2399 } | |
| 2400 CheckProcessingFails( | |
| 2401 packet, | |
| 2402 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2403 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 2404 expected_error, QUIC_INVALID_CONNECTION_CLOSE_DATA); | |
| 2405 } | |
| 2406 } | |
| 2407 | |
| 2408 TEST_P(QuicFramerTest, GoAwayFrame) { | |
| 2409 unsigned char packet[] = { | |
| 2410 // public flags (8 byte connection_id) | |
| 2411 0x3C, | |
| 2412 // connection_id | |
| 2413 0x10, 0x32, 0x54, 0x76, | |
| 2414 0x98, 0xBA, 0xDC, 0xFE, | |
| 2415 // packet sequence number | |
| 2416 0xBC, 0x9A, 0x78, 0x56, | |
| 2417 0x34, 0x12, | |
| 2418 // private flags | |
| 2419 0x00, | |
| 2420 | |
| 2421 // frame type (go away frame) | |
| 2422 0x03, | |
| 2423 // error code | |
| 2424 0x09, 0x00, 0x00, 0x00, | |
| 2425 // stream id | |
| 2426 0x04, 0x03, 0x02, 0x01, | |
| 2427 // error details length | |
| 2428 0x0d, 0x00, | |
| 2429 // error details | |
| 2430 'b', 'e', 'c', 'a', | |
| 2431 'u', 's', 'e', ' ', | |
| 2432 'I', ' ', 'c', 'a', | |
| 2433 'n', | |
| 2434 }; | |
| 2435 | |
| 2436 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2437 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2438 | |
| 2439 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2440 ASSERT_TRUE(visitor_.header_.get()); | |
| 2441 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2442 | |
| 2443 EXPECT_EQ(GG_UINT64_C(0x01020304), | |
| 2444 visitor_.goaway_frame_.last_good_stream_id); | |
| 2445 EXPECT_EQ(0x9, visitor_.goaway_frame_.error_code); | |
| 2446 EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase); | |
| 2447 | |
| 2448 const size_t reason_size = arraysize("because I can") - 1; | |
| 2449 // Now test framing boundaries. | |
| 2450 for (size_t i = kQuicFrameTypeSize; | |
| 2451 i < QuicFramer::GetMinGoAwayFrameSize() + reason_size; ++i) { | |
| 2452 string expected_error; | |
| 2453 if (i < kQuicFrameTypeSize + kQuicErrorCodeSize) { | |
| 2454 expected_error = "Unable to read go away error code."; | |
| 2455 } else if (i < kQuicFrameTypeSize + kQuicErrorCodeSize + | |
| 2456 kQuicMaxStreamIdSize) { | |
| 2457 expected_error = "Unable to read last good stream id."; | |
| 2458 } else { | |
| 2459 expected_error = "Unable to read goaway reason."; | |
| 2460 } | |
| 2461 CheckProcessingFails( | |
| 2462 packet, | |
| 2463 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2464 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 2465 expected_error, QUIC_INVALID_GOAWAY_DATA); | |
| 2466 } | |
| 2467 } | |
| 2468 | |
| 2469 TEST_P(QuicFramerTest, WindowUpdateFrame) { | |
| 2470 unsigned char packet[] = { | |
| 2471 // public flags (8 byte connection_id) | |
| 2472 0x3C, | |
| 2473 // connection_id | |
| 2474 0x10, 0x32, 0x54, 0x76, | |
| 2475 0x98, 0xBA, 0xDC, 0xFE, | |
| 2476 // packet sequence number | |
| 2477 0xBC, 0x9A, 0x78, 0x56, | |
| 2478 0x34, 0x12, | |
| 2479 // private flags | |
| 2480 0x00, | |
| 2481 | |
| 2482 // frame type (window update frame) | |
| 2483 0x04, | |
| 2484 // stream id | |
| 2485 0x04, 0x03, 0x02, 0x01, | |
| 2486 // byte offset | |
| 2487 0x05, 0x06, 0x07, 0x08, | |
| 2488 0x09, 0x0a, 0x0b, 0x0c, | |
| 2489 }; | |
| 2490 | |
| 2491 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2492 | |
| 2493 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2494 | |
| 2495 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2496 ASSERT_TRUE(visitor_.header_.get()); | |
| 2497 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2498 | |
| 2499 EXPECT_EQ(GG_UINT64_C(0x01020304), | |
| 2500 visitor_.window_update_frame_.stream_id); | |
| 2501 EXPECT_EQ(GG_UINT64_C(0x0c0b0a0908070605), | |
| 2502 visitor_.window_update_frame_.byte_offset); | |
| 2503 | |
| 2504 // Now test framing boundaries. | |
| 2505 for (size_t i = kQuicFrameTypeSize; | |
| 2506 i < QuicFramer::GetWindowUpdateFrameSize(); ++i) { | |
| 2507 string expected_error; | |
| 2508 if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) { | |
| 2509 expected_error = "Unable to read stream_id."; | |
| 2510 } else { | |
| 2511 expected_error = "Unable to read window byte_offset."; | |
| 2512 } | |
| 2513 CheckProcessingFails( | |
| 2514 packet, | |
| 2515 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2516 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 2517 expected_error, QUIC_INVALID_WINDOW_UPDATE_DATA); | |
| 2518 } | |
| 2519 } | |
| 2520 | |
| 2521 TEST_P(QuicFramerTest, BlockedFrame) { | |
| 2522 unsigned char packet[] = { | |
| 2523 // public flags (8 byte connection_id) | |
| 2524 0x3C, | |
| 2525 // connection_id | |
| 2526 0x10, 0x32, 0x54, 0x76, | |
| 2527 0x98, 0xBA, 0xDC, 0xFE, | |
| 2528 // packet sequence number | |
| 2529 0xBC, 0x9A, 0x78, 0x56, | |
| 2530 0x34, 0x12, | |
| 2531 // private flags | |
| 2532 0x00, | |
| 2533 | |
| 2534 // frame type (blocked frame) | |
| 2535 0x05, | |
| 2536 // stream id | |
| 2537 0x04, 0x03, 0x02, 0x01, | |
| 2538 }; | |
| 2539 | |
| 2540 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2541 | |
| 2542 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2543 | |
| 2544 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2545 ASSERT_TRUE(visitor_.header_.get()); | |
| 2546 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2547 | |
| 2548 EXPECT_EQ(GG_UINT64_C(0x01020304), | |
| 2549 visitor_.blocked_frame_.stream_id); | |
| 2550 | |
| 2551 // Now test framing boundaries. | |
| 2552 for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetBlockedFrameSize(); | |
| 2553 ++i) { | |
| 2554 string expected_error = "Unable to read stream_id."; | |
| 2555 CheckProcessingFails( | |
| 2556 packet, | |
| 2557 i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2558 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), | |
| 2559 expected_error, QUIC_INVALID_BLOCKED_DATA); | |
| 2560 } | |
| 2561 } | |
| 2562 | |
| 2563 TEST_P(QuicFramerTest, PingFrame) { | |
| 2564 unsigned char packet[] = { | |
| 2565 // public flags (8 byte connection_id) | |
| 2566 0x3C, | |
| 2567 // connection_id | |
| 2568 0x10, 0x32, 0x54, 0x76, | |
| 2569 0x98, 0xBA, 0xDC, 0xFE, | |
| 2570 // packet sequence number | |
| 2571 0xBC, 0x9A, 0x78, 0x56, | |
| 2572 0x34, 0x12, | |
| 2573 // private flags | |
| 2574 0x00, | |
| 2575 | |
| 2576 // frame type (ping frame) | |
| 2577 0x07, | |
| 2578 }; | |
| 2579 | |
| 2580 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2581 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2582 | |
| 2583 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2584 ASSERT_TRUE(visitor_.header_.get()); | |
| 2585 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2586 | |
| 2587 EXPECT_EQ(1u, visitor_.ping_frames_.size()); | |
| 2588 | |
| 2589 // No need to check the PING frame boundaries because it has no payload. | |
| 2590 } | |
| 2591 | |
| 2592 TEST_P(QuicFramerTest, PublicResetPacket) { | |
| 2593 unsigned char packet[] = { | |
| 2594 // public flags (public reset, 8 byte connection_id) | |
| 2595 0x0E, | |
| 2596 // connection_id | |
| 2597 0x10, 0x32, 0x54, 0x76, | |
| 2598 0x98, 0xBA, 0xDC, 0xFE, | |
| 2599 // message tag (kPRST) | |
| 2600 'P', 'R', 'S', 'T', | |
| 2601 // num_entries (2) + padding | |
| 2602 0x02, 0x00, 0x00, 0x00, | |
| 2603 // tag kRNON | |
| 2604 'R', 'N', 'O', 'N', | |
| 2605 // end offset 8 | |
| 2606 0x08, 0x00, 0x00, 0x00, | |
| 2607 // tag kRSEQ | |
| 2608 'R', 'S', 'E', 'Q', | |
| 2609 // end offset 16 | |
| 2610 0x10, 0x00, 0x00, 0x00, | |
| 2611 // nonce proof | |
| 2612 0x89, 0x67, 0x45, 0x23, | |
| 2613 0x01, 0xEF, 0xCD, 0xAB, | |
| 2614 // rejected sequence number | |
| 2615 0xBC, 0x9A, 0x78, 0x56, | |
| 2616 0x34, 0x12, 0x00, 0x00, | |
| 2617 }; | |
| 2618 | |
| 2619 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2620 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2621 ASSERT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2622 ASSERT_TRUE(visitor_.public_reset_packet_.get()); | |
| 2623 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 2624 visitor_.public_reset_packet_->public_header.connection_id); | |
| 2625 EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag); | |
| 2626 EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag); | |
| 2627 EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789), | |
| 2628 visitor_.public_reset_packet_->nonce_proof); | |
| 2629 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 2630 visitor_.public_reset_packet_->rejected_sequence_number); | |
| 2631 EXPECT_TRUE( | |
| 2632 visitor_.public_reset_packet_->client_address.address().empty()); | |
| 2633 | |
| 2634 // Now test framing boundaries. | |
| 2635 for (size_t i = 0; i < arraysize(packet); ++i) { | |
| 2636 string expected_error; | |
| 2637 DVLOG(1) << "iteration: " << i; | |
| 2638 if (i < kConnectionIdOffset) { | |
| 2639 expected_error = "Unable to read public flags."; | |
| 2640 CheckProcessingFails(packet, i, expected_error, | |
| 2641 QUIC_INVALID_PACKET_HEADER); | |
| 2642 } else if (i < kPublicResetPacketMessageTagOffset) { | |
| 2643 expected_error = "Unable to read ConnectionId."; | |
| 2644 CheckProcessingFails(packet, i, expected_error, | |
| 2645 QUIC_INVALID_PACKET_HEADER); | |
| 2646 } else { | |
| 2647 expected_error = "Unable to read reset message."; | |
| 2648 CheckProcessingFails(packet, i, expected_error, | |
| 2649 QUIC_INVALID_PUBLIC_RST_PACKET); | |
| 2650 } | |
| 2651 } | |
| 2652 } | |
| 2653 | |
| 2654 TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) { | |
| 2655 unsigned char packet[] = { | |
| 2656 // public flags (public reset, 8 byte connection_id) | |
| 2657 0x0E, | |
| 2658 // connection_id | |
| 2659 0x10, 0x32, 0x54, 0x76, | |
| 2660 0x98, 0xBA, 0xDC, 0xFE, | |
| 2661 // message tag (kPRST) | |
| 2662 'P', 'R', 'S', 'T', | |
| 2663 // num_entries (2) + padding | |
| 2664 0x02, 0x00, 0x00, 0x00, | |
| 2665 // tag kRNON | |
| 2666 'R', 'N', 'O', 'N', | |
| 2667 // end offset 8 | |
| 2668 0x08, 0x00, 0x00, 0x00, | |
| 2669 // tag kRSEQ | |
| 2670 'R', 'S', 'E', 'Q', | |
| 2671 // end offset 16 | |
| 2672 0x10, 0x00, 0x00, 0x00, | |
| 2673 // nonce proof | |
| 2674 0x89, 0x67, 0x45, 0x23, | |
| 2675 0x01, 0xEF, 0xCD, 0xAB, | |
| 2676 // rejected sequence number | |
| 2677 0xBC, 0x9A, 0x78, 0x56, | |
| 2678 0x34, 0x12, 0x00, 0x00, | |
| 2679 // trailing junk | |
| 2680 'j', 'u', 'n', 'k', | |
| 2681 }; | |
| 2682 | |
| 2683 string expected_error = "Unable to read reset message."; | |
| 2684 CheckProcessingFails(packet, arraysize(packet), expected_error, | |
| 2685 QUIC_INVALID_PUBLIC_RST_PACKET); | |
| 2686 } | |
| 2687 | |
| 2688 TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) { | |
| 2689 unsigned char packet[] = { | |
| 2690 // public flags (public reset, 8 byte connection_id) | |
| 2691 0x0E, | |
| 2692 // connection_id | |
| 2693 0x10, 0x32, 0x54, 0x76, | |
| 2694 0x98, 0xBA, 0xDC, 0xFE, | |
| 2695 // message tag (kPRST) | |
| 2696 'P', 'R', 'S', 'T', | |
| 2697 // num_entries (3) + padding | |
| 2698 0x03, 0x00, 0x00, 0x00, | |
| 2699 // tag kRNON | |
| 2700 'R', 'N', 'O', 'N', | |
| 2701 // end offset 8 | |
| 2702 0x08, 0x00, 0x00, 0x00, | |
| 2703 // tag kRSEQ | |
| 2704 'R', 'S', 'E', 'Q', | |
| 2705 // end offset 16 | |
| 2706 0x10, 0x00, 0x00, 0x00, | |
| 2707 // tag kCADR | |
| 2708 'C', 'A', 'D', 'R', | |
| 2709 // end offset 24 | |
| 2710 0x18, 0x00, 0x00, 0x00, | |
| 2711 // nonce proof | |
| 2712 0x89, 0x67, 0x45, 0x23, | |
| 2713 0x01, 0xEF, 0xCD, 0xAB, | |
| 2714 // rejected sequence number | |
| 2715 0xBC, 0x9A, 0x78, 0x56, | |
| 2716 0x34, 0x12, 0x00, 0x00, | |
| 2717 // client address: 4.31.198.44:443 | |
| 2718 0x02, 0x00, | |
| 2719 0x04, 0x1F, 0xC6, 0x2C, | |
| 2720 0xBB, 0x01, | |
| 2721 }; | |
| 2722 | |
| 2723 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2724 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2725 ASSERT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2726 ASSERT_TRUE(visitor_.public_reset_packet_.get()); | |
| 2727 EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), | |
| 2728 visitor_.public_reset_packet_->public_header.connection_id); | |
| 2729 EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag); | |
| 2730 EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag); | |
| 2731 EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789), | |
| 2732 visitor_.public_reset_packet_->nonce_proof); | |
| 2733 EXPECT_EQ(GG_UINT64_C(0x123456789ABC), | |
| 2734 visitor_.public_reset_packet_->rejected_sequence_number); | |
| 2735 EXPECT_EQ("4.31.198.44", | |
| 2736 IPAddressToString(visitor_.public_reset_packet_-> | |
| 2737 client_address.address())); | |
| 2738 EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port()); | |
| 2739 | |
| 2740 // Now test framing boundaries. | |
| 2741 for (size_t i = 0; i < arraysize(packet); ++i) { | |
| 2742 string expected_error; | |
| 2743 DVLOG(1) << "iteration: " << i; | |
| 2744 if (i < kConnectionIdOffset) { | |
| 2745 expected_error = "Unable to read public flags."; | |
| 2746 CheckProcessingFails(packet, i, expected_error, | |
| 2747 QUIC_INVALID_PACKET_HEADER); | |
| 2748 } else if (i < kPublicResetPacketMessageTagOffset) { | |
| 2749 expected_error = "Unable to read ConnectionId."; | |
| 2750 CheckProcessingFails(packet, i, expected_error, | |
| 2751 QUIC_INVALID_PACKET_HEADER); | |
| 2752 } else { | |
| 2753 expected_error = "Unable to read reset message."; | |
| 2754 CheckProcessingFails(packet, i, expected_error, | |
| 2755 QUIC_INVALID_PUBLIC_RST_PACKET); | |
| 2756 } | |
| 2757 } | |
| 2758 } | |
| 2759 | |
| 2760 TEST_P(QuicFramerTest, VersionNegotiationPacket) { | |
| 2761 unsigned char packet[] = { | |
| 2762 // public flags (version, 8 byte connection_id) | |
| 2763 0x3D, | |
| 2764 // connection_id | |
| 2765 0x10, 0x32, 0x54, 0x76, | |
| 2766 0x98, 0xBA, 0xDC, 0xFE, | |
| 2767 // version tag | |
| 2768 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), | |
| 2769 'Q', '2', '.', '0', | |
| 2770 }; | |
| 2771 | |
| 2772 QuicFramerPeer::SetIsServer(&framer_, false); | |
| 2773 | |
| 2774 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2775 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2776 ASSERT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2777 ASSERT_TRUE(visitor_.version_negotiation_packet_.get()); | |
| 2778 EXPECT_EQ(2u, visitor_.version_negotiation_packet_->versions.size()); | |
| 2779 EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]); | |
| 2780 | |
| 2781 for (size_t i = 0; i <= kPublicFlagsSize + PACKET_8BYTE_CONNECTION_ID; ++i) { | |
| 2782 string expected_error; | |
| 2783 QuicErrorCode error_code = QUIC_INVALID_PACKET_HEADER; | |
| 2784 if (i < kConnectionIdOffset) { | |
| 2785 expected_error = "Unable to read public flags."; | |
| 2786 } else if (i < kVersionOffset) { | |
| 2787 expected_error = "Unable to read ConnectionId."; | |
| 2788 } else { | |
| 2789 expected_error = "Unable to read supported version in negotiation."; | |
| 2790 error_code = QUIC_INVALID_VERSION_NEGOTIATION_PACKET; | |
| 2791 } | |
| 2792 CheckProcessingFails(packet, i, expected_error, error_code); | |
| 2793 } | |
| 2794 } | |
| 2795 | |
| 2796 TEST_P(QuicFramerTest, FecPacket) { | |
| 2797 unsigned char packet[] = { | |
| 2798 // public flags (8 byte connection_id) | |
| 2799 0x3C, | |
| 2800 // connection_id | |
| 2801 0x10, 0x32, 0x54, 0x76, | |
| 2802 0x98, 0xBA, 0xDC, 0xFE, | |
| 2803 // packet sequence number | |
| 2804 0xBC, 0x9A, 0x78, 0x56, | |
| 2805 0x34, 0x12, | |
| 2806 // private flags (fec group & FEC) | |
| 2807 0x06, | |
| 2808 // first fec protected packet offset | |
| 2809 0x01, | |
| 2810 | |
| 2811 // redundancy | |
| 2812 'a', 'b', 'c', 'd', | |
| 2813 'e', 'f', 'g', 'h', | |
| 2814 'i', 'j', 'k', 'l', | |
| 2815 'm', 'n', 'o', 'p', | |
| 2816 }; | |
| 2817 | |
| 2818 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 2819 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 2820 | |
| 2821 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 2822 ASSERT_TRUE(visitor_.header_.get()); | |
| 2823 EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); | |
| 2824 | |
| 2825 EXPECT_EQ(0u, visitor_.stream_frames_.size()); | |
| 2826 EXPECT_EQ(0u, visitor_.ack_frames_.size()); | |
| 2827 ASSERT_EQ(1, visitor_.fec_count_); | |
| 2828 const QuicFecData& fec_data = *visitor_.fec_data_[0]; | |
| 2829 EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), fec_data.fec_group); | |
| 2830 EXPECT_EQ("abcdefghijklmnop", fec_data.redundancy); | |
| 2831 } | |
| 2832 | |
| 2833 TEST_P(QuicFramerTest, BuildPaddingFramePacket) { | |
| 2834 QuicPacketHeader header; | |
| 2835 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 2836 header.public_header.reset_flag = false; | |
| 2837 header.public_header.version_flag = false; | |
| 2838 header.fec_flag = false; | |
| 2839 header.entropy_flag = false; | |
| 2840 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 2841 header.fec_group = 0; | |
| 2842 | |
| 2843 QuicPaddingFrame padding_frame; | |
| 2844 | |
| 2845 QuicFrames frames; | |
| 2846 frames.push_back(QuicFrame(&padding_frame)); | |
| 2847 | |
| 2848 unsigned char packet[kMaxPacketSize] = { | |
| 2849 // public flags (8 byte connection_id) | |
| 2850 0x3C, | |
| 2851 // connection_id | |
| 2852 0x10, 0x32, 0x54, 0x76, | |
| 2853 0x98, 0xBA, 0xDC, 0xFE, | |
| 2854 // packet sequence number | |
| 2855 0xBC, 0x9A, 0x78, 0x56, | |
| 2856 0x34, 0x12, | |
| 2857 // private flags | |
| 2858 0x00, | |
| 2859 | |
| 2860 // frame type (padding frame) | |
| 2861 0x00, | |
| 2862 0x00, 0x00, 0x00, 0x00 | |
| 2863 }; | |
| 2864 | |
| 2865 uint64 header_size = | |
| 2866 GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2867 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 2868 memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); | |
| 2869 | |
| 2870 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 2871 ASSERT_TRUE(data != nullptr); | |
| 2872 | |
| 2873 test::CompareCharArraysWithHexError("constructed packet", | |
| 2874 data->data(), data->length(), | |
| 2875 AsChars(packet), | |
| 2876 arraysize(packet)); | |
| 2877 } | |
| 2878 | |
| 2879 TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) { | |
| 2880 QuicPacketHeader header; | |
| 2881 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 2882 header.public_header.reset_flag = false; | |
| 2883 header.public_header.version_flag = false; | |
| 2884 header.fec_flag = false; | |
| 2885 header.entropy_flag = false; | |
| 2886 header.public_header.sequence_number_length = PACKET_4BYTE_SEQUENCE_NUMBER; | |
| 2887 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 2888 header.fec_group = 0; | |
| 2889 | |
| 2890 QuicPaddingFrame padding_frame; | |
| 2891 | |
| 2892 QuicFrames frames; | |
| 2893 frames.push_back(QuicFrame(&padding_frame)); | |
| 2894 | |
| 2895 unsigned char packet[kMaxPacketSize] = { | |
| 2896 // public flags (8 byte connection_id and 4 byte sequence number) | |
| 2897 0x2C, | |
| 2898 // connection_id | |
| 2899 0x10, 0x32, 0x54, 0x76, | |
| 2900 0x98, 0xBA, 0xDC, 0xFE, | |
| 2901 // packet sequence number | |
| 2902 0xBC, 0x9A, 0x78, 0x56, | |
| 2903 // private flags | |
| 2904 0x00, | |
| 2905 | |
| 2906 // frame type (padding frame) | |
| 2907 0x00, | |
| 2908 0x00, 0x00, 0x00, 0x00 | |
| 2909 }; | |
| 2910 | |
| 2911 uint64 header_size = | |
| 2912 GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2913 PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 2914 memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); | |
| 2915 | |
| 2916 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 2917 ASSERT_TRUE(data != nullptr); | |
| 2918 | |
| 2919 test::CompareCharArraysWithHexError("constructed packet", | |
| 2920 data->data(), data->length(), | |
| 2921 AsChars(packet), | |
| 2922 arraysize(packet)); | |
| 2923 } | |
| 2924 | |
| 2925 TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) { | |
| 2926 QuicPacketHeader header; | |
| 2927 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 2928 header.public_header.reset_flag = false; | |
| 2929 header.public_header.version_flag = false; | |
| 2930 header.fec_flag = false; | |
| 2931 header.entropy_flag = false; | |
| 2932 header.public_header.sequence_number_length = PACKET_2BYTE_SEQUENCE_NUMBER; | |
| 2933 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 2934 header.fec_group = 0; | |
| 2935 | |
| 2936 QuicPaddingFrame padding_frame; | |
| 2937 | |
| 2938 QuicFrames frames; | |
| 2939 frames.push_back(QuicFrame(&padding_frame)); | |
| 2940 | |
| 2941 unsigned char packet[kMaxPacketSize] = { | |
| 2942 // public flags (8 byte connection_id and 2 byte sequence number) | |
| 2943 0x1C, | |
| 2944 // connection_id | |
| 2945 0x10, 0x32, 0x54, 0x76, | |
| 2946 0x98, 0xBA, 0xDC, 0xFE, | |
| 2947 // packet sequence number | |
| 2948 0xBC, 0x9A, | |
| 2949 // private flags | |
| 2950 0x00, | |
| 2951 | |
| 2952 // frame type (padding frame) | |
| 2953 0x00, | |
| 2954 0x00, 0x00, 0x00, 0x00 | |
| 2955 }; | |
| 2956 | |
| 2957 uint64 header_size = | |
| 2958 GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 2959 PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 2960 memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); | |
| 2961 | |
| 2962 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 2963 ASSERT_TRUE(data != nullptr); | |
| 2964 | |
| 2965 test::CompareCharArraysWithHexError("constructed packet", | |
| 2966 data->data(), data->length(), | |
| 2967 AsChars(packet), | |
| 2968 arraysize(packet)); | |
| 2969 } | |
| 2970 | |
| 2971 TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) { | |
| 2972 QuicPacketHeader header; | |
| 2973 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 2974 header.public_header.reset_flag = false; | |
| 2975 header.public_header.version_flag = false; | |
| 2976 header.fec_flag = false; | |
| 2977 header.entropy_flag = false; | |
| 2978 header.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER; | |
| 2979 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 2980 header.fec_group = 0; | |
| 2981 | |
| 2982 QuicPaddingFrame padding_frame; | |
| 2983 | |
| 2984 QuicFrames frames; | |
| 2985 frames.push_back(QuicFrame(&padding_frame)); | |
| 2986 | |
| 2987 unsigned char packet[kMaxPacketSize] = { | |
| 2988 // public flags (8 byte connection_id and 1 byte sequence number) | |
| 2989 0x0C, | |
| 2990 // connection_id | |
| 2991 0x10, 0x32, 0x54, 0x76, | |
| 2992 0x98, 0xBA, 0xDC, 0xFE, | |
| 2993 // packet sequence number | |
| 2994 0xBC, | |
| 2995 // private flags | |
| 2996 0x00, | |
| 2997 | |
| 2998 // frame type (padding frame) | |
| 2999 0x00, | |
| 3000 0x00, 0x00, 0x00, 0x00 | |
| 3001 }; | |
| 3002 | |
| 3003 uint64 header_size = | |
| 3004 GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | |
| 3005 PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 3006 memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); | |
| 3007 | |
| 3008 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3009 ASSERT_TRUE(data != nullptr); | |
| 3010 | |
| 3011 test::CompareCharArraysWithHexError("constructed packet", | |
| 3012 data->data(), data->length(), | |
| 3013 AsChars(packet), | |
| 3014 arraysize(packet)); | |
| 3015 } | |
| 3016 | |
| 3017 TEST_P(QuicFramerTest, BuildStreamFramePacket) { | |
| 3018 QuicPacketHeader header; | |
| 3019 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3020 header.public_header.reset_flag = false; | |
| 3021 header.public_header.version_flag = false; | |
| 3022 header.fec_flag = false; | |
| 3023 header.entropy_flag = true; | |
| 3024 header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC); | |
| 3025 header.fec_group = 0; | |
| 3026 | |
| 3027 QuicStreamFrame stream_frame; | |
| 3028 stream_frame.stream_id = 0x01020304; | |
| 3029 stream_frame.fin = true; | |
| 3030 stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654); | |
| 3031 stream_frame.data = MakeIOVector("hello world!"); | |
| 3032 | |
| 3033 QuicFrames frames; | |
| 3034 frames.push_back(QuicFrame(&stream_frame)); | |
| 3035 | |
| 3036 unsigned char packet[] = { | |
| 3037 // public flags (8 byte connection_id) | |
| 3038 0x3C, | |
| 3039 // connection_id | |
| 3040 0x10, 0x32, 0x54, 0x76, | |
| 3041 0x98, 0xBA, 0xDC, 0xFE, | |
| 3042 // packet sequence number | |
| 3043 0xBC, 0x9A, 0x78, 0x56, | |
| 3044 0x34, 0x12, | |
| 3045 // private flags (entropy) | |
| 3046 0x01, | |
| 3047 | |
| 3048 // frame type (stream frame with fin and no length) | |
| 3049 0xDF, | |
| 3050 // stream id | |
| 3051 0x04, 0x03, 0x02, 0x01, | |
| 3052 // offset | |
| 3053 0x54, 0x76, 0x10, 0x32, | |
| 3054 0xDC, 0xFE, 0x98, 0xBA, | |
| 3055 // data | |
| 3056 'h', 'e', 'l', 'l', | |
| 3057 'o', ' ', 'w', 'o', | |
| 3058 'r', 'l', 'd', '!', | |
| 3059 }; | |
| 3060 | |
| 3061 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3062 ASSERT_TRUE(data != nullptr); | |
| 3063 | |
| 3064 test::CompareCharArraysWithHexError("constructed packet", | |
| 3065 data->data(), data->length(), | |
| 3066 AsChars(packet), arraysize(packet)); | |
| 3067 } | |
| 3068 | |
| 3069 TEST_P(QuicFramerTest, BuildStreamFramePacketInFecGroup) { | |
| 3070 QuicPacketHeader header; | |
| 3071 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3072 header.public_header.reset_flag = false; | |
| 3073 header.public_header.version_flag = false; | |
| 3074 header.fec_flag = false; | |
| 3075 header.entropy_flag = true; | |
| 3076 header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC); | |
| 3077 header.is_in_fec_group = IN_FEC_GROUP; | |
| 3078 header.fec_group = GG_UINT64_C(0x77123456789ABC); | |
| 3079 | |
| 3080 QuicStreamFrame stream_frame; | |
| 3081 stream_frame.stream_id = 0x01020304; | |
| 3082 stream_frame.fin = true; | |
| 3083 stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654); | |
| 3084 stream_frame.data = MakeIOVector("hello world!"); | |
| 3085 | |
| 3086 QuicFrames frames; | |
| 3087 frames.push_back(QuicFrame(&stream_frame)); | |
| 3088 unsigned char packet[] = { | |
| 3089 // public flags (8 byte connection_id) | |
| 3090 0x3C, | |
| 3091 // connection_id | |
| 3092 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 3093 // packet sequence number | |
| 3094 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 3095 // private flags (entropy, is_in_fec_group) | |
| 3096 0x03, | |
| 3097 // FEC group | |
| 3098 0x00, | |
| 3099 // frame type (stream frame with fin and data length field) | |
| 3100 0xFF, | |
| 3101 // stream id | |
| 3102 0x04, 0x03, 0x02, 0x01, | |
| 3103 // offset | |
| 3104 0x54, 0x76, 0x10, 0x32, 0xDC, 0xFE, 0x98, 0xBA, | |
| 3105 // data length (since packet is in an FEC group) | |
| 3106 0x0C, 0x00, | |
| 3107 // data | |
| 3108 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', | |
| 3109 }; | |
| 3110 | |
| 3111 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3112 ASSERT_TRUE(data != nullptr); | |
| 3113 | |
| 3114 test::CompareCharArraysWithHexError("constructed packet", | |
| 3115 data->data(), data->length(), | |
| 3116 AsChars(packet), arraysize(packet)); | |
| 3117 } | |
| 3118 | |
| 3119 TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) { | |
| 3120 QuicPacketHeader header; | |
| 3121 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3122 header.public_header.reset_flag = false; | |
| 3123 header.public_header.version_flag = true; | |
| 3124 header.fec_flag = false; | |
| 3125 header.entropy_flag = true; | |
| 3126 header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC); | |
| 3127 header.fec_group = 0; | |
| 3128 | |
| 3129 QuicStreamFrame stream_frame; | |
| 3130 stream_frame.stream_id = 0x01020304; | |
| 3131 stream_frame.fin = true; | |
| 3132 stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654); | |
| 3133 stream_frame.data = MakeIOVector("hello world!"); | |
| 3134 | |
| 3135 QuicFrames frames; | |
| 3136 frames.push_back(QuicFrame(&stream_frame)); | |
| 3137 | |
| 3138 unsigned char packet[] = { | |
| 3139 // public flags (version, 8 byte connection_id) | |
| 3140 0x3D, | |
| 3141 // connection_id | |
| 3142 0x10, | |
| 3143 0x32, | |
| 3144 0x54, | |
| 3145 0x76, | |
| 3146 0x98, | |
| 3147 0xBA, | |
| 3148 0xDC, | |
| 3149 0xFE, | |
| 3150 // version tag | |
| 3151 'Q', | |
| 3152 '0', | |
| 3153 GetQuicVersionDigitTens(), | |
| 3154 GetQuicVersionDigitOnes(), | |
| 3155 // packet sequence number | |
| 3156 0xBC, | |
| 3157 0x9A, | |
| 3158 0x78, | |
| 3159 0x56, | |
| 3160 0x34, | |
| 3161 0x12, | |
| 3162 // private flags (entropy) | |
| 3163 0x01, | |
| 3164 | |
| 3165 // frame type (stream frame with fin and no length) | |
| 3166 0xDF, | |
| 3167 // stream id | |
| 3168 0x04, | |
| 3169 0x03, | |
| 3170 0x02, | |
| 3171 0x01, | |
| 3172 // offset | |
| 3173 0x54, | |
| 3174 0x76, | |
| 3175 0x10, | |
| 3176 0x32, | |
| 3177 0xDC, | |
| 3178 0xFE, | |
| 3179 0x98, | |
| 3180 0xBA, | |
| 3181 // data | |
| 3182 'h', | |
| 3183 'e', | |
| 3184 'l', | |
| 3185 'l', | |
| 3186 'o', | |
| 3187 ' ', | |
| 3188 'w', | |
| 3189 'o', | |
| 3190 'r', | |
| 3191 'l', | |
| 3192 'd', | |
| 3193 '!', | |
| 3194 }; | |
| 3195 | |
| 3196 QuicFramerPeer::SetIsServer(&framer_, false); | |
| 3197 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3198 ASSERT_TRUE(data != nullptr); | |
| 3199 | |
| 3200 test::CompareCharArraysWithHexError("constructed packet", | |
| 3201 data->data(), data->length(), | |
| 3202 AsChars(packet), arraysize(packet)); | |
| 3203 } | |
| 3204 | |
| 3205 TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) { | |
| 3206 QuicPacketPublicHeader header; | |
| 3207 header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3208 header.reset_flag = false; | |
| 3209 header.version_flag = true; | |
| 3210 | |
| 3211 unsigned char packet[] = { | |
| 3212 // public flags (version, 8 byte connection_id) | |
| 3213 0x0D, | |
| 3214 // connection_id | |
| 3215 0x10, | |
| 3216 0x32, | |
| 3217 0x54, | |
| 3218 0x76, | |
| 3219 0x98, | |
| 3220 0xBA, | |
| 3221 0xDC, | |
| 3222 0xFE, | |
| 3223 // version tag | |
| 3224 'Q', | |
| 3225 '0', | |
| 3226 GetQuicVersionDigitTens(), | |
| 3227 GetQuicVersionDigitOnes(), | |
| 3228 }; | |
| 3229 | |
| 3230 QuicVersionVector versions; | |
| 3231 versions.push_back(GetParam()); | |
| 3232 scoped_ptr<QuicEncryptedPacket> data( | |
| 3233 framer_.BuildVersionNegotiationPacket(header, versions)); | |
| 3234 | |
| 3235 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
| 3236 data->length(), AsChars(packet), | |
| 3237 arraysize(packet)); | |
| 3238 } | |
| 3239 | |
| 3240 TEST_P(QuicFramerTest, BuildAckFramePacket) { | |
| 3241 QuicPacketHeader header; | |
| 3242 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3243 header.public_header.reset_flag = false; | |
| 3244 header.public_header.version_flag = false; | |
| 3245 header.fec_flag = false; | |
| 3246 header.entropy_flag = true; | |
| 3247 header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8); | |
| 3248 header.fec_group = 0; | |
| 3249 | |
| 3250 QuicAckFrame ack_frame; | |
| 3251 ack_frame.entropy_hash = 0x43; | |
| 3252 ack_frame.largest_observed = GG_UINT64_C(0x770123456789ABF); | |
| 3253 ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero(); | |
| 3254 ack_frame.missing_packets.insert(GG_UINT64_C(0x770123456789ABE)); | |
| 3255 | |
| 3256 QuicFrames frames; | |
| 3257 frames.push_back(QuicFrame(&ack_frame)); | |
| 3258 | |
| 3259 unsigned char packet[] = { | |
| 3260 // public flags (8 byte connection_id) | |
| 3261 0x3C, | |
| 3262 // connection_id | |
| 3263 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 3264 // packet sequence number | |
| 3265 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 3266 // private flags (entropy) | |
| 3267 0x01, | |
| 3268 | |
| 3269 // frame type (ack frame) | |
| 3270 // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) | |
| 3271 0x6C, | |
| 3272 // entropy hash of all received packets. | |
| 3273 0x43, | |
| 3274 // largest observed packet sequence number | |
| 3275 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 3276 // Zero delta time. | |
| 3277 0x00, 0x00, | |
| 3278 // num received packets. | |
| 3279 0x00, | |
| 3280 // num missing packet ranges | |
| 3281 0x01, | |
| 3282 // missing packet delta | |
| 3283 0x01, | |
| 3284 // 0 more missing packets in range. | |
| 3285 0x00, | |
| 3286 // 0 revived packets. | |
| 3287 0x00, | |
| 3288 }; | |
| 3289 | |
| 3290 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3291 ASSERT_TRUE(data != nullptr); | |
| 3292 | |
| 3293 test::CompareCharArraysWithHexError("constructed packet", | |
| 3294 data->data(), data->length(), | |
| 3295 AsChars(packet), arraysize(packet)); | |
| 3296 } | |
| 3297 | |
| 3298 // TODO(jri): Add test for tuncated packets in which the original ack frame had | |
| 3299 // revived packets. (In both the large and small packet cases below). | |
| 3300 | |
| 3301 TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacket) { | |
| 3302 QuicPacketHeader header; | |
| 3303 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3304 header.public_header.reset_flag = false; | |
| 3305 header.public_header.version_flag = false; | |
| 3306 header.fec_flag = false; | |
| 3307 header.entropy_flag = true; | |
| 3308 header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8); | |
| 3309 header.fec_group = 0; | |
| 3310 | |
| 3311 QuicAckFrame ack_frame; | |
| 3312 // This entropy hash is different from what shows up in the packet below, | |
| 3313 // since entropy is recomputed by the framer on ack truncation (by | |
| 3314 // TestEntropyCalculator for this test.) | |
| 3315 ack_frame.entropy_hash = 0x43; | |
| 3316 ack_frame.largest_observed = 2 * 300; | |
| 3317 ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero(); | |
| 3318 for (size_t i = 1; i < 2 * 300; i += 2) { | |
| 3319 ack_frame.missing_packets.insert(i); | |
| 3320 } | |
| 3321 | |
| 3322 QuicFrames frames; | |
| 3323 frames.push_back(QuicFrame(&ack_frame)); | |
| 3324 | |
| 3325 unsigned char packet[] = { | |
| 3326 // public flags (8 byte connection_id) | |
| 3327 0x3C, | |
| 3328 // connection_id | |
| 3329 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 3330 // packet sequence number | |
| 3331 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 3332 // private flags (entropy) | |
| 3333 0x01, | |
| 3334 | |
| 3335 // frame type (ack frame) | |
| 3336 // (has nacks, is truncated, 2 byte largest observed, 1 byte delta) | |
| 3337 0x74, | |
| 3338 // entropy hash of all received packets, set to 1 by TestEntropyCalculator | |
| 3339 // since ack is truncated. | |
| 3340 0x01, | |
| 3341 // 2-byte largest observed packet sequence number. | |
| 3342 // Expected to be 510 (0x1FE), since only 255 nack ranges can fit. | |
| 3343 0xFE, 0x01, | |
| 3344 // Zero delta time. | |
| 3345 0x00, 0x00, | |
| 3346 // num missing packet ranges (limited to 255 by size of this field). | |
| 3347 0xFF, | |
| 3348 // {missing packet delta, further missing packets in range} | |
| 3349 // 6 nack ranges x 42 + 3 nack ranges | |
| 3350 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3351 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3352 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3353 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3354 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3355 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3356 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3357 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3358 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3359 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3360 | |
| 3361 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3362 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3363 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3364 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3365 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3366 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3367 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3368 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3369 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3370 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3371 | |
| 3372 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3373 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3374 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3375 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3376 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3377 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3378 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3379 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3380 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3381 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3382 | |
| 3383 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3384 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3385 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3386 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3387 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3388 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3389 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3390 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3391 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3392 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3393 | |
| 3394 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3395 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3396 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3397 | |
| 3398 // 0 revived packets. | |
| 3399 0x00, | |
| 3400 }; | |
| 3401 | |
| 3402 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3403 ASSERT_TRUE(data != nullptr); | |
| 3404 | |
| 3405 test::CompareCharArraysWithHexError("constructed packet", | |
| 3406 data->data(), data->length(), | |
| 3407 AsChars(packet), arraysize(packet)); | |
| 3408 } | |
| 3409 | |
| 3410 TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacket) { | |
| 3411 QuicPacketHeader header; | |
| 3412 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3413 header.public_header.reset_flag = false; | |
| 3414 header.public_header.version_flag = false; | |
| 3415 header.fec_flag = false; | |
| 3416 header.entropy_flag = true; | |
| 3417 header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8); | |
| 3418 header.fec_group = 0; | |
| 3419 | |
| 3420 QuicAckFrame ack_frame; | |
| 3421 // This entropy hash is different from what shows up in the packet below, | |
| 3422 // since entropy is recomputed by the framer on ack truncation (by | |
| 3423 // TestEntropyCalculator for this test.) | |
| 3424 ack_frame.entropy_hash = 0x43; | |
| 3425 ack_frame.largest_observed = 2 * 300; | |
| 3426 ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero(); | |
| 3427 for (size_t i = 1; i < 2 * 300; i += 2) { | |
| 3428 ack_frame.missing_packets.insert(i); | |
| 3429 } | |
| 3430 | |
| 3431 QuicFrames frames; | |
| 3432 frames.push_back(QuicFrame(&ack_frame)); | |
| 3433 | |
| 3434 unsigned char packet[] = { | |
| 3435 // public flags (8 byte connection_id) | |
| 3436 0x3C, | |
| 3437 // connection_id | |
| 3438 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, | |
| 3439 // packet sequence number | |
| 3440 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12, | |
| 3441 // private flags (entropy) | |
| 3442 0x01, | |
| 3443 | |
| 3444 // frame type (ack frame) | |
| 3445 // (has nacks, is truncated, 2 byte largest observed, 1 byte delta) | |
| 3446 0x74, | |
| 3447 // entropy hash of all received packets, set to 1 by TestEntropyCalculator | |
| 3448 // since ack is truncated. | |
| 3449 0x01, | |
| 3450 // 2-byte largest observed packet sequence number. | |
| 3451 // Expected to be 12 (0x0C), since only 6 nack ranges can fit. | |
| 3452 0x0C, 0x00, | |
| 3453 // Zero delta time. | |
| 3454 0x00, 0x00, | |
| 3455 // num missing packet ranges (limited to 6 by packet size of 37). | |
| 3456 0x06, | |
| 3457 // {missing packet delta, further missing packets in range} | |
| 3458 // 6 nack ranges | |
| 3459 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, | |
| 3460 // 0 revived packets. | |
| 3461 0x00, | |
| 3462 }; | |
| 3463 | |
| 3464 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames, 37u)); | |
| 3465 ASSERT_TRUE(data != nullptr); | |
| 3466 // Expect 1 byte unused since at least 2 bytes are needed to fit more nacks. | |
| 3467 EXPECT_EQ(36u, data->length()); | |
| 3468 test::CompareCharArraysWithHexError("constructed packet", | |
| 3469 data->data(), data->length(), | |
| 3470 AsChars(packet), arraysize(packet)); | |
| 3471 } | |
| 3472 | |
| 3473 TEST_P(QuicFramerTest, BuildStopWaitingPacket) { | |
| 3474 QuicPacketHeader header; | |
| 3475 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3476 header.public_header.reset_flag = false; | |
| 3477 header.public_header.version_flag = false; | |
| 3478 header.fec_flag = false; | |
| 3479 header.entropy_flag = true; | |
| 3480 header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8); | |
| 3481 header.fec_group = 0; | |
| 3482 | |
| 3483 QuicStopWaitingFrame stop_waiting_frame; | |
| 3484 stop_waiting_frame.entropy_hash = 0x14; | |
| 3485 stop_waiting_frame.least_unacked = GG_UINT64_C(0x770123456789AA0); | |
| 3486 | |
| 3487 QuicFrames frames; | |
| 3488 frames.push_back(QuicFrame(&stop_waiting_frame)); | |
| 3489 | |
| 3490 unsigned char packet[] = { | |
| 3491 // public flags (8 byte connection_id) | |
| 3492 0x3C, | |
| 3493 // connection_id | |
| 3494 0x10, 0x32, 0x54, 0x76, | |
| 3495 0x98, 0xBA, 0xDC, 0xFE, | |
| 3496 // packet sequence number | |
| 3497 0xA8, 0x9A, 0x78, 0x56, | |
| 3498 0x34, 0x12, | |
| 3499 // private flags (entropy) | |
| 3500 0x01, | |
| 3501 | |
| 3502 // frame type (stop waiting frame) | |
| 3503 0x06, | |
| 3504 // entropy hash of sent packets till least awaiting - 1. | |
| 3505 0x14, | |
| 3506 // least packet sequence number awaiting an ack, delta from sequence number. | |
| 3507 0x08, 0x00, 0x00, 0x00, | |
| 3508 0x00, 0x00, | |
| 3509 }; | |
| 3510 | |
| 3511 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3512 ASSERT_TRUE(data != nullptr); | |
| 3513 | |
| 3514 test::CompareCharArraysWithHexError("constructed packet", | |
| 3515 data->data(), data->length(), | |
| 3516 AsChars(packet), arraysize(packet)); | |
| 3517 } | |
| 3518 | |
| 3519 TEST_P(QuicFramerTest, BuildRstFramePacketQuic) { | |
| 3520 QuicPacketHeader header; | |
| 3521 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3522 header.public_header.reset_flag = false; | |
| 3523 header.public_header.version_flag = false; | |
| 3524 header.fec_flag = false; | |
| 3525 header.entropy_flag = false; | |
| 3526 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3527 header.fec_group = 0; | |
| 3528 | |
| 3529 QuicRstStreamFrame rst_frame; | |
| 3530 rst_frame.stream_id = 0x01020304; | |
| 3531 rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708); | |
| 3532 rst_frame.error_details = "because I can"; | |
| 3533 rst_frame.byte_offset = 0x0807060504030201; | |
| 3534 | |
| 3535 unsigned char packet[] = { | |
| 3536 // public flags (8 byte connection_id) | |
| 3537 0x3C, | |
| 3538 // connection_id | |
| 3539 0x10, 0x32, 0x54, 0x76, | |
| 3540 0x98, 0xBA, 0xDC, 0xFE, | |
| 3541 // packet sequence number | |
| 3542 0xBC, 0x9A, 0x78, 0x56, | |
| 3543 0x34, 0x12, | |
| 3544 // private flags | |
| 3545 0x00, | |
| 3546 | |
| 3547 // frame type (rst stream frame) | |
| 3548 0x01, | |
| 3549 // stream id | |
| 3550 0x04, 0x03, 0x02, 0x01, | |
| 3551 // sent byte offset | |
| 3552 0x01, 0x02, 0x03, 0x04, | |
| 3553 0x05, 0x06, 0x07, 0x08, | |
| 3554 // error code | |
| 3555 0x08, 0x07, 0x06, 0x05, | |
| 3556 // error details length | |
| 3557 0x0d, 0x00, | |
| 3558 // error details | |
| 3559 'b', 'e', 'c', 'a', | |
| 3560 'u', 's', 'e', ' ', | |
| 3561 'I', ' ', 'c', 'a', | |
| 3562 'n', | |
| 3563 }; | |
| 3564 | |
| 3565 QuicFrames frames; | |
| 3566 frames.push_back(QuicFrame(&rst_frame)); | |
| 3567 | |
| 3568 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3569 ASSERT_TRUE(data != nullptr); | |
| 3570 | |
| 3571 test::CompareCharArraysWithHexError("constructed packet", | |
| 3572 data->data(), data->length(), | |
| 3573 AsChars(packet), arraysize(packet)); | |
| 3574 } | |
| 3575 | |
| 3576 TEST_P(QuicFramerTest, BuildCloseFramePacket) { | |
| 3577 QuicPacketHeader header; | |
| 3578 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3579 header.public_header.reset_flag = false; | |
| 3580 header.public_header.version_flag = false; | |
| 3581 header.fec_flag = false; | |
| 3582 header.entropy_flag = true; | |
| 3583 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3584 header.fec_group = 0; | |
| 3585 | |
| 3586 QuicConnectionCloseFrame close_frame; | |
| 3587 close_frame.error_code = static_cast<QuicErrorCode>(0x05060708); | |
| 3588 close_frame.error_details = "because I can"; | |
| 3589 | |
| 3590 QuicFrames frames; | |
| 3591 frames.push_back(QuicFrame(&close_frame)); | |
| 3592 | |
| 3593 unsigned char packet[] = { | |
| 3594 // public flags (8 byte connection_id) | |
| 3595 0x3C, | |
| 3596 // connection_id | |
| 3597 0x10, 0x32, 0x54, 0x76, | |
| 3598 0x98, 0xBA, 0xDC, 0xFE, | |
| 3599 // packet sequence number | |
| 3600 0xBC, 0x9A, 0x78, 0x56, | |
| 3601 0x34, 0x12, | |
| 3602 // private flags (entropy) | |
| 3603 0x01, | |
| 3604 | |
| 3605 // frame type (connection close frame) | |
| 3606 0x02, | |
| 3607 // error code | |
| 3608 0x08, 0x07, 0x06, 0x05, | |
| 3609 // error details length | |
| 3610 0x0d, 0x00, | |
| 3611 // error details | |
| 3612 'b', 'e', 'c', 'a', | |
| 3613 'u', 's', 'e', ' ', | |
| 3614 'I', ' ', 'c', 'a', | |
| 3615 'n', | |
| 3616 }; | |
| 3617 | |
| 3618 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3619 ASSERT_TRUE(data != nullptr); | |
| 3620 | |
| 3621 test::CompareCharArraysWithHexError("constructed packet", | |
| 3622 data->data(), data->length(), | |
| 3623 AsChars(packet), arraysize(packet)); | |
| 3624 } | |
| 3625 | |
| 3626 TEST_P(QuicFramerTest, BuildGoAwayPacket) { | |
| 3627 QuicPacketHeader header; | |
| 3628 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3629 header.public_header.reset_flag = false; | |
| 3630 header.public_header.version_flag = false; | |
| 3631 header.fec_flag = false; | |
| 3632 header.entropy_flag = true; | |
| 3633 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3634 header.fec_group = 0; | |
| 3635 | |
| 3636 QuicGoAwayFrame goaway_frame; | |
| 3637 goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708); | |
| 3638 goaway_frame.last_good_stream_id = 0x01020304; | |
| 3639 goaway_frame.reason_phrase = "because I can"; | |
| 3640 | |
| 3641 QuicFrames frames; | |
| 3642 frames.push_back(QuicFrame(&goaway_frame)); | |
| 3643 | |
| 3644 unsigned char packet[] = { | |
| 3645 // public flags (8 byte connection_id) | |
| 3646 0x3C, | |
| 3647 // connection_id | |
| 3648 0x10, 0x32, 0x54, 0x76, | |
| 3649 0x98, 0xBA, 0xDC, 0xFE, | |
| 3650 // packet sequence number | |
| 3651 0xBC, 0x9A, 0x78, 0x56, | |
| 3652 0x34, 0x12, | |
| 3653 // private flags(entropy) | |
| 3654 0x01, | |
| 3655 | |
| 3656 // frame type (go away frame) | |
| 3657 0x03, | |
| 3658 // error code | |
| 3659 0x08, 0x07, 0x06, 0x05, | |
| 3660 // stream id | |
| 3661 0x04, 0x03, 0x02, 0x01, | |
| 3662 // error details length | |
| 3663 0x0d, 0x00, | |
| 3664 // error details | |
| 3665 'b', 'e', 'c', 'a', | |
| 3666 'u', 's', 'e', ' ', | |
| 3667 'I', ' ', 'c', 'a', | |
| 3668 'n', | |
| 3669 }; | |
| 3670 | |
| 3671 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3672 ASSERT_TRUE(data != nullptr); | |
| 3673 | |
| 3674 test::CompareCharArraysWithHexError("constructed packet", | |
| 3675 data->data(), data->length(), | |
| 3676 AsChars(packet), arraysize(packet)); | |
| 3677 } | |
| 3678 | |
| 3679 TEST_P(QuicFramerTest, BuildWindowUpdatePacket) { | |
| 3680 QuicPacketHeader header; | |
| 3681 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3682 header.public_header.reset_flag = false; | |
| 3683 header.public_header.version_flag = false; | |
| 3684 header.fec_flag = false; | |
| 3685 header.entropy_flag = true; | |
| 3686 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3687 header.fec_group = 0; | |
| 3688 | |
| 3689 QuicWindowUpdateFrame window_update_frame; | |
| 3690 window_update_frame.stream_id = 0x01020304; | |
| 3691 window_update_frame.byte_offset = 0x1122334455667788; | |
| 3692 | |
| 3693 QuicFrames frames; | |
| 3694 frames.push_back(QuicFrame(&window_update_frame)); | |
| 3695 | |
| 3696 unsigned char packet[] = { | |
| 3697 // public flags (8 byte connection_id) | |
| 3698 0x3C, | |
| 3699 // connection_id | |
| 3700 0x10, 0x32, 0x54, 0x76, | |
| 3701 0x98, 0xBA, 0xDC, 0xFE, | |
| 3702 // packet sequence number | |
| 3703 0xBC, 0x9A, 0x78, 0x56, | |
| 3704 0x34, 0x12, | |
| 3705 // private flags(entropy) | |
| 3706 0x01, | |
| 3707 | |
| 3708 // frame type (window update frame) | |
| 3709 0x04, | |
| 3710 // stream id | |
| 3711 0x04, 0x03, 0x02, 0x01, | |
| 3712 // byte offset | |
| 3713 0x88, 0x77, 0x66, 0x55, | |
| 3714 0x44, 0x33, 0x22, 0x11, | |
| 3715 }; | |
| 3716 | |
| 3717 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3718 ASSERT_TRUE(data != nullptr); | |
| 3719 | |
| 3720 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
| 3721 data->length(), AsChars(packet), | |
| 3722 arraysize(packet)); | |
| 3723 } | |
| 3724 | |
| 3725 TEST_P(QuicFramerTest, BuildBlockedPacket) { | |
| 3726 QuicPacketHeader header; | |
| 3727 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3728 header.public_header.reset_flag = false; | |
| 3729 header.public_header.version_flag = false; | |
| 3730 header.fec_flag = false; | |
| 3731 header.entropy_flag = true; | |
| 3732 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3733 header.fec_group = 0; | |
| 3734 | |
| 3735 QuicBlockedFrame blocked_frame; | |
| 3736 blocked_frame.stream_id = 0x01020304; | |
| 3737 | |
| 3738 QuicFrames frames; | |
| 3739 frames.push_back(QuicFrame(&blocked_frame)); | |
| 3740 | |
| 3741 unsigned char packet[] = { | |
| 3742 // public flags (8 byte connection_id) | |
| 3743 0x3C, | |
| 3744 // connection_id | |
| 3745 0x10, 0x32, 0x54, 0x76, | |
| 3746 0x98, 0xBA, 0xDC, 0xFE, | |
| 3747 // packet sequence number | |
| 3748 0xBC, 0x9A, 0x78, 0x56, | |
| 3749 0x34, 0x12, | |
| 3750 // private flags(entropy) | |
| 3751 0x01, | |
| 3752 | |
| 3753 // frame type (blocked frame) | |
| 3754 0x05, | |
| 3755 // stream id | |
| 3756 0x04, 0x03, 0x02, 0x01, | |
| 3757 }; | |
| 3758 | |
| 3759 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3760 ASSERT_TRUE(data != nullptr); | |
| 3761 | |
| 3762 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
| 3763 data->length(), AsChars(packet), | |
| 3764 arraysize(packet)); | |
| 3765 } | |
| 3766 | |
| 3767 TEST_P(QuicFramerTest, BuildPingPacket) { | |
| 3768 QuicPacketHeader header; | |
| 3769 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3770 header.public_header.reset_flag = false; | |
| 3771 header.public_header.version_flag = false; | |
| 3772 header.fec_flag = false; | |
| 3773 header.entropy_flag = true; | |
| 3774 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3775 header.fec_group = 0; | |
| 3776 | |
| 3777 QuicPingFrame ping_frame; | |
| 3778 | |
| 3779 QuicFrames frames; | |
| 3780 frames.push_back(QuicFrame(&ping_frame)); | |
| 3781 | |
| 3782 unsigned char packet[] = { | |
| 3783 // public flags (8 byte connection_id) | |
| 3784 0x3C, | |
| 3785 // connection_id | |
| 3786 0x10, 0x32, 0x54, 0x76, | |
| 3787 0x98, 0xBA, 0xDC, 0xFE, | |
| 3788 // packet sequence number | |
| 3789 0xBC, 0x9A, 0x78, 0x56, | |
| 3790 0x34, 0x12, | |
| 3791 // private flags(entropy) | |
| 3792 0x01, | |
| 3793 | |
| 3794 // frame type (ping frame) | |
| 3795 0x07, | |
| 3796 }; | |
| 3797 | |
| 3798 scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); | |
| 3799 ASSERT_TRUE(data != nullptr); | |
| 3800 | |
| 3801 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
| 3802 data->length(), AsChars(packet), | |
| 3803 arraysize(packet)); | |
| 3804 } | |
| 3805 | |
| 3806 TEST_P(QuicFramerTest, BuildPublicResetPacket) { | |
| 3807 QuicPublicResetPacket reset_packet; | |
| 3808 reset_packet.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3809 reset_packet.public_header.reset_flag = true; | |
| 3810 reset_packet.public_header.version_flag = false; | |
| 3811 reset_packet.rejected_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3812 reset_packet.nonce_proof = GG_UINT64_C(0xABCDEF0123456789); | |
| 3813 | |
| 3814 unsigned char packet[] = { | |
| 3815 // public flags (public reset, 8 byte ConnectionId) | |
| 3816 0x0E, | |
| 3817 // connection_id | |
| 3818 0x10, 0x32, 0x54, 0x76, | |
| 3819 0x98, 0xBA, 0xDC, 0xFE, | |
| 3820 // message tag (kPRST) | |
| 3821 'P', 'R', 'S', 'T', | |
| 3822 // num_entries (2) + padding | |
| 3823 0x02, 0x00, 0x00, 0x00, | |
| 3824 // tag kRNON | |
| 3825 'R', 'N', 'O', 'N', | |
| 3826 // end offset 8 | |
| 3827 0x08, 0x00, 0x00, 0x00, | |
| 3828 // tag kRSEQ | |
| 3829 'R', 'S', 'E', 'Q', | |
| 3830 // end offset 16 | |
| 3831 0x10, 0x00, 0x00, 0x00, | |
| 3832 // nonce proof | |
| 3833 0x89, 0x67, 0x45, 0x23, | |
| 3834 0x01, 0xEF, 0xCD, 0xAB, | |
| 3835 // rejected sequence number | |
| 3836 0xBC, 0x9A, 0x78, 0x56, | |
| 3837 0x34, 0x12, 0x00, 0x00, | |
| 3838 }; | |
| 3839 | |
| 3840 scoped_ptr<QuicEncryptedPacket> data( | |
| 3841 framer_.BuildPublicResetPacket(reset_packet)); | |
| 3842 ASSERT_TRUE(data != nullptr); | |
| 3843 | |
| 3844 test::CompareCharArraysWithHexError("constructed packet", | |
| 3845 data->data(), data->length(), | |
| 3846 AsChars(packet), arraysize(packet)); | |
| 3847 } | |
| 3848 | |
| 3849 TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) { | |
| 3850 QuicPublicResetPacket reset_packet; | |
| 3851 reset_packet.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3852 reset_packet.public_header.reset_flag = true; | |
| 3853 reset_packet.public_header.version_flag = false; | |
| 3854 reset_packet.rejected_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3855 reset_packet.nonce_proof = GG_UINT64_C(0xABCDEF0123456789); | |
| 3856 reset_packet.client_address = IPEndPoint(Loopback4(), 0x1234); | |
| 3857 | |
| 3858 unsigned char packet[] = { | |
| 3859 // public flags (public reset, 8 byte ConnectionId) | |
| 3860 0x0E, | |
| 3861 // connection_id | |
| 3862 0x10, 0x32, 0x54, 0x76, | |
| 3863 0x98, 0xBA, 0xDC, 0xFE, | |
| 3864 // message tag (kPRST) | |
| 3865 'P', 'R', 'S', 'T', | |
| 3866 // num_entries (3) + padding | |
| 3867 0x03, 0x00, 0x00, 0x00, | |
| 3868 // tag kRNON | |
| 3869 'R', 'N', 'O', 'N', | |
| 3870 // end offset 8 | |
| 3871 0x08, 0x00, 0x00, 0x00, | |
| 3872 // tag kRSEQ | |
| 3873 'R', 'S', 'E', 'Q', | |
| 3874 // end offset 16 | |
| 3875 0x10, 0x00, 0x00, 0x00, | |
| 3876 // tag kCADR | |
| 3877 'C', 'A', 'D', 'R', | |
| 3878 // end offset 24 | |
| 3879 0x18, 0x00, 0x00, 0x00, | |
| 3880 // nonce proof | |
| 3881 0x89, 0x67, 0x45, 0x23, | |
| 3882 0x01, 0xEF, 0xCD, 0xAB, | |
| 3883 // rejected sequence number | |
| 3884 0xBC, 0x9A, 0x78, 0x56, | |
| 3885 0x34, 0x12, 0x00, 0x00, | |
| 3886 // client address | |
| 3887 0x02, 0x00, | |
| 3888 0x7F, 0x00, 0x00, 0x01, | |
| 3889 0x34, 0x12, | |
| 3890 }; | |
| 3891 | |
| 3892 scoped_ptr<QuicEncryptedPacket> data( | |
| 3893 framer_.BuildPublicResetPacket(reset_packet)); | |
| 3894 ASSERT_TRUE(data != nullptr); | |
| 3895 | |
| 3896 test::CompareCharArraysWithHexError("constructed packet", | |
| 3897 data->data(), data->length(), | |
| 3898 AsChars(packet), arraysize(packet)); | |
| 3899 } | |
| 3900 | |
| 3901 TEST_P(QuicFramerTest, BuildFecPacket) { | |
| 3902 QuicPacketHeader header; | |
| 3903 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 3904 header.public_header.reset_flag = false; | |
| 3905 header.public_header.version_flag = false; | |
| 3906 header.fec_flag = true; | |
| 3907 header.entropy_flag = true; | |
| 3908 header.packet_sequence_number = (GG_UINT64_C(0x123456789ABC)); | |
| 3909 header.is_in_fec_group = IN_FEC_GROUP; | |
| 3910 header.fec_group = GG_UINT64_C(0x123456789ABB);; | |
| 3911 | |
| 3912 QuicFecData fec_data; | |
| 3913 fec_data.fec_group = 1; | |
| 3914 fec_data.redundancy = "abcdefghijklmnop"; | |
| 3915 | |
| 3916 unsigned char packet[] = { | |
| 3917 // public flags (8 byte connection_id) | |
| 3918 0x3C, | |
| 3919 // connection_id | |
| 3920 0x10, 0x32, 0x54, 0x76, | |
| 3921 0x98, 0xBA, 0xDC, 0xFE, | |
| 3922 // packet sequence number | |
| 3923 0xBC, 0x9A, 0x78, 0x56, | |
| 3924 0x34, 0x12, | |
| 3925 // private flags (entropy & fec group & fec packet) | |
| 3926 0x07, | |
| 3927 // first fec protected packet offset | |
| 3928 0x01, | |
| 3929 | |
| 3930 // redundancy | |
| 3931 'a', 'b', 'c', 'd', | |
| 3932 'e', 'f', 'g', 'h', | |
| 3933 'i', 'j', 'k', 'l', | |
| 3934 'm', 'n', 'o', 'p', | |
| 3935 }; | |
| 3936 | |
| 3937 scoped_ptr<QuicPacket> data(framer_.BuildFecPacket(header, fec_data)); | |
| 3938 ASSERT_TRUE(data != nullptr); | |
| 3939 | |
| 3940 test::CompareCharArraysWithHexError("constructed packet", | |
| 3941 data->data(), data->length(), | |
| 3942 AsChars(packet), arraysize(packet)); | |
| 3943 } | |
| 3944 | |
| 3945 TEST_P(QuicFramerTest, EncryptPacket) { | |
| 3946 QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3947 unsigned char packet[] = { | |
| 3948 // public flags (8 byte connection_id) | |
| 3949 0x3C, | |
| 3950 // connection_id | |
| 3951 0x10, 0x32, 0x54, 0x76, | |
| 3952 0x98, 0xBA, 0xDC, 0xFE, | |
| 3953 // packet sequence number | |
| 3954 0xBC, 0x9A, 0x78, 0x56, | |
| 3955 0x34, 0x12, | |
| 3956 // private flags (fec group & fec packet) | |
| 3957 0x06, | |
| 3958 // first fec protected packet offset | |
| 3959 0x01, | |
| 3960 | |
| 3961 // redundancy | |
| 3962 'a', 'b', 'c', 'd', | |
| 3963 'e', 'f', 'g', 'h', | |
| 3964 'i', 'j', 'k', 'l', | |
| 3965 'm', 'n', 'o', 'p', | |
| 3966 }; | |
| 3967 | |
| 3968 scoped_ptr<QuicPacket> raw(new QuicPacket( | |
| 3969 AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, | |
| 3970 !kIncludeVersion, PACKET_6BYTE_SEQUENCE_NUMBER)); | |
| 3971 scoped_ptr<QuicEncryptedPacket> encrypted( | |
| 3972 framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw)); | |
| 3973 | |
| 3974 ASSERT_TRUE(encrypted.get() != nullptr); | |
| 3975 EXPECT_TRUE(CheckEncryption(sequence_number, raw.get())); | |
| 3976 } | |
| 3977 | |
| 3978 TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) { | |
| 3979 QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 3980 unsigned char packet[] = { | |
| 3981 // public flags (version, 8 byte connection_id) | |
| 3982 0x3D, | |
| 3983 // connection_id | |
| 3984 0x10, 0x32, 0x54, 0x76, | |
| 3985 0x98, 0xBA, 0xDC, 0xFE, | |
| 3986 // version tag | |
| 3987 'Q', '.', '1', '0', | |
| 3988 // packet sequence number | |
| 3989 0xBC, 0x9A, 0x78, 0x56, | |
| 3990 0x34, 0x12, | |
| 3991 // private flags (fec group & fec flags) | |
| 3992 0x06, | |
| 3993 // first fec protected packet offset | |
| 3994 0x01, | |
| 3995 | |
| 3996 // redundancy | |
| 3997 'a', 'b', 'c', 'd', | |
| 3998 'e', 'f', 'g', 'h', | |
| 3999 'i', 'j', 'k', 'l', | |
| 4000 'm', 'n', 'o', 'p', | |
| 4001 }; | |
| 4002 | |
| 4003 scoped_ptr<QuicPacket> raw(new QuicPacket( | |
| 4004 AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, | |
| 4005 kIncludeVersion, PACKET_6BYTE_SEQUENCE_NUMBER)); | |
| 4006 scoped_ptr<QuicEncryptedPacket> encrypted( | |
| 4007 framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw)); | |
| 4008 | |
| 4009 ASSERT_TRUE(encrypted.get() != nullptr); | |
| 4010 EXPECT_TRUE(CheckEncryption(sequence_number, raw.get())); | |
| 4011 } | |
| 4012 | |
| 4013 TEST_P(QuicFramerTest, AckTruncationLargePacket) { | |
| 4014 QuicPacketHeader header; | |
| 4015 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 4016 header.public_header.reset_flag = false; | |
| 4017 header.public_header.version_flag = false; | |
| 4018 header.fec_flag = false; | |
| 4019 header.entropy_flag = false; | |
| 4020 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 4021 header.fec_group = 0; | |
| 4022 | |
| 4023 // Create a packet with just the ack. | |
| 4024 QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u); | |
| 4025 QuicFrame frame; | |
| 4026 frame.type = ACK_FRAME; | |
| 4027 frame.ack_frame = &ack_frame; | |
| 4028 QuicFrames frames; | |
| 4029 frames.push_back(frame); | |
| 4030 | |
| 4031 // Build an ack packet with truncation due to limit in number of nack ranges. | |
| 4032 scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames)); | |
| 4033 ASSERT_TRUE(raw_ack_packet != nullptr); | |
| 4034 scoped_ptr<QuicEncryptedPacket> ack_packet( | |
| 4035 framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number, | |
| 4036 *raw_ack_packet)); | |
| 4037 // Now make sure we can turn our ack packet back into an ack frame. | |
| 4038 ASSERT_TRUE(framer_.ProcessPacket(*ack_packet)); | |
| 4039 ASSERT_EQ(1u, visitor_.ack_frames_.size()); | |
| 4040 QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0]; | |
| 4041 EXPECT_TRUE(processed_ack_frame.is_truncated); | |
| 4042 EXPECT_EQ(510u, processed_ack_frame.largest_observed); | |
| 4043 ASSERT_EQ(255u, processed_ack_frame.missing_packets.size()); | |
| 4044 SequenceNumberSet::const_iterator missing_iter = | |
| 4045 processed_ack_frame.missing_packets.begin(); | |
| 4046 EXPECT_EQ(1u, *missing_iter); | |
| 4047 SequenceNumberSet::const_reverse_iterator last_missing_iter = | |
| 4048 processed_ack_frame.missing_packets.rbegin(); | |
| 4049 EXPECT_EQ(509u, *last_missing_iter); | |
| 4050 } | |
| 4051 | |
| 4052 TEST_P(QuicFramerTest, AckTruncationSmallPacket) { | |
| 4053 QuicPacketHeader header; | |
| 4054 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 4055 header.public_header.reset_flag = false; | |
| 4056 header.public_header.version_flag = false; | |
| 4057 header.fec_flag = false; | |
| 4058 header.entropy_flag = false; | |
| 4059 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 4060 header.fec_group = 0; | |
| 4061 | |
| 4062 // Create a packet with just the ack. | |
| 4063 QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u); | |
| 4064 QuicFrame frame; | |
| 4065 frame.type = ACK_FRAME; | |
| 4066 frame.ack_frame = &ack_frame; | |
| 4067 QuicFrames frames; | |
| 4068 frames.push_back(frame); | |
| 4069 | |
| 4070 // Build an ack packet with truncation due to limit in number of nack ranges. | |
| 4071 scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames, 500)); | |
| 4072 ASSERT_TRUE(raw_ack_packet != nullptr); | |
| 4073 scoped_ptr<QuicEncryptedPacket> ack_packet( | |
| 4074 framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number, | |
| 4075 *raw_ack_packet)); | |
| 4076 // Now make sure we can turn our ack packet back into an ack frame. | |
| 4077 ASSERT_TRUE(framer_.ProcessPacket(*ack_packet)); | |
| 4078 ASSERT_EQ(1u, visitor_.ack_frames_.size()); | |
| 4079 QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0]; | |
| 4080 EXPECT_TRUE(processed_ack_frame.is_truncated); | |
| 4081 EXPECT_EQ(476u, processed_ack_frame.largest_observed); | |
| 4082 ASSERT_EQ(238u, processed_ack_frame.missing_packets.size()); | |
| 4083 SequenceNumberSet::const_iterator missing_iter = | |
| 4084 processed_ack_frame.missing_packets.begin(); | |
| 4085 EXPECT_EQ(1u, *missing_iter); | |
| 4086 SequenceNumberSet::const_reverse_iterator last_missing_iter = | |
| 4087 processed_ack_frame.missing_packets.rbegin(); | |
| 4088 EXPECT_EQ(475u, *last_missing_iter); | |
| 4089 } | |
| 4090 | |
| 4091 TEST_P(QuicFramerTest, CleanTruncation) { | |
| 4092 QuicPacketHeader header; | |
| 4093 header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); | |
| 4094 header.public_header.reset_flag = false; | |
| 4095 header.public_header.version_flag = false; | |
| 4096 header.fec_flag = false; | |
| 4097 header.entropy_flag = true; | |
| 4098 header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); | |
| 4099 header.fec_group = 0; | |
| 4100 | |
| 4101 QuicAckFrame ack_frame; | |
| 4102 ack_frame.largest_observed = 201; | |
| 4103 for (uint64 i = 1; i < ack_frame.largest_observed; ++i) { | |
| 4104 ack_frame.missing_packets.insert(i); | |
| 4105 } | |
| 4106 | |
| 4107 // Create a packet with just the ack. | |
| 4108 QuicFrame frame; | |
| 4109 frame.type = ACK_FRAME; | |
| 4110 frame.ack_frame = &ack_frame; | |
| 4111 QuicFrames frames; | |
| 4112 frames.push_back(frame); | |
| 4113 | |
| 4114 scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames)); | |
| 4115 ASSERT_TRUE(raw_ack_packet != nullptr); | |
| 4116 | |
| 4117 scoped_ptr<QuicEncryptedPacket> ack_packet( | |
| 4118 framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number, | |
| 4119 *raw_ack_packet)); | |
| 4120 | |
| 4121 // Now make sure we can turn our ack packet back into an ack frame. | |
| 4122 ASSERT_TRUE(framer_.ProcessPacket(*ack_packet)); | |
| 4123 | |
| 4124 // Test for clean truncation of the ack by comparing the length of the | |
| 4125 // original packets to the re-serialized packets. | |
| 4126 frames.clear(); | |
| 4127 frame.type = ACK_FRAME; | |
| 4128 frame.ack_frame = visitor_.ack_frames_[0]; | |
| 4129 frames.push_back(frame); | |
| 4130 | |
| 4131 size_t original_raw_length = raw_ack_packet->length(); | |
| 4132 raw_ack_packet.reset(BuildDataPacket(header, frames)); | |
| 4133 ASSERT_TRUE(raw_ack_packet != nullptr); | |
| 4134 EXPECT_EQ(original_raw_length, raw_ack_packet->length()); | |
| 4135 ASSERT_TRUE(raw_ack_packet != nullptr); | |
| 4136 } | |
| 4137 | |
| 4138 TEST_P(QuicFramerTest, EntropyFlagTest) { | |
| 4139 unsigned char packet[] = { | |
| 4140 // public flags (8 byte connection_id) | |
| 4141 0x3C, | |
| 4142 // connection_id | |
| 4143 0x10, 0x32, 0x54, 0x76, | |
| 4144 0x98, 0xBA, 0xDC, 0xFE, | |
| 4145 // packet sequence number | |
| 4146 0xBC, 0x9A, 0x78, 0x56, | |
| 4147 0x34, 0x12, | |
| 4148 // private flags (Entropy) | |
| 4149 0x01, | |
| 4150 | |
| 4151 // frame type (stream frame with fin and no length) | |
| 4152 0xDF, | |
| 4153 // stream id | |
| 4154 0x04, 0x03, 0x02, 0x01, | |
| 4155 // offset | |
| 4156 0x54, 0x76, 0x10, 0x32, | |
| 4157 0xDC, 0xFE, 0x98, 0xBA, | |
| 4158 // data | |
| 4159 'h', 'e', 'l', 'l', | |
| 4160 'o', ' ', 'w', 'o', | |
| 4161 'r', 'l', 'd', '!', | |
| 4162 }; | |
| 4163 | |
| 4164 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 4165 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 4166 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 4167 ASSERT_TRUE(visitor_.header_.get()); | |
| 4168 EXPECT_TRUE(visitor_.header_->entropy_flag); | |
| 4169 EXPECT_EQ(1 << 4, visitor_.header_->entropy_hash); | |
| 4170 EXPECT_FALSE(visitor_.header_->fec_flag); | |
| 4171 }; | |
| 4172 | |
| 4173 TEST_P(QuicFramerTest, FecEntropyTest) { | |
| 4174 unsigned char packet[] = { | |
| 4175 // public flags (8 byte connection_id) | |
| 4176 0x3C, | |
| 4177 // connection_id | |
| 4178 0x10, 0x32, 0x54, 0x76, | |
| 4179 0x98, 0xBA, 0xDC, 0xFE, | |
| 4180 // packet sequence number | |
| 4181 0xBC, 0x9A, 0x78, 0x56, | |
| 4182 0x34, 0x12, | |
| 4183 // private flags (Entropy & fec group & FEC) | |
| 4184 0x07, | |
| 4185 // first fec protected packet offset | |
| 4186 0xFF, | |
| 4187 | |
| 4188 // frame type (stream frame with fin and no length) | |
| 4189 0xDF, | |
| 4190 // stream id | |
| 4191 0x04, 0x03, 0x02, 0x01, | |
| 4192 // offset | |
| 4193 0x54, 0x76, 0x10, 0x32, | |
| 4194 0xDC, 0xFE, 0x98, 0xBA, | |
| 4195 // data | |
| 4196 'h', 'e', 'l', 'l', | |
| 4197 'o', ' ', 'w', 'o', | |
| 4198 'r', 'l', 'd', '!', | |
| 4199 }; | |
| 4200 | |
| 4201 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 4202 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 4203 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 4204 ASSERT_TRUE(visitor_.header_.get()); | |
| 4205 EXPECT_TRUE(visitor_.header_->fec_flag); | |
| 4206 EXPECT_TRUE(visitor_.header_->entropy_flag); | |
| 4207 EXPECT_EQ(1 << 4, visitor_.header_->entropy_hash); | |
| 4208 }; | |
| 4209 | |
| 4210 TEST_P(QuicFramerTest, StopPacketProcessing) { | |
| 4211 unsigned char packet[] = { | |
| 4212 // public flags (8 byte connection_id) | |
| 4213 0x3C, | |
| 4214 // connection_id | |
| 4215 0x10, 0x32, 0x54, 0x76, | |
| 4216 0x98, 0xBA, 0xDC, 0xFE, | |
| 4217 // packet sequence number | |
| 4218 0xBC, 0x9A, 0x78, 0x56, | |
| 4219 0x34, 0x12, | |
| 4220 // Entropy | |
| 4221 0x01, | |
| 4222 | |
| 4223 // frame type (stream frame with fin) | |
| 4224 0xFF, | |
| 4225 // stream id | |
| 4226 0x04, 0x03, 0x02, 0x01, | |
| 4227 // offset | |
| 4228 0x54, 0x76, 0x10, 0x32, | |
| 4229 0xDC, 0xFE, 0x98, 0xBA, | |
| 4230 // data length | |
| 4231 0x0c, 0x00, | |
| 4232 // data | |
| 4233 'h', 'e', 'l', 'l', | |
| 4234 'o', ' ', 'w', 'o', | |
| 4235 'r', 'l', 'd', '!', | |
| 4236 | |
| 4237 // frame type (ack frame) | |
| 4238 0x40, | |
| 4239 // entropy hash of sent packets till least awaiting - 1. | |
| 4240 0x14, | |
| 4241 // least packet sequence number awaiting an ack | |
| 4242 0xA0, 0x9A, 0x78, 0x56, | |
| 4243 0x34, 0x12, | |
| 4244 // entropy hash of all received packets. | |
| 4245 0x43, | |
| 4246 // largest observed packet sequence number | |
| 4247 0xBF, 0x9A, 0x78, 0x56, | |
| 4248 0x34, 0x12, | |
| 4249 // num missing packets | |
| 4250 0x01, | |
| 4251 // missing packet | |
| 4252 0xBE, 0x9A, 0x78, 0x56, | |
| 4253 0x34, 0x12, | |
| 4254 }; | |
| 4255 | |
| 4256 MockFramerVisitor visitor; | |
| 4257 framer_.set_visitor(&visitor); | |
| 4258 EXPECT_CALL(visitor, OnPacket()); | |
| 4259 EXPECT_CALL(visitor, OnPacketHeader(_)); | |
| 4260 EXPECT_CALL(visitor, OnStreamFrame(_)).WillOnce(Return(false)); | |
| 4261 EXPECT_CALL(visitor, OnAckFrame(_)).Times(0); | |
| 4262 EXPECT_CALL(visitor, OnPacketComplete()); | |
| 4263 EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)).WillOnce(Return(true)); | |
| 4264 | |
| 4265 QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); | |
| 4266 EXPECT_TRUE(framer_.ProcessPacket(encrypted)); | |
| 4267 EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); | |
| 4268 } | |
| 4269 | |
| 4270 } // namespace test | |
| 4271 } // namespace net | |
| OLD | NEW |