15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_framer.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/port.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_decrypter.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_encrypter.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_protocol.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_utils.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/quic_framer_peer.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/test/gtest_util.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::hash_set;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::make_pair;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::map;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::numeric_limits;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using std::pair;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector;
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::Return;
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::_;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const QuicPacketSequenceNumber kEpoch = GG_UINT64_C(1) << 48;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const QuicPacketSequenceNumber kMask = kEpoch - 1;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Index into the connection_id offset in the header.
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const size_t kConnectionIdOffset = kPublicFlagsSize;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Index into the version string in the header. (if present).
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const size_t kVersionOffset = kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Size in bytes of the stream frame fields for an arbitrary StreamID and
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// offset and the last frame in a packet.
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)size_t GetMinStreamFrameSize() {
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Index into the sequence number offset in the header.
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t GetSequenceNumberOffset(QuicConnectionIdLength connection_id_length,
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               bool include_version) {
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return kConnectionIdOffset + connection_id_length +
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (include_version ? kQuicVersionSize : 0);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t GetSequenceNumberOffset(bool include_version) {
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetSequenceNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Index into the private flags offset in the data packet header.
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t GetPrivateFlagsOffset(QuicConnectionIdLength connection_id_length,
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             bool include_version) {
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetSequenceNumberOffset(connection_id_length, include_version) +
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER;
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t GetPrivateFlagsOffset(bool include_version) {
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t GetPrivateFlagsOffset(bool include_version,
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             QuicSequenceNumberLength sequence_number_length) {
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetSequenceNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sequence_number_length;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Index into the fec group offset in the header.
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t GetFecGroupOffset(QuicConnectionIdLength connection_id_length,
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         bool include_version) {
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetPrivateFlagsOffset(connection_id_length, include_version) +
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kPrivateFlagsSize;
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t GetFecGroupOffset(bool include_version) {
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kPrivateFlagsSize;
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t GetFecGroupOffset(bool include_version,
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                         QuicSequenceNumberLength sequence_number_length) {
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetPrivateFlagsOffset(include_version, sequence_number_length) +
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kPrivateFlagsSize;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Index into the message tag of the public reset packet.
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Public resets always have full connection_ids.
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const size_t kPublicResetPacketMessageTagOffset =
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID;
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestEncrypter : public QuicEncrypter {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestEncrypter() {}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SetKey(StringPiece key) OVERRIDE {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SetNoncePrefix(StringPiece nonce_prefix) OVERRIDE {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool Encrypt(StringPiece nonce,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       StringPiece associated_data,
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       StringPiece plaintext,
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       unsigned char* output) OVERRIDE {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(false) << "Not implemented";
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual QuicData* EncryptPacket(QuicPacketSequenceNumber sequence_number,
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  StringPiece associated_data,
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  StringPiece plaintext) OVERRIDE {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence_number_ = sequence_number;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    associated_data_ = associated_data.as_string();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    plaintext_ = plaintext.as_string();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new QuicData(plaintext.data(), plaintext.length());
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t GetKeySize() const OVERRIDE {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t GetNoncePrefixSize() const OVERRIDE {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) const OVERRIDE {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ciphertext_size;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t GetCiphertextSize(size_t plaintext_size) const OVERRIDE {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return plaintext_size;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual StringPiece GetKey() const OVERRIDE {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return StringPiece();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual StringPiece GetNoncePrefix() const OVERRIDE {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return StringPiece();
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketSequenceNumber sequence_number_;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string associated_data_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string plaintext_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestDecrypter : public QuicDecrypter {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestDecrypter() {}
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SetKey(StringPiece key) OVERRIDE {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SetNoncePrefix(StringPiece nonce_prefix) OVERRIDE {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool Decrypt(StringPiece nonce,
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       StringPiece associated_data,
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       StringPiece ciphertext,
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       unsigned char* output,
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       size_t* output_length) OVERRIDE {
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(false) << "Not implemented";
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual QuicData* DecryptPacket(QuicPacketSequenceNumber sequence_number,
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  StringPiece associated_data,
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  StringPiece ciphertext) OVERRIDE {
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence_number_ = sequence_number;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    associated_data_ = associated_data.as_string();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ciphertext_ = ciphertext.as_string();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new QuicData(ciphertext.data(), ciphertext.length());
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual StringPiece GetKey() const OVERRIDE {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return StringPiece();
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual StringPiece GetNoncePrefix() const OVERRIDE {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return StringPiece();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketSequenceNumber sequence_number_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string associated_data_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string ciphertext_;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestQuicVisitor : public ::net::QuicFramerVisitorInterface {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuicVisitor()
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : error_count_(0),
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        version_mismatch_(0),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        packet_count_(0),
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frame_count_(0),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fec_count_(0),
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        complete_packets_(0),
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        revived_packets_(0),
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        accept_packet_(true),
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        accept_public_header_(true) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TestQuicVisitor() {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STLDeleteElements(&stream_frames_);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STLDeleteElements(&ack_frames_);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    STLDeleteElements(&congestion_feedback_frames_);
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    STLDeleteElements(&stop_waiting_frames_);
2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    STLDeleteElements(&ping_frames_);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STLDeleteElements(&fec_data_);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnError(QuicFramer* f) OVERRIDE {
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1) << "QuicFramer Error: " << QuicUtils::ErrorToString(f->error())
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             << " (" << f->error() << ")";
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++error_count_;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnPacket() OVERRIDE {}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnPublicResetPacket(
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const QuicPublicResetPacket& packet) OVERRIDE {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public_reset_packet_.reset(new QuicPublicResetPacket(packet));
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnVersionNegotiationPacket(
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const QuicVersionNegotiationPacket& packet) OVERRIDE {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnRevivedPacket() OVERRIDE {
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++revived_packets_;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE {
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1) << "QuicFramer Version Mismatch, version: " << version;
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++version_mismatch_;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool OnUnauthenticatedPublicHeader(
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const QuicPacketPublicHeader& header) OVERRIDE {
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public_header_.reset(new QuicPacketPublicHeader(header));
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return accept_public_header_;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual bool OnUnauthenticatedHeader(
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const QuicPacketHeader& header) OVERRIDE {
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void OnDecryptedPacket(EncryptionLevel level) OVERRIDE {}
250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE {
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++packet_count_;
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    header_.reset(new QuicPacketHeader(header));
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return accept_packet_;
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE {
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++frame_count_;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stream_frames_.push_back(new QuicStreamFrame(frame));
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnFecProtectedPayload(StringPiece payload) OVERRIDE {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_protected_payload_ = payload.as_string();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnAckFrame(const QuicAckFrame& frame) OVERRIDE {
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++frame_count_;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ack_frames_.push_back(new QuicAckFrame(frame));
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnCongestionFeedbackFrame(
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const QuicCongestionFeedbackFrame& frame) OVERRIDE {
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++frame_count_;
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    congestion_feedback_frames_.push_back(
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new QuicCongestionFeedbackFrame(frame));
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) OVERRIDE {
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++frame_count_;
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    stop_waiting_frames_.push_back(new QuicStopWaitingFrame(frame));
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return true;
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual bool OnPingFrame(const QuicPingFrame& frame) OVERRIDE {
2880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ++frame_count_;
2890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ping_frames_.push_back(new QuicPingFrame(frame));
2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return true;
2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnFecData(const QuicFecData& fec) OVERRIDE {
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++fec_count_;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_data_.push_back(new QuicFecData(fec));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnPacketComplete() OVERRIDE {
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++complete_packets_;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) OVERRIDE {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rst_stream_frame_ = frame;
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnConnectionCloseFrame(
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const QuicConnectionCloseFrame& frame) OVERRIDE {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    connection_close_frame_ = frame;
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) OVERRIDE {
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    goaway_frame_ = frame;
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame)
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OVERRIDE {
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window_update_frame_ = frame;
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) OVERRIDE {
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blocked_frame_ = frame;
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Counters from the visitor_ callbacks.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error_count_;
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int version_mismatch_;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int packet_count_;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int frame_count_;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fec_count_;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int complete_packets_;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int revived_packets_;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool accept_packet_;
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool accept_public_header_;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<QuicPacketHeader> header_;
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<QuicPacketPublicHeader> public_header_;
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicPublicResetPacket> public_reset_packet_;
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<QuicStreamFrame*> stream_frames_;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<QuicAckFrame*> ack_frames_;
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vector<QuicCongestionFeedbackFrame*> congestion_feedback_frames_;
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  vector<QuicStopWaitingFrame*> stop_waiting_frames_;
3480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  vector<QuicPingFrame*> ping_frames_;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<QuicFecData*> fec_data_;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string fec_protected_payload_;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicRstStreamFrame rst_stream_frame_;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicConnectionCloseFrame connection_close_frame_;
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicGoAwayFrame goaway_frame_;
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicWindowUpdateFrame window_update_frame_;
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicBlockedFrame blocked_frame_;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
358558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFramerTest()
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : encrypter_(new test::TestEncrypter()),
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        decrypter_(new test::TestDecrypter()),
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        start_(QuicTime::Zero().Add(QuicTime::Delta::FromMicroseconds(0x10))),
3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        framer_(QuicSupportedVersions(), start_, true) {
3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    version_ = GetParam();
3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    framer_.set_version(version_);
3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    framer_.SetDecrypter(decrypter_, ENCRYPTION_NONE);
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer_.set_visitor(&visitor_);
370558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    framer_.set_received_entropy_calculator(&entropy_calculator_);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Helper function to get unsigned char representation of digit in the
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // units place of the current QUIC version number.
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  unsigned char GetQuicVersionDigitOnes() {
37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return static_cast<unsigned char> ('0' + version_%10);
37758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
37858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Helper function to get unsigned char representation of digit in the
38058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // tens place of the current QUIC version number.
38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  unsigned char GetQuicVersionDigitTens() {
38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return static_cast<unsigned char> ('0' + (version_/10)%10);
38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CheckEncryption(QuicPacketSequenceNumber sequence_number,
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       QuicPacket* packet) {
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (sequence_number != encrypter_->sequence_number_) {
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Encrypted incorrect packet sequence number.  expected "
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << sequence_number << " actual: "
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << encrypter_->sequence_number_;
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (packet->AssociatedData() != encrypter_->associated_data_) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Encrypted incorrect associated data.  expected "
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << packet->AssociatedData() << " actual: "
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << encrypter_->associated_data_;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (packet->Plaintext() != encrypter_->plaintext_) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Encrypted incorrect plaintext data.  expected "
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << packet->Plaintext() << " actual: "
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << encrypter_->plaintext_;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CheckDecryption(const QuicEncryptedPacket& encrypted,
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       bool includes_version) {
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (visitor_.header_->packet_sequence_number !=
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        decrypter_->sequence_number_) {
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Decrypted incorrect packet sequence number.  expected "
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << visitor_.header_->packet_sequence_number << " actual: "
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << decrypter_->sequence_number_;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (QuicFramer::GetAssociatedDataFromEncryptedPacket(
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            encrypted, PACKET_8BYTE_CONNECTION_ID,
419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            includes_version, PACKET_6BYTE_SEQUENCE_NUMBER) !=
420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        decrypter_->associated_data_) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Decrypted incorrect associated data.  expected "
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << QuicFramer::GetAssociatedDataFromEncryptedPacket(
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     encrypted, PACKET_8BYTE_CONNECTION_ID,
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     includes_version, PACKET_6BYTE_SEQUENCE_NUMBER)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << " actual: " << decrypter_->associated_data_;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StringPiece ciphertext(encrypted.AsStringPiece().substr(
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        GetStartOfEncryptedData(PACKET_8BYTE_CONNECTION_ID, includes_version,
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER)));
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (ciphertext != decrypter_->ciphertext_) {
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      LOG(ERROR) << "Decrypted incorrect ciphertext data.  expected "
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << ciphertext << " actual: "
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << decrypter_->ciphertext_;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* AsChars(unsigned char* data) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<char*>(data);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckProcessingFails(unsigned char* packet,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            size_t len,
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            string expected_error,
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            QuicErrorCode error_code) {
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicEncryptedPacket encrypted(AsChars(packet), len, false);
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Checks if the supplied string matches data in the supplied StreamFrame.
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void CheckStreamFrameData(string str, QuicStreamFrame* frame) {
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<string> frame_data(frame->GetDataAsString());
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(str, *frame_data);
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void CheckStreamFrameBoundaries(unsigned char* packet,
4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  size_t stream_id_size,
4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  bool include_version) {
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Now test framing boundaries.
4646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    for (size_t i = kQuicFrameTypeSize; i < GetMinStreamFrameSize(); ++i) {
4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      string expected_error;
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (i < kQuicFrameTypeSize + stream_id_size) {
4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        expected_error = "Unable to read stream_id.";
4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      } else if (i < kQuicFrameTypeSize + stream_id_size +
4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                 kQuicMaxStreamOffsetSize) {
4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        expected_error = "Unable to read offset.";
4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      } else {
4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        expected_error = "Unable to read frame data.";
4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CheckProcessingFails(
4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          packet,
476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, include_version,
4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  PACKET_6BYTE_SEQUENCE_NUMBER,
4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  NOT_IN_FEC_GROUP),
4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          expected_error, QUIC_INVALID_STREAM_DATA);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckCalculatePacketSequenceNumber(
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      QuicPacketSequenceNumber expected_sequence_number,
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      QuicPacketSequenceNumber last_sequence_number) {
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicPacketSequenceNumber wire_sequence_number =
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        expected_sequence_number & kMask;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicFramerPeer::SetLastSequenceNumber(&framer_, last_sequence_number);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_sequence_number,
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              QuicFramerPeer::CalculatePacketSequenceNumberFromWire(
491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                  &framer_, PACKET_6BYTE_SEQUENCE_NUMBER, wire_sequence_number))
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "last_sequence_number: " << last_sequence_number
493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        << " wire_sequence_number: " << wire_sequence_number;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  QuicPacket* BuildDataPacket(const QuicPacketHeader& header,
49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              const QuicFrames& frames) {
49846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return BuildUnsizedDataPacket(&framer_, header, frames).packet;
49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
50046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::TestEncrypter* encrypter_;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::TestDecrypter* decrypter_;
5032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicVersion version_;
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicTime start_;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFramer framer_;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::TestQuicVisitor visitor_;
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test::TestEntropyCalculator entropy_calculator_;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
510c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch// Run all framer tests with all supported versions of QUIC.
511558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochINSTANTIATE_TEST_CASE_P(QuicFramerTests,
512558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        QuicFramerTest,
513c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                        ::testing::ValuesIn(kSupportedQuicVersions));
514558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
515558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochStart) {
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A few quick manual sanity checks
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckCalculatePacketSequenceNumber(GG_UINT64_C(1), GG_UINT64_C(0));
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckCalculatePacketSequenceNumber(kEpoch + 1, kMask);
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckCalculatePacketSequenceNumber(kEpoch, kMask);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cases where the last number was close to the start of the range
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint64 last = 0; last < 10; last++) {
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Small numbers should not wrap (even if they're out of order).
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(j, last);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Large numbers should not wrap either (because we're near 0 already).
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(kEpoch - 1 - j, last);
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
535558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochEnd) {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cases where the last number was close to the end of the range
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint64 i = 0; i < 10; i++) {
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicPacketSequenceNumber last = kEpoch - i;
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Small numbers should wrap.
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(kEpoch + j, last);
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Large numbers should not (even if they're out of order).
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(kEpoch - 1 - j, last);
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Next check where we're in a non-zero epoch to verify we handle
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// reverse wrapping, too.
554558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearPrevEpoch) {
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 prev_epoch = 1 * kEpoch;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 cur_epoch = 2 * kEpoch;
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cases where the last number was close to the start of the range
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint64 i = 0; i < 10; i++) {
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint64 last = cur_epoch + i;
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Small number should not wrap (even if they're out of order).
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(cur_epoch + j, last);
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // But large numbers should reverse wrap.
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uint64 num = kEpoch - 1 - j;
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(prev_epoch + num, last);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
573558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextEpoch) {
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 cur_epoch = 2 * kEpoch;
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 next_epoch = 3 * kEpoch;
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cases where the last number was close to the end of the range
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint64 i = 0; i < 10; i++) {
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicPacketSequenceNumber last = next_epoch - 1 - i;
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Small numbers should wrap.
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(next_epoch + j, last);
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // but large numbers should not (even if they're out of order).
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uint64 num = kEpoch - 1 - j;
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(cur_epoch + num, last);
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
593558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextMax) {
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 max_number = numeric_limits<uint64>::max();
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 max_epoch = max_number & ~kMask;
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cases where the last number was close to the end of the range
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint64 i = 0; i < 10; i++) {
599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Subtract 1, because the expected next sequence number is 1 more than the
600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // last sequence number.
601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicPacketSequenceNumber last = max_number - i - 1;
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Small numbers should not wrap, because they have nowhere to go.
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(max_epoch + j, last);
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Large numbers should not wrap either.
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint64 j = 0; j < 10; j++) {
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uint64 num = kEpoch - 1 - j;
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CheckCalculatePacketSequenceNumber(max_epoch + num, last);
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
616558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, EmptyPacket) {
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char packet[] = { 0x00 };
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicEncryptedPacket encrypted(packet, 0, false);
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
623558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, LargePacket) {
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[kMaxPacketSize + 1] = {
625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  memset(packet + GetPacketHeaderSize(
638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)             PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), 0,
640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)         kMaxPacketSize - GetPacketHeaderSize(
641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)             PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP) + 1);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we've parsed the packet header, so we can send an error.
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure the correct error is propagated.
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(QUIC_PACKET_TOO_LARGE, framer_.error());
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, PacketHeader) {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.version_flag);
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(visitor_.header_->fec_flag);
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(visitor_.header_->entropy_flag);
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, visitor_.header_->entropy_hash);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            visitor_.header_->packet_sequence_number);
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0;
687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++i) {
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string expected_error;
691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read public flags.";
69390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (i < GetPrivateFlagsOffset(!kIncludeVersion)) {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_error = "Unable to read sequence number.";
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (i < GetFecGroupOffset(!kIncludeVersion)) {
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read private flags.";
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read first fec protected packet offset.";
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) {
707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicFramerPeer::SetLastSerializedConnectionId(
708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &framer_, GG_UINT64_C(0xFEDCBA9876543210));
709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[] = {
711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (4 byte connection_id)
712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x38,
713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x34, 0x12,
718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
7243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
727a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.version_flag);
730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->fec_flag);
731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->entropy_flag);
732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, visitor_.header_->entropy_hash);
733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            visitor_.header_->packet_sequence_number);
735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0;
740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < GetPacketHeaderSize(PACKET_4BYTE_CONNECTION_ID, !kIncludeVersion,
741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
742868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++i) {
743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    string expected_error;
744a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read public flags.";
746a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetSequenceNumberOffset(PACKET_4BYTE_CONNECTION_ID,
747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           !kIncludeVersion)) {
748a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
749a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetPrivateFlagsOffset(PACKET_4BYTE_CONNECTION_ID,
750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         !kIncludeVersion)) {
751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read sequence number.";
752a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetFecGroupOffset(PACKET_4BYTE_CONNECTION_ID,
753a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     !kIncludeVersion)) {
754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read private flags.";
755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read first fec protected packet offset.";
757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
762a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) {
763a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicFramerPeer::SetLastSerializedConnectionId(
764a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &framer_, GG_UINT64_C(0xFEDCBA9876543210));
765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[] = {
767a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (1 byte connection_id)
768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x34,
769a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10,
771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x34, 0x12,
774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
776868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
7803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.version_flag);
786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->fec_flag);
787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->entropy_flag);
788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, visitor_.header_->entropy_hash);
789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            visitor_.header_->packet_sequence_number);
791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0;
796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < GetPacketHeaderSize(PACKET_1BYTE_CONNECTION_ID, !kIncludeVersion,
797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++i) {
799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    string expected_error;
800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read public flags.";
802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetSequenceNumberOffset(PACKET_1BYTE_CONNECTION_ID,
803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           !kIncludeVersion)) {
804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetPrivateFlagsOffset(PACKET_1BYTE_CONNECTION_ID,
806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         !kIncludeVersion)) {
807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read sequence number.";
808a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetFecGroupOffset(PACKET_1BYTE_CONNECTION_ID,
809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     !kIncludeVersion)) {
810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read private flags.";
811868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read first fec protected packet offset.";
813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
818a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
819a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicFramerPeer::SetLastSerializedConnectionId(
820a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &framer_, GG_UINT64_C(0xFEDCBA9876543210));
821868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[] = {
823a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (0 byte connection_id)
824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x30,
825a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x34, 0x12,
829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
830868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
834868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
8353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
839868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.version_flag);
841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->fec_flag);
842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->entropy_flag);
843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, visitor_.header_->entropy_hash);
844868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            visitor_.header_->packet_sequence_number);
846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
850868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0;
851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < GetPacketHeaderSize(PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
853868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++i) {
854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    string expected_error;
855a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read public flags.";
857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetSequenceNumberOffset(PACKET_0BYTE_CONNECTION_ID,
858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           !kIncludeVersion)) {
859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
860a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetPrivateFlagsOffset(PACKET_0BYTE_CONNECTION_ID,
861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         !kIncludeVersion)) {
862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read sequence number.";
863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < GetFecGroupOffset(PACKET_0BYTE_CONNECTION_ID,
864a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     !kIncludeVersion)) {
865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read private flags.";
866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read first fec protected packet offset.";
868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
873558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
87590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // public flags (version)
876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3D,
877a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // version tag
88158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
8913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
894a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(visitor_.header_->public_header.version_flag);
8973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]);
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(visitor_.header_->fec_flag);
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(visitor_.header_->entropy_flag);
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, visitor_.header_->entropy_hash);
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            visitor_.header_->packet_sequence_number);
903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0;
908a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++i) {
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string expected_error;
912a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read public flags.";
91490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else if (i < kVersionOffset) {
915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (i <  GetSequenceNumberOffset(kIncludeVersion)) {
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read protocol version.";
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (i < GetPrivateFlagsOffset(kIncludeVersion)) {
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read sequence number.";
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (i < GetFecGroupOffset(kIncludeVersion)) {
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read private flags.";
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read first fec protected packet offset.";
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
929558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) {
930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicFramerPeer::SetLastSequenceNumber(&framer_,
931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        GG_UINT64_C(0x123456789ABA));
932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[] = {
934a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id and 4 byte sequence number)
935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x2C,
936a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
9473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
950a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.version_flag);
953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->fec_flag);
954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->entropy_flag);
955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, visitor_.header_->entropy_hash);
956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            visitor_.header_->packet_sequence_number);
958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0;
963a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++i) {
966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    string expected_error;
967a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read public flags.";
969868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
970a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         PACKET_4BYTE_SEQUENCE_NUMBER)) {
973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read sequence number.";
974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetFecGroupOffset(!kIncludeVersion,
975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     PACKET_4BYTE_SEQUENCE_NUMBER)) {
976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read private flags.";
977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read first fec protected packet offset.";
979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
980868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
981868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
982868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
983868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
984558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) {
985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicFramerPeer::SetLastSequenceNumber(&framer_,
986868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        GG_UINT64_C(0x123456789ABA));
987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
988868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[] = {
989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id and 2 byte sequence number)
990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x1C,
991a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A,
996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
1001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
10023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
1003868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
1004868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
1005a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
1006868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
1007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.version_flag);
1008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->fec_flag);
1009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->entropy_flag);
1010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, visitor_.header_->entropy_hash);
1011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
1012868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            visitor_.header_->packet_sequence_number);
1013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
1014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
1015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
1017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0;
1018a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
1019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
1020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++i) {
1021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    string expected_error;
1022a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
1023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read public flags.";
1024868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
1025a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
1027868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         PACKET_2BYTE_SEQUENCE_NUMBER)) {
1028868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read sequence number.";
1029868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetFecGroupOffset(!kIncludeVersion,
1030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     PACKET_2BYTE_SEQUENCE_NUMBER)) {
1031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read private flags.";
1032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
1033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read first fec protected packet offset.";
1034868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
1036868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1037868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1038868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1039558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) {
1040868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicFramerPeer::SetLastSequenceNumber(&framer_,
1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        GG_UINT64_C(0x123456789ABA));
1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[] = {
1044a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id and 1 byte sequence number)
1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x0C,
1046a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
1047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
1048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
1049868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
1050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC,
1051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
1052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
1053868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
1054868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
1056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
10573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
1058868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
1059868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
1060a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
1061868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
1062868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->public_header.version_flag);
1063868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->fec_flag);
1064868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(visitor_.header_->entropy_flag);
1065868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, visitor_.header_->entropy_hash);
1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            visitor_.header_->packet_sequence_number);
1068868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
1069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
1072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0;
1073a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
1075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++i) {
1076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    string expected_error;
1077a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
1078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read public flags.";
1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
1080a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
1081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
1082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         PACKET_1BYTE_SEQUENCE_NUMBER)) {
1083868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read sequence number.";
1084868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (i < GetFecGroupOffset(!kIncludeVersion,
1085868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     PACKET_1BYTE_SEQUENCE_NUMBER)) {
1086868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read private flags.";
1087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
1088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      expected_error = "Unable to read first fec protected packet offset.";
1089868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
1091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1092868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1093868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1094558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, InvalidPublicFlag) {
1095868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[] = {
1096e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // public flags: all flags set but the public reset flag and version flag.
1097e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    0xFC,
1098a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
1099868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
1100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
1101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
1102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
1103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x34, 0x12,
1104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
1105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
1106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
110758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // frame type (padding)
11081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
110958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00
1110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
1111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckProcessingFails(packet,
1112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       arraysize(packet),
1113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       "Illegal public flags value.",
1114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       QUIC_INVALID_PACKET_HEADER);
1115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Now turn off validation.
1117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  framer_.set_validate_flags(false);
1118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
1119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
1120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) {
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
1124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id and version flag and an unknown flag)
1125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x4D,
1126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
1129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // version tag
113058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x34, 0x12,
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // frame type (padding)
11381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
113958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckProcessingFails(packet,
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       arraysize(packet),
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       "Illegal public flags value.",
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       QUIC_INVALID_PACKET_HEADER);
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1147558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[] = {
1149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id, version flag and an unknown flag)
1150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x7D,
1151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
1153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // version tag
1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    'Q', '0', '0', '0',
1156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
1157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x34, 0x12,
1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
1161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // frame type (padding frame)
11631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
116458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00
1165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
1167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
1168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
1169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
1170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, visitor_.frame_count_);
1171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, visitor_.version_mismatch_);
1172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
1173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1174558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, InvalidPrivateFlag) {
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
1176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
1177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
1178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
1185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10,
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // frame type (padding)
11881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
118958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckProcessingFails(packet,
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       arraysize(packet),
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       "Illegal private flags value.",
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       QUIC_INVALID_PACKET_HEADER);
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, InvalidFECGroupOffset) {
11982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
1199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
12002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
1201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
12022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
12032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
12042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
12052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x01, 0x00, 0x00, 0x00,
12062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x00, 0x00,
12072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags (fec group)
12082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x02,
12092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // first fec protected packet offset
12102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10
12112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
12122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CheckProcessingFails(packet,
12132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                       arraysize(packet),
12142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                       "First fec protected packet offset must be less "
12152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                       "than the sequence number.",
12162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                       QUIC_INVALID_PACKET_HEADER);
12172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch};
12182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1219558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, PaddingFrame) {
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
1221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
1222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
1223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x34, 0x12,
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00,
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // frame type (padding frame)
12331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ignored data (which in this case is a stream frame)
123558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // frame type (stream frame with fin)
12361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFF,
123758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // stream id
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
123958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // offset
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x54, 0x76, 0x10, 0x32,
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xDC, 0xFE, 0x98, 0xBA,
124258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // data length
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x0c, 0x00,
124458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // data
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'h',  'e',  'l',  'l',
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'o',  ' ',  'w',  'o',
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'r',  'l',  'd',  '!',
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, visitor_.stream_frames_.size());
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.ack_frames_.size());
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A packet with no frames is not acceptable.
1259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CheckProcessingFails(
1260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      packet,
1261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
1262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                          PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
12633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      "Packet has no frames.", QUIC_MISSING_PAYLOAD);
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, StreamFrame) {
12672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
1268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
12692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
1270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
12712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
12722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
12732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
12742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
12752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
12762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags
12772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x00,
12782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
12792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
12801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFF,
12812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
12822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04, 0x03, 0x02, 0x01,
12832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
12842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
12852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
12862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data length
12872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x0c, 0x00,
12882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
12892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
12902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
12912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
12922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
12932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
12942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
12952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
12962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
12972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
12982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
12992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
13002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_EQ(1u, visitor_.stream_frames_.size());
13022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(0u, visitor_.ack_frames_.size());
13032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(static_cast<uint64>(0x01020304),
13042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->stream_id);
13052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
13062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
13072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->offset);
1308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
13092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
13113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, !kIncludeVersion);
13122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
13132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
13152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
1316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
13172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
1318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
13192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
13202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
13212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
13222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
13232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
13242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags
13252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x00,
13262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
13281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFE,
13292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
13302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04, 0x03, 0x02,
13312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
13322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
13332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
13342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data length
13352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x0c, 0x00,
13362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
13372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
13382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
13392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
13402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
13412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
13432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
13442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
13462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
13472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
13482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_EQ(1u, visitor_.stream_frames_.size());
13502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(0u, visitor_.ack_frames_.size());
135158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x00020304),
13522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->stream_id);
13532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
13542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
13552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->offset);
1356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
13572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
13592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const size_t stream_id_size = 3;
13603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
13612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
13622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
13642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
1365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
13662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
1367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
13682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
13692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
13702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
13712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
13722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
13732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags
13742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x00,
13752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
13771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFD,
13782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
13792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04, 0x03,
13802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
13812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
13822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
13832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data length
13842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x0c, 0x00,
13852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
13862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
13872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
13882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
13892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
13902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
13922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
13932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
13952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
13962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
13972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_EQ(1u, visitor_.stream_frames_.size());
13992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(0u, visitor_.ack_frames_.size());
14002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(static_cast<uint64>(0x00000304),
14012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->stream_id);
14022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
14032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
14042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->offset);
1405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
14062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
14082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const size_t stream_id_size = 2;
14093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
14102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
14112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
14132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
1414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
14152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
1416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
14172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
14182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
14192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
14202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
14212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
14222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags
14232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x00,
14242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
14261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFC,
14272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
14282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04,
14292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
14302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
14312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
14322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data length
14332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x0c, 0x00,
14342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
14352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
14362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
14372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
14382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
14392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
14412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
14422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
14442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
14452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
14462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_EQ(1u, visitor_.stream_frames_.size());
14482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(0u, visitor_.ack_frames_.size());
14492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(static_cast<uint64>(0x00000004),
14502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->stream_id);
14512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
14522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
14532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->offset);
1454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
14552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
14572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const size_t stream_id_size = 1;
14583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
14592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
14602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, StreamFrameWithVersion) {
14622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
1463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (version, 8 byte connection_id)
14642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3D,
1465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
14662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
14672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
14682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // version tag
146958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
14702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
14712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
14722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
14732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags
14742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x00,
14752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
14771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFF,
14782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
14792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04, 0x03, 0x02, 0x01,
14802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
14812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
14822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
14832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data length
14842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x0c, 0x00,
14852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
14862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
14872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
14882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
14892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
14902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
14922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
14932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
14952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
1496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(visitor_.header_->public_header.version_flag);
1497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]);
14982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion));
14992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
15002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_EQ(1u, visitor_.stream_frames_.size());
15012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(0u, visitor_.ack_frames_.size());
15022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(static_cast<uint64>(0x01020304),
15032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->stream_id);
15042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
15052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
15062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->offset);
1507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
15082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
15091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
15103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, kIncludeVersion);
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1513558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, RejectPacket) {
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visitor_.accept_packet_ = false;
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
1517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
1518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
1519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
15291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFF,
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // stream id
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // offset
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x54, 0x76, 0x10, 0x32,
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xDC, 0xFE, 0x98, 0xBA,
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // data length
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x0c, 0x00,
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // data
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'h',  'e',  'l',  'l',
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'o',  ' ',  'w',  'o',
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'r',  'l',  'd',  '!',
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(0u, visitor_.stream_frames_.size());
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, visitor_.ack_frames_.size());
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, RejectPublicHeader) {
15555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  visitor_.accept_public_header_ = false;
15565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
1558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
15595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
1560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
15615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
15625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
15635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
15645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
15665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
15675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
15695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(visitor_.public_header_.get());
15705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(visitor_.header_.get());
15715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
15725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1573558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, RevivedStreamFrame) {
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char payload[] = {
15752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
15761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFF,
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // stream id
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // offset
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x54, 0x76, 0x10, 0x32,
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xDC, 0xFE, 0x98, 0xBA,
15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // data length
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x0c, 0x00,
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // data
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'h',  'e',  'l',  'l',
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'o',  ' ',  'w',  'o',
15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'r',  'l',  'd',  '!',
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketHeader header;
1591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.reset_flag = false;
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.version_flag = false;
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_flag = true;
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.entropy_flag = true;
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_group = 0;
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Do not encrypt the payload because the revived payload is post-encryption.
16002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessRevivedPacket(&header,
16012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                           StringPiece(AsChars(payload),
16022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                                       arraysize(payload))));
16032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
16042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
16052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_EQ(1, visitor_.revived_packets_);
16062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
16072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
1608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.header_->public_header.connection_id);
16092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
16102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_FALSE(visitor_.header_->public_header.version_flag);
16112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.header_->fec_flag);
16122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.header_->entropy_flag);
16132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(1 << (header.packet_sequence_number % 8),
16142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.header_->entropy_hash);
16152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
16162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.header_->packet_sequence_number);
16172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
16182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(0x00u, visitor_.header_->fec_group);
16192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
16202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_EQ(1u, visitor_.stream_frames_.size());
16212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(0u, visitor_.ack_frames_.size());
16222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.stream_frames_[0]->stream_id);
16232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
16242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
16252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            visitor_.stream_frames_[0]->offset);
1626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
16272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1629558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, StreamFrameInFecGroup) {
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
1631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
1632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
1633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x12, 0x34,
1639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags (fec group)
1640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x02,
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // first fec protected packet offset
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x02,
16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
16451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFF,
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // stream id
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // offset
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x54, 0x76, 0x10, 0x32,
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xDC, 0xFE, 0x98, 0xBA,
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // data length
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x0c, 0x00,
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // data
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'h',  'e',  'l',  'l',
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'o',  ' ',  'w',  'o',
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'r',  'l',  'd',  '!',
16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
1665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x341256789ABA),
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            visitor_.header_->fec_group);
1668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t fec_offset =
1669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetStartOfFecProtectedData(PACKET_8BYTE_CONNECTION_ID,
1670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 !kIncludeVersion,
1671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 PACKET_6BYTE_SEQUENCE_NUMBER);
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(
1673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      string(AsChars(packet) + fec_offset, arraysize(packet) - fec_offset),
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      visitor_.fec_protected_payload_);
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, visitor_.stream_frames_.size());
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, visitor_.ack_frames_.size());
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.stream_frames_[0]->stream_id);
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            visitor_.stream_frames_[0]->offset);
1682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, AckFramev22) {
16861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ > QUIC_VERSION_22) {
16871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
16881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
16891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
16901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
16911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
16921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
16931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
16941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
16951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
16961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
16971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
16981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
16991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
17001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
17021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
17031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x6C,
17041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets.
17051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBA,
17061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // largest observed packet sequence number
17071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBF, 0x9A, 0x78, 0x56,
17081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
17091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
17101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
17111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num missing packets
17121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
17131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // missing packet delta
17141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
17151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 0 more missing packets in range.
17161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
17171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of revived packets.
17181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
17191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
17201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
17221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
17231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
17251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(visitor_.header_.get());
17261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
17271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, visitor_.stream_frames_.size());
17291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, visitor_.ack_frames_.size());
17301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
17311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0xBA, frame.entropy_hash);
17321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
17331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, frame.missing_packets.size());
17341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SequenceNumberSet::const_iterator missing_iter =
17351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      frame.missing_packets.begin();
17361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
17371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
17391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
17401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicEntropyHashSize;
17411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
17421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_6BYTE_SEQUENCE_NUMBER;
17431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumMissingPacketOffset = kMissingDeltaTimeOffset +
17441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicDeltaTimeLargestObservedSize;
17451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
17461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kNumberOfNackRangesSize;
17471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingPacketsRange = kMissingPacketsOffset +
17481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
17491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kRevivedPacketsLength = kMissingPacketsRange +
17501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
17511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
17521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t ack_frame_size = kRevivedPacketsLength +
17531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
17541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
17551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    string expected_error;
17561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (i < kLargestObservedOffset) {
17571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read entropy hash for received packets.";
17581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingDeltaTimeOffset) {
17591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read largest observed.";
17601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumMissingPacketOffset) {
17611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read delta time largest observed.";
17621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingPacketsOffset) {
17631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num missing packet ranges.";
17641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingPacketsRange) {
17651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read missing sequence number delta.";
17661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kRevivedPacketsLength) {
17671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read missing sequence number range.";
17681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
17691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num revived packets.";
17701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
17711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CheckProcessingFails(
17721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        packet,
17731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
17741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
17751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        expected_error, QUIC_INVALID_ACK_DATA);
17761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
17771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
17781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, AckFrameTwoTimestamp) {
17811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
17821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
17831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
17841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
17851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
17861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
17871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
17881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
17891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
17901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
17911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
17921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
17931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
17941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
17951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
17971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
17981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x6C,
17991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets.
18001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBA,
18011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // largest observed packet sequence number
18021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBF, 0x9A, 0x78, 0x56,
18031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
18041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
18051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
18061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of timestamps.
18071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x02,
18081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Delta from largest observed.
18091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
18101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Delta time.
18111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
18121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Delta from largest observed.
18131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x02,
18141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Delta time.
18151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32,
18161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num missing packets
18171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
18181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // missing packet delta
18191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
18201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 0 more missing packets in range.
18211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
18221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of revived packets.
18231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
18241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
18251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
18271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
18281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
18301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(visitor_.header_.get());
18311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
18321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, visitor_.stream_frames_.size());
18341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, visitor_.ack_frames_.size());
18351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
18361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0xBA, frame.entropy_hash);
18371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
18381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, frame.missing_packets.size());
18391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(2u, frame.received_packet_times.size());
18401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SequenceNumberSet::const_iterator missing_iter =
18411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      frame.missing_packets.begin();
18421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
18431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
18451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
18461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicEntropyHashSize;
18471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
18481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_6BYTE_SEQUENCE_NUMBER;
18491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
18501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicDeltaTimeLargestObservedSize;
18511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kTimestampDeltaLargestObserved1 = kNumTimestampsOffset +
18521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicNumTimestampsSize;
18531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kTimestampTimeDeltaLargestObserved1 =
18541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kTimestampDeltaLargestObserved1 + 1;
18551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kTimestampDeltaLargestObserved2 =
18561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kTimestampTimeDeltaLargestObserved1 + 4;
18571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kTimestampTimeDeltaLargestObserved2 =
18581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kTimestampDeltaLargestObserved2 + 1;
18591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumMissingPacketOffset =
18601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kTimestampTimeDeltaLargestObserved2 + 2;
18611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
18621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kNumberOfNackRangesSize;
18631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingPacketsRange = kMissingPacketsOffset +
18641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
18651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kRevivedPacketsLength = kMissingPacketsRange +
18661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
18671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
18681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t ack_frame_size = kRevivedPacketsLength +
18691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
18701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
18711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    string expected_error;
18721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (i < kLargestObservedOffset) {
18731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read entropy hash for received packets.";
18741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingDeltaTimeOffset) {
18751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read largest observed.";
18761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumTimestampsOffset) {
18771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read delta time largest observed.";
18781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kTimestampDeltaLargestObserved1) {
18791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num received packets.";
18801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kTimestampTimeDeltaLargestObserved1) {
18811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read sequence delta in received packets.";
18821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kTimestampDeltaLargestObserved2) {
18831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read time delta in received packets.";
18841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kTimestampTimeDeltaLargestObserved2) {
18851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read sequence delta in received packets.";
18861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumMissingPacketOffset) {
18871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error =
18881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "Unable to read incremental time delta in received packets.";
18891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingPacketsOffset) {
18901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num missing packet ranges.";
18911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingPacketsRange) {
18921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read missing sequence number delta.";
18931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kRevivedPacketsLength) {
18941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read missing sequence number range.";
18951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
18961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num revived packets.";
18971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
18981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CheckProcessingFails(
18991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        packet,
19001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
19011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
19021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        expected_error, QUIC_INVALID_ACK_DATA);
19031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
19041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
19051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, AckFrameOneTimestamp) {
19081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
19091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
19101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
19111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
19121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
19131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
19141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
19151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
19161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
19171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
19181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
19191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
19201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
19211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
19221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
19241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
19251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x6C,
19261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets.
19271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBA,
19281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // largest observed packet sequence number
19291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBF, 0x9A, 0x78, 0x56,
19301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
19311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
19321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
19331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of timestamps.
19341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
19351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Delta from largest observed.
19361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
19371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Delta time.
19381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
19391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num missing packets
19401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
19411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // missing packet delta
19421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
19431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 0 more missing packets in range.
19441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
19451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of revived packets.
19461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
19471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
19481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
19501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
19511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
19531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(visitor_.header_.get());
19541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
19551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, visitor_.stream_frames_.size());
19571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, visitor_.ack_frames_.size());
19581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
19591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0xBA, frame.entropy_hash);
19601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
19611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, frame.missing_packets.size());
19621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, frame.received_packet_times.size());
19631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SequenceNumberSet::const_iterator missing_iter =
19641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      frame.missing_packets.begin();
19651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
19661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
19681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
19691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicEntropyHashSize;
19701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
19711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_6BYTE_SEQUENCE_NUMBER;
19721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
19731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicDeltaTimeLargestObservedSize;
19741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kTimestampDeltaLargestObserved = kNumTimestampsOffset +
19751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicNumTimestampsSize;
19761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kTimestampTimeDeltaLargestObserved =
19771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    kTimestampDeltaLargestObserved + 1;
19781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumMissingPacketOffset = kTimestampTimeDeltaLargestObserved + 4;
19791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
19801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kNumberOfNackRangesSize;
19811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingPacketsRange = kMissingPacketsOffset +
19821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
19831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kRevivedPacketsLength = kMissingPacketsRange +
19841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
19851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
19861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t ack_frame_size = kRevivedPacketsLength +
19871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
19881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
19891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    string expected_error;
19901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (i < kLargestObservedOffset) {
19911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read entropy hash for received packets.";
19921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingDeltaTimeOffset) {
19931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read largest observed.";
19941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumTimestampsOffset) {
19951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read delta time largest observed.";
19961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kTimestampDeltaLargestObserved) {
19971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num received packets.";
19981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kTimestampTimeDeltaLargestObserved) {
19991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read sequence delta in received packets.";
20001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumMissingPacketOffset) {
20011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read time delta in received packets.";
20021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingPacketsOffset) {
20031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num missing packet ranges.";
20041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingPacketsRange) {
20051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read missing sequence number delta.";
20061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kRevivedPacketsLength) {
20071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read missing sequence number range.";
20081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
20091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num revived packets.";
20101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
20111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CheckProcessingFails(
20121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        packet,
20131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
20141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
20151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        expected_error, QUIC_INVALID_ACK_DATA);
20161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
20171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
20181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
20191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2020a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(QuicFramerTest, AckFrame) {
20211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
20221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
20231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
20241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
20251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
20261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
20271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
20281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
20291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
20301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
20311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
20321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
20331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
20341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
20351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
20361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
20371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
20381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x6C,
20391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets.
20401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBA,
20411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // largest observed packet sequence number
20421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBF, 0x9A, 0x78, 0x56,
20431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
20441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
20451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
20461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of timestamps.
20471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
20481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num missing packets
20491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
20501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // missing packet delta
20511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
20521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 0 more missing packets in range.
20531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
20541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of revived packets.
20551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
20561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
20571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
20581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
20591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
20601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
20611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
20621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(visitor_.header_.get());
20631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
20641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
20651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, visitor_.stream_frames_.size());
20661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, visitor_.ack_frames_.size());
20671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
20681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0xBA, frame.entropy_hash);
20691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
20701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, frame.missing_packets.size());
20711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SequenceNumberSet::const_iterator missing_iter =
20721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      frame.missing_packets.begin();
20731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
20741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
20751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
20761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
20771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicEntropyHashSize;
20781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
20791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_6BYTE_SEQUENCE_NUMBER;
20801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
20811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicDeltaTimeLargestObservedSize;
20821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumMissingPacketOffset = kNumTimestampsOffset +
20831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicNumTimestampsSize;
20841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
20851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kNumberOfNackRangesSize;
20861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kMissingPacketsRange = kMissingPacketsOffset +
20871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
20881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kRevivedPacketsLength = kMissingPacketsRange +
20891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
20901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
20911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t ack_frame_size = kRevivedPacketsLength +
20921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_1BYTE_SEQUENCE_NUMBER;
20931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
20941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    string expected_error;
20951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (i < kLargestObservedOffset) {
20961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read entropy hash for received packets.";
20971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingDeltaTimeOffset) {
20981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read largest observed.";
20991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumTimestampsOffset) {
21001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read delta time largest observed.";
21011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumMissingPacketOffset) {
21021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num received packets.";
21031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingPacketsOffset) {
21041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num missing packet ranges.";
21051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kMissingPacketsRange) {
21061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read missing sequence number delta.";
21071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kRevivedPacketsLength) {
21081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read missing sequence number range.";
21091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
21101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num revived packets.";
21111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
21121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CheckProcessingFails(
21131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        packet,
21141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
21151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
21161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        expected_error, QUIC_INVALID_ACK_DATA);
21171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
21181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
21191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
21201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, AckFrameRevivedPackets) {
21211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
21221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
21231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unsigned char packet[] = {
2125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
2126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x3C,
2127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
2128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
2129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
2130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // packet sequence number
2131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
2132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
2133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // private flags (entropy)
2134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // frame type (ack frame)
2137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
2138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x6C,
2139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // entropy hash of all received packets.
2140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xBA,
2141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // largest observed packet sequence number
2142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xBF, 0x9A, 0x78, 0x56,
2143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
2144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Zero delta time.
2145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x0, 0x0,
21461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num received packets.
21471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
2148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // num missing packets
2149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // missing packet delta
2151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 0 more missing packets in range.
2153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x00,
2154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Number of revived packets.
21551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
21561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Revived packet sequence number.
21571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBE, 0x9A, 0x78, 0x56,
21581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
21591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of revived packets.
2160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x00,
2161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
2162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
2164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
2165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
2167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
2168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
2169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.stream_frames_.size());
2171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1u, visitor_.ack_frames_.size());
2172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
21735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0xBA, frame.entropy_hash);
21745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
21755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(1u, frame.missing_packets.size());
2176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SequenceNumberSet::const_iterator missing_iter =
21775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame.missing_packets.begin();
2178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
2179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
2181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
2182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kQuicEntropyHashSize;
2183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
2184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER;
21851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
2186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kQuicDeltaTimeLargestObservedSize;
21871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kNumMissingPacketOffset = kNumTimestampsOffset +
21881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kQuicNumTimestampsSize;
2189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
2190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      kNumberOfNackRangesSize;
2191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kMissingPacketsRange = kMissingPacketsOffset +
2192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_1BYTE_SEQUENCE_NUMBER;
2193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kRevivedPacketsLength = kMissingPacketsRange +
2194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_1BYTE_SEQUENCE_NUMBER;
21951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength +
2196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_1BYTE_SEQUENCE_NUMBER;
21971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
21981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t ack_frame_size = kRevivedPacketSequenceNumberLength +
21991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      PACKET_6BYTE_SEQUENCE_NUMBER;
2200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
2201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    string expected_error;
22021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (i < kReceivedEntropyOffset) {
22031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read least unacked delta.";
22041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kLargestObservedOffset) {
2205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read entropy hash for received packets.";
2206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < kMissingDeltaTimeOffset) {
2207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read largest observed.";
22081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumTimestampsOffset) {
2209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read delta time largest observed.";
22101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kNumMissingPacketOffset) {
22111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read num received packets.";
2212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < kMissingPacketsOffset) {
2213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read num missing packet ranges.";
2214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < kMissingPacketsRange) {
2215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read missing sequence number delta.";
2216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (i < kRevivedPacketsLength) {
2217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read missing sequence number range.";
22181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (i < kRevivedPacketSequenceNumberLength) {
2219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read num revived packets.";
22201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
22211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      expected_error = "Unable to read revived packet.";
2222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
2223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CheckProcessingFails(
2224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        packet,
2225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
22265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
22275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        expected_error, QUIC_INVALID_ACK_DATA);
22285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
22295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
22305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
22311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, AckFrameRevivedPacketsv22) {
22321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ > QUIC_VERSION_22) {
22331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
22341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unsigned char packet[] = {
2236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
2237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x3C,
2238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
2239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
2240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
2241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // packet sequence number
2242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
2243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
2244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // private flags (entropy)
2245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // frame type (ack frame)
2248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
2249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x6C,
2250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // entropy hash of all received packets.
2251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xBA,
2252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // largest observed packet sequence number
2253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xBF, 0x9A, 0x78, 0x56,
2254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
2255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Zero delta time.
2256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x0, 0x0,
2257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // num missing packets
2258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // missing packet delta
2260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 0 more missing packets in range.
2262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x00,
2263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Number of revived packets.
2264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Revived packet sequence number.
2266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xBE, 0x9A, 0x78, 0x56,
2267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
22681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of revived packets.
22691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
2270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
2271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
2273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
2274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
2276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
2277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
2278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.stream_frames_.size());
2280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1u, visitor_.ack_frames_.size());
2281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
22825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0xBA, frame.entropy_hash);
22835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
22845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(1u, frame.missing_packets.size());
2285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SequenceNumberSet::const_iterator missing_iter =
22865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame.missing_packets.begin();
2287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
2288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
2290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
2291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kQuicEntropyHashSize;
2292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
2293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER;
2294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kNumMissingPacketOffset = kMissingDeltaTimeOffset +
2295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kQuicDeltaTimeLargestObservedSize;
2296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
2297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      kNumberOfNackRangesSize;
2298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kMissingPacketsRange = kMissingPacketsOffset +
2299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_1BYTE_SEQUENCE_NUMBER;
2300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kRevivedPacketsLength = kMissingPacketsRange +
2301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_1BYTE_SEQUENCE_NUMBER;
2302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength +
2303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_1BYTE_SEQUENCE_NUMBER;
23041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
2305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t ack_frame_size = kRevivedPacketSequenceNumberLength +
2306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER;
23075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
23085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    string expected_error;
23095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (i < kReceivedEntropyOffset) {
23105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read least unacked delta.";
23115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (i < kLargestObservedOffset) {
23125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read entropy hash for received packets.";
23135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (i < kMissingDeltaTimeOffset) {
23145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read largest observed.";
23155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (i < kNumMissingPacketOffset) {
23165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read delta time largest observed.";
23175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (i < kMissingPacketsOffset) {
23185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read num missing packet ranges.";
23195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (i < kMissingPacketsRange) {
23205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read missing sequence number delta.";
23215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (i < kRevivedPacketsLength) {
23225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read missing sequence number range.";
23235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (i < kRevivedPacketSequenceNumberLength) {
23245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read num revived packets.";
23255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else {
23265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expected_error = "Unable to read revived packet.";
23275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
23285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CheckProcessingFails(
23295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        packet,
23305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
23315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
23325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        expected_error, QUIC_INVALID_ACK_DATA);
23335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
23340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
23350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
23361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, AckFrameNoNacksv22) {
23371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ > QUIC_VERSION_22) {
23381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
23391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
23401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
23411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
23421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
23431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
23441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
23451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
23461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
23471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
23481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
23491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
23501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
23511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
23521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
23531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (no nacks, not truncated, 6 byte largest observed, 1 byte delta)
23541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x4C,
23551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets.
23561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBA,
23571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // largest observed packet sequence number
23581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBF, 0x9A, 0x78, 0x56,
23591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
23601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
23611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
23621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
23631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
23641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
23651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
23661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
23671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
23681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(visitor_.header_.get());
23691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
23701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
23711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, visitor_.stream_frames_.size());
23721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, visitor_.ack_frames_.size());
23731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicAckFrame* frame = visitor_.ack_frames_[0];
23741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0xBA, frame->entropy_hash);
23751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
23761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0u, frame->missing_packets.size());
23771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
23781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify that the packet re-serializes identically.
23791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicFrames frames;
23801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frames.push_back(QuicFrame(frame));
23811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
23821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(data != NULL);
23831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
23841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test::CompareCharArraysWithHexError("constructed packet",
23851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      data->data(), data->length(),
23861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      AsChars(packet), arraysize(packet));
23871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
23881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
23895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_P(QuicFramerTest, AckFrameNoNacks) {
23901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
23911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
23921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unsigned char packet[] = {
2394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
2395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x3C,
2396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
2397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
2398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
2399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // packet sequence number
2400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
2401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
2402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // private flags (entropy)
2403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // frame type (ack frame)
24065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // (no nacks, not truncated, 6 byte largest observed, 1 byte delta)
24075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x4C,
2408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // entropy hash of all received packets.
2409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xBA,
2410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // largest observed packet sequence number
2411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xBF, 0x9A, 0x78, 0x56,
2412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
2413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Zero delta time.
2414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x0, 0x0,
24151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Number of received packets.
24161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
2417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
2418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
2420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
2421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
2423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
2424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
2425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.stream_frames_.size());
2427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1u, visitor_.ack_frames_.size());
2428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicAckFrame* frame = visitor_.ack_frames_[0];
24295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0xBA, frame->entropy_hash);
24305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
24315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(0u, frame->missing_packets.size());
2432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify that the packet re-serializes identically.
2434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicFrames frames;
2435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frames.push_back(QuicFrame(frame));
243646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
2437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
2438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
2440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      data->data(), data->length(),
2441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
2442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
2443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
24441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, AckFrame500Nacksv22) {
24451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ > QUIC_VERSION_22) {
24461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
24471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
24481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
24491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
24501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
24511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
24521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
24531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
24541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
24551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
24561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
24571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
24581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
24591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
24601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
24611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
24621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x6C,
24631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets.
24641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBA,
24651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // largest observed packet sequence number
24661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBF, 0x9A, 0x78, 0x56,
24671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
24681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
24691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
24701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num missing packet ranges
24711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x02,
24721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // missing packet delta
24731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
24741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 243 more missing packets in range.
24751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The ranges are listed in this order so the re-constructed packet matches.
24761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xF3,
24771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // No gap between ranges
24781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
24791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 255 more missing packets in range.
24801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xFF,
24811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // No revived packets.
24821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
24831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
24841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
24851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
24861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
24871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
24881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
24891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(visitor_.header_.get());
24901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
24911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
24921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, visitor_.stream_frames_.size());
24931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, visitor_.ack_frames_.size());
24941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicAckFrame* frame = visitor_.ack_frames_[0];
24951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0xBA, frame->entropy_hash);
24961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
24971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, frame->revived_packets.size());
24981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(500u, frame->missing_packets.size());
24991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SequenceNumberSet::const_iterator first_missing_iter =
25001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      frame->missing_packets.begin();
25011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter);
25021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SequenceNumberSet::const_reverse_iterator last_missing_iter =
25031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      frame->missing_packets.rbegin();
25041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter);
25051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
25061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify that the packet re-serializes identically.
25071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicFrames frames;
25081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frames.push_back(QuicFrame(frame));
25091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
25101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(data != NULL);
25111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
25121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test::CompareCharArraysWithHexError("constructed packet",
25131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      data->data(), data->length(),
25141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      AsChars(packet), arraysize(packet));
25151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
25161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
25175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_P(QuicFramerTest, AckFrame500Nacks) {
25181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
25191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
25201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
25210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  unsigned char packet[] = {
2522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
25230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x3C,
2524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
25250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
25260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
25270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // packet sequence number
25280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
25290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x34, 0x12,
25300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // private flags (entropy)
25310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x01,
25320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // frame type (ack frame)
25340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
25350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x6C,
25360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // entropy hash of all received packets.
25370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0xBA,
25380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // largest observed packet sequence number
25390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0xBF, 0x9A, 0x78, 0x56,
25400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x34, 0x12,
25410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Zero delta time.
25420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x0, 0x0,
25431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // No received packets.
25441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
25450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // num missing packet ranges
25460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x02,
25470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // missing packet delta
25480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x01,
25490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // 243 more missing packets in range.
25500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // The ranges are listed in this order so the re-constructed packet matches.
25510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0xF3,
25520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // No gap between ranges
25530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x00,
25540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // 255 more missing packets in range.
25550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0xFF,
25565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // No revived packets.
25575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
25580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  };
25590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
25610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
25620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
25640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
25650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
25660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.stream_frames_.size());
25680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(1u, visitor_.ack_frames_.size());
25690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicAckFrame* frame = visitor_.ack_frames_[0];
25705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0xBA, frame->entropy_hash);
25715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
25725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0u, frame->revived_packets.size());
25735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(500u, frame->missing_packets.size());
25740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SequenceNumberSet::const_iterator first_missing_iter =
25755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame->missing_packets.begin();
25760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter);
25770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SequenceNumberSet::const_reverse_iterator last_missing_iter =
25785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame->missing_packets.rbegin();
25790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter);
25800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify that the packet re-serializes identically.
25820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicFrames frames;
25830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  frames.push_back(QuicFrame(frame));
258446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
25850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
25860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
25880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                      data->data(), data->length(),
25890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
25900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
25910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) {
25935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
2594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
25955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
2596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
25975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
25985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
25995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // packet sequence number
26005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
26015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
26025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags
26035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
26045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
26055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (congestion feedback frame)
26065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x20,
26075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // congestion feedback type (tcp)
26085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
26095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // ack_frame.feedback.tcp.receive_window
26105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x04,
26115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
26125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
26135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
26145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
26155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
26165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
26175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
26185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
26195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
26205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.stream_frames_.size());
26215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
26225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const QuicCongestionFeedbackFrame& frame =
26235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *visitor_.congestion_feedback_frames_[0];
26245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(kTCP, frame.type);
26255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0x4030u, frame.tcp.receive_window);
26265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
26271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
26285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = kQuicFrameTypeSize; i < 4; ++i) {
26295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    string expected_error;
26305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (i < 2) {
26315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read congestion feedback type.";
26325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (i < 4) {
26335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read receive window.";
26345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
26355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CheckProcessingFails(
26365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        packet,
2637a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
26385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
26395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        expected_error, QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
26405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
26415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
26425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2643558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) {
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
2645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
2646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
2647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
26502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
26532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // frame type (congestion feedback frame)
26571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x20,
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // congestion feedback type (invalid)
26592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x03,
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
26632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
26642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
26653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(QUIC_INVALID_CONGESTION_FEEDBACK_DATA, framer_.error());
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(QuicFramerTest, StopWaitingFrame) {
2669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unsigned char packet[] = {
2670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
2671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x3C,
2672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
2673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
2674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
2675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // packet sequence number
2676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
2677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
2678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // private flags (entropy)
2679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
2680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // frame type (ack frame)
2682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
2683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x06,
2684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // entropy hash of sent packets till least awaiting - 1.
2685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xAB,
2686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // least packet sequence number awaiting an ack, delta from sequence number.
2687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x08, 0x00, 0x00, 0x00,
2688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x00, 0x00,
2689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
2690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
2692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
2693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
2695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
2696a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
2697a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2698a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.stream_frames_.size());
2699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size());
2700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0];
2701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0xAB, frame.entropy_hash);
2702a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.least_unacked);
2703a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2704a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kSentEntropyOffset = kQuicFrameTypeSize;
2705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize;
2706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t frame_size = 7;
2707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = kQuicFrameTypeSize; i < frame_size; ++i) {
2708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    string expected_error;
2709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kLeastUnackedOffset) {
2710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read entropy hash for sent packets.";
2711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else {
2712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read least unacked delta.";
2713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
2714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CheckProcessingFails(
2715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        packet,
2716a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
2717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
2718a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        expected_error, QUIC_INVALID_STOP_WAITING_DATA);
2719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
2720a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
2721a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
27225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, RstStreamFrameQuic) {
27235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
2724a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
27255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
2726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
27275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
27285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
27295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // packet sequence number
27305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
27315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
27325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags
27335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
27345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (rst stream frame)
27365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01,
27375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // stream id
27385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
27395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // sent byte offset
27415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x02, 0x03, 0x04,
27425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05, 0x06, 0x07, 0x08,
27435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // error code
27455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x00, 0x00, 0x00,
27465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // error details length
27485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x0d, 0x00,
27495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // error details
27505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'b',  'e',  'c',  'a',
27515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'u',  's',  'e',  ' ',
27525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'I',  ' ',  'c',  'a',
27535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'n',
27545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
27555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
27575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
27585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
27605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
27615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
27625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.rst_stream_frame_.stream_id);
27645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0x01, visitor_.rst_stream_frame_.error_code);
27655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("because I can", visitor_.rst_stream_frame_.error_details);
27665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0807060504030201),
27675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.rst_stream_frame_.byte_offset);
27685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
27705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = kQuicFrameTypeSize;
27715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       i < QuicFramer::GetMinRstStreamFrameSize(); ++i) {
27725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    string expected_error;
27735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) {
27745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read stream_id.";
27755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize +
27765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       + kQuicMaxStreamOffsetSize) {
27775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read rst stream sent byte offset.";
27785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize +
27795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       + kQuicMaxStreamOffsetSize + kQuicErrorCodeSize) {
27805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read rst stream error code.";
27815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
27825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read rst stream error details.";
27835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
27845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CheckProcessingFails(
27855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        packet,
2786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
27875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
27885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        expected_error, QUIC_INVALID_RST_STREAM_DATA);
27895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
27905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
27915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_P(QuicFramerTest, ConnectionCloseFrame) {
27930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  unsigned char packet[] = {
2794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
27950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x3C,
2796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
27970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
27980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
27990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // packet sequence number
28000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
28010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x34, 0x12,
28020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // private flags
28030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x00,
28040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
28050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // frame type (connection close frame)
28060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x02,
28070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // error code
28080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x11, 0x00, 0x00, 0x00,
28090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
28100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // error details length
28110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x0d, 0x00,
28120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // error details
28130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    'b',  'e',  'c',  'a',
28140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    'u',  's',  'e',  ' ',
28150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    'I',  ' ',  'c',  'a',
28160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    'n',
28170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  };
28180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
28190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
28200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
28210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
28220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
28230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
28240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
28250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
28260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.stream_frames_.size());
28270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
28280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(0x11, visitor_.connection_close_frame_.error_code);
28290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
28300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
28310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(0u, visitor_.ack_frames_.size());
28320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
28331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
28340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (size_t i = kQuicFrameTypeSize;
28350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       i < QuicFramer::GetMinConnectionCloseFrameSize(); ++i) {
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string expected_error;
28372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i < kQuicFrameTypeSize + kQuicErrorCodeSize) {
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_error = "Unable to read connection close error code.";
28392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_error = "Unable to read connection close error details.";
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CheckProcessingFails(
2843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        packet,
2844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
2845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
2846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        expected_error, QUIC_INVALID_CONNECTION_CLOSE_DATA);
28472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
28482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, GoAwayFrame) {
28515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
2852a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
28535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
2854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
28555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
28565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
28575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // packet sequence number
28585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
28595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
28605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags
28615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
28625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
28635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (go away frame)
28645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03,
28655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // error code
28665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x09, 0x00, 0x00, 0x00,
28675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // stream id
28685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
28695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // error details length
28705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x0d, 0x00,
28715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // error details
28725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'b',  'e',  'c',  'a',
28735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'u',  's',  'e',  ' ',
28745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'I',  ' ',  'c',  'a',
28755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'n',
28765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
28775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
28785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
28795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
28805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
28815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
28825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
28835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
28845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
28855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x01020304),
28865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.goaway_frame_.last_good_stream_id);
28875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0x9, visitor_.goaway_frame_.error_code);
28885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
28895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
28905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const size_t reason_size = arraysize("because I can") - 1;
28911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
28925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = kQuicFrameTypeSize;
28935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       i < QuicFramer::GetMinGoAwayFrameSize() + reason_size; ++i) {
28945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    string expected_error;
28955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (i < kQuicFrameTypeSize + kQuicErrorCodeSize) {
28965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read go away error code.";
28975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (i < kQuicFrameTypeSize + kQuicErrorCodeSize +
28985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               kQuicMaxStreamIdSize) {
28995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read last good stream id.";
29005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
29015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read goaway reason.";
29025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
29035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CheckProcessingFails(
29045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        packet,
2905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
29065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
29075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        expected_error, QUIC_INVALID_GOAWAY_DATA);
29085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
29095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
29105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, WindowUpdateFrame) {
29125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
2913a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
29145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
2915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
29165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
29175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
29185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // packet sequence number
29195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
29205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
29215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags
29225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
29235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (window update frame)
29255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04,
29265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // stream id
29275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
29285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // byte offset
29295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05, 0x06, 0x07, 0x08,
29305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x09, 0x0a, 0x0b, 0x0c,
29315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
29325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
29345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
29365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
29385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
29395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
29405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x01020304),
29425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.window_update_frame_.stream_id);
29435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0c0b0a0908070605),
29445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.window_update_frame_.byte_offset);
29455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
29475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = kQuicFrameTypeSize;
29485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       i < QuicFramer::GetWindowUpdateFrameSize(); ++i) {
29495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    string expected_error;
29505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) {
29515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read stream_id.";
29525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
29535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read window byte_offset.";
29545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
29555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CheckProcessingFails(
29565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        packet,
2957a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
29585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
29595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        expected_error, QUIC_INVALID_WINDOW_UPDATE_DATA);
29605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
29615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
29625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, BlockedFrame) {
29645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
2965a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
29665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
2967a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
29685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
29695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
29705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // packet sequence number
29715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
29725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
29735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags
29745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
29755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (blocked frame)
29775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05,
29785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // stream id
29795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
29805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
29815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
29835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
29855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
29875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
29885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
29895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x01020304),
29915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.blocked_frame_.stream_id);
29925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
29945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetBlockedFrameSize();
29955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++i) {
29965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    string expected_error = "Unable to read stream_id.";
29975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CheckProcessingFails(
29985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        packet,
2999a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
30005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
30015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        expected_error, QUIC_INVALID_BLOCKED_DATA);
30025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
30035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
30045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
30050529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(QuicFramerTest, PingFrame) {
3006116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (version_ <= QUIC_VERSION_16) {
30070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
30080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
30090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  unsigned char packet[] = {
30110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // public flags (8 byte connection_id)
30120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x3C,
30130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // connection_id
30140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x10, 0x32, 0x54, 0x76,
30150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
30160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // packet sequence number
30170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
30180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x34, 0x12,
30190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // private flags
30200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x00,
30210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // frame type (ping frame)
30230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x07,
30240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
30250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
30270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
30280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
30300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
30310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
30320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1u, visitor_.ping_frames_.size());
30340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // No need to check the PING frame boundaries because it has no payload.
30360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
30370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, PublicResetPacket) {
30395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
3040a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (public reset, 8 byte connection_id)
30415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x0E,
3042a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
30435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
30445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
30455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // message tag (kPRST)
30465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'P', 'R', 'S', 'T',
30475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // num_entries (2) + padding
30485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x02, 0x00, 0x00, 0x00,
30495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRNON
30505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'N', 'O', 'N',
30515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 8
30525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x08, 0x00, 0x00, 0x00,
30535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRSEQ
30545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'S', 'E', 'Q',
30555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 16
30565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x00, 0x00, 0x00,
30575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // nonce proof
30585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x89, 0x67, 0x45, 0x23,
30595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0xEF, 0xCD, 0xAB,
30605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // rejected sequence number
30615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
30625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12, 0x00, 0x00,
30635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
30645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
30655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
30665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
30675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
30685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(visitor_.public_reset_packet_.get());
30695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
3070a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.public_reset_packet_->public_header.connection_id);
30715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
30725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
30735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789),
30745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.public_reset_packet_->nonce_proof);
30755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
30765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.public_reset_packet_->rejected_sequence_number);
30775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(
30785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      visitor_.public_reset_packet_->client_address.address().empty());
30795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
30801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
30815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < arraysize(packet); ++i) {
30825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    string expected_error;
30835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1) << "iteration: " << i;
3084a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
30855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read public flags.";
30865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CheckProcessingFails(packet, i, expected_error,
30875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           QUIC_INVALID_PACKET_HEADER);
30885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (i < kPublicResetPacketMessageTagOffset) {
3089a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
30905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CheckProcessingFails(packet, i, expected_error,
30915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           QUIC_INVALID_PACKET_HEADER);
30925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
30935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read reset message.";
30945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CheckProcessingFails(packet, i, expected_error,
30955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           QUIC_INVALID_PUBLIC_RST_PACKET);
30965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
30975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
30985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
30995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) {
31015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
3102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (public reset, 8 byte connection_id)
31035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x0E,
3104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
31055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
31065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
31075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // message tag (kPRST)
31085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'P', 'R', 'S', 'T',
31095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // num_entries (2) + padding
31105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x02, 0x00, 0x00, 0x00,
31115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRNON
31125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'N', 'O', 'N',
31135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 8
31145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x08, 0x00, 0x00, 0x00,
31155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRSEQ
31165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'S', 'E', 'Q',
31175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 16
31185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x00, 0x00, 0x00,
31195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // nonce proof
31205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x89, 0x67, 0x45, 0x23,
31215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0xEF, 0xCD, 0xAB,
31225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // rejected sequence number
31235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
31245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12, 0x00, 0x00,
31255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // trailing junk
31265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'j', 'u', 'n', 'k',
31275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
31285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  string expected_error = "Unable to read reset message.";
31305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckProcessingFails(packet, arraysize(packet), expected_error,
31315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       QUIC_INVALID_PUBLIC_RST_PACKET);
31325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
31335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
31352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
3136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (public reset, 8 byte connection_id)
31375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x0E,
3138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
31392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
31402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
31415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // message tag (kPRST)
31425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'P', 'R', 'S', 'T',
31435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // num_entries (3) + padding
31445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x00, 0x00, 0x00,
31455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRNON
31465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'N', 'O', 'N',
31475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 8
31485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x08, 0x00, 0x00, 0x00,
31495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRSEQ
31505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'S', 'E', 'Q',
31515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 16
31525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x00, 0x00, 0x00,
31535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kCADR
31545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'C', 'A', 'D', 'R',
31555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 24
31565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x18, 0x00, 0x00, 0x00,
31575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // nonce proof
31585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x89, 0x67, 0x45, 0x23,
31595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0xEF, 0xCD, 0xAB,
31605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // rejected sequence number
31612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
31625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12, 0x00, 0x00,
31635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // client address: 4.31.198.44:443
31645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x02, 0x00,
31655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04, 0x1F, 0xC6, 0x2C,
31665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBB, 0x01,
31672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
31682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
31702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
31715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
31725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(visitor_.public_reset_packet_.get());
31735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
3174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            visitor_.public_reset_packet_->public_header.connection_id);
31755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
31765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
31775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789),
31785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.public_reset_packet_->nonce_proof);
31795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
31805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            visitor_.public_reset_packet_->rejected_sequence_number);
31815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("4.31.198.44",
31825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            IPAddressToString(visitor_.public_reset_packet_->
31835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                client_address.address()));
31845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port());
31852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now test framing boundaries.
31875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < arraysize(packet); ++i) {
31882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string expected_error;
31895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1) << "iteration: " << i;
3190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
31915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read public flags.";
31925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CheckProcessingFails(packet, i, expected_error,
31935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           QUIC_INVALID_PACKET_HEADER);
31945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (i < kPublicResetPacketMessageTagOffset) {
3195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
31965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CheckProcessingFails(packet, i, expected_error,
31975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           QUIC_INVALID_PACKET_HEADER);
31982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
31995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expected_error = "Unable to read reset message.";
32005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CheckProcessingFails(packet, i, expected_error,
32015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           QUIC_INVALID_PUBLIC_RST_PACKET);
32022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
32032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
32042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
32052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3206558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, VersionNegotiationPacket) {
32072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
3208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (version, 8 byte connection_id)
3209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3D,
3210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
32112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
32122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
32132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // version tag
321458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
32152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'Q', '2', '.', '0',
32162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFramerPeer::SetIsServer(&framer_, false);
32192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
32212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
32222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
32232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
32242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2u, visitor_.version_negotiation_packet_->versions.size());
32253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
32262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i <= kPublicFlagsSize + PACKET_8BYTE_CONNECTION_ID; ++i) {
32282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string expected_error;
32292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicErrorCode error_code = QUIC_INVALID_PACKET_HEADER;
3230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (i < kConnectionIdOffset) {
32312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read public flags.";
323290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else if (i < kVersionOffset) {
3233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      expected_error = "Unable to read ConnectionId.";
32342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
32352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_error = "Unable to read supported version in negotiation.";
32362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      error_code = QUIC_INVALID_VERSION_NEGOTIATION_PACKET;
32372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
32382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CheckProcessingFails(packet, i, expected_error, error_code);
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3242558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, FecPacket) {
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
3244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
3245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
3246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
32492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
3252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags (fec group & FEC)
3253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x06,
32542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // first fec protected packet offset
32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,
32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // redundancy
32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'a',  'b',  'c',  'd',
32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'e',  'f',  'g',  'h',
32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'i',  'j',  'k',  'l',
32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'm',  'n',  'o',  'p',
32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
32652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(visitor_.header_.get());
32692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.stream_frames_.size());
32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, visitor_.ack_frames_.size());
32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, visitor_.fec_count_);
32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const QuicFecData& fec_data = *visitor_.fec_data_[0];
32752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), fec_data.fec_group);
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("abcdefghijklmnop", fec_data.redundancy);
32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, BuildPaddingFramePacket) {
32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
3281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
32822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.reset_flag = false;
32832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.version_flag = false;
32842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_flag = false;
32852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.entropy_flag = false;
32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
32872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_group = 0;
32882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPaddingFrame padding_frame;
32902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFrames frames;
32922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(&padding_frame));
32932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[kMaxPacketSize] = {
3295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
3296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
3297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
32982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
32992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
33002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
33012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
33022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x34, 0x12,
33032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
33042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00,
33052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // frame type (padding frame)
33071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
330858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00
33092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
33102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint64 header_size =
3312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
3313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                          PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
3314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
3315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
331646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
3317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
3318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
3320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      data->data(), data->length(),
33211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      AsChars(packet),
3322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      arraysize(packet));
3323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
33252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
3326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicPacketHeader header;
3327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
3328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.reset_flag = false;
3329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.version_flag = false;
3330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.fec_flag = false;
3331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.entropy_flag = false;
3332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.sequence_number_length = PACKET_4BYTE_SEQUENCE_NUMBER;
3333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
3334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.fec_group = 0;
3335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicPaddingFrame padding_frame;
3337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicFrames frames;
3339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  frames.push_back(QuicFrame(&padding_frame));
3340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[kMaxPacketSize] = {
3342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id and 4 byte sequence number)
3343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x2C,
3344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
3345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
3346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
3347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
3348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
3349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
3350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
3351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // frame type (padding frame)
33531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
335458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00
3355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
3356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint64 header_size =
3358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
3359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                          PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
3360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
3361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
336246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
3363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
3364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
3366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      data->data(), data->length(),
33671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      AsChars(packet),
3368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      arraysize(packet));
3369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
33712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
3372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicPacketHeader header;
3373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
3374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.reset_flag = false;
3375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.version_flag = false;
3376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.fec_flag = false;
3377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.entropy_flag = false;
3378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.sequence_number_length = PACKET_2BYTE_SEQUENCE_NUMBER;
3379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
3380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.fec_group = 0;
3381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicPaddingFrame padding_frame;
3383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicFrames frames;
3385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  frames.push_back(QuicFrame(&padding_frame));
3386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[kMaxPacketSize] = {
3388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id and 2 byte sequence number)
3389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x1C,
3390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
3391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
3392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
3393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
3394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC, 0x9A,
3395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
3396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
3397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // frame type (padding frame)
33991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
340058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00
3401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
3402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint64 header_size =
3404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
3405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                          PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
3406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
3407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
340846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
3409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
3410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
3412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      data->data(), data->length(),
34131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      AsChars(packet),
3414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      arraysize(packet));
3415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
34172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
3418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicPacketHeader header;
3419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
3420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.reset_flag = false;
3421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.version_flag = false;
3422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.fec_flag = false;
3423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.entropy_flag = false;
3424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
3425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
3426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.fec_group = 0;
3427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicPaddingFrame padding_frame;
3429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicFrames frames;
3431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  frames.push_back(QuicFrame(&padding_frame));
3432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char packet[kMaxPacketSize] = {
3434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id and 1 byte sequence number)
3435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x0C,
3436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
3437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
3438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
3439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packet sequence number
3440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0xBC,
3441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags
3442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00,
3443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // frame type (padding frame)
34451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x00,
344658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00
3447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
3448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint64 header_size =
3450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
3451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                          PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
3452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
34532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
345446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
34552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(data != NULL);
34562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
34582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      data->data(), data->length(),
34591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      AsChars(packet),
3460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      arraysize(packet));
34612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
34622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, BuildStreamFramePacket) {
34642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicPacketHeader header;
3465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
34662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  header.public_header.reset_flag = false;
34672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  header.public_header.version_flag = false;
34682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  header.fec_flag = false;
34692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  header.entropy_flag = true;
34702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
34712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  header.fec_group = 0;
34722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
34732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicStreamFrame stream_frame;
34742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_frame.stream_id = 0x01020304;
34752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_frame.fin = true;
34762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
3477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stream_frame.data = MakeIOVector("hello world!");
34782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
34792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicFrames frames;
34802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  frames.push_back(QuicFrame(&stream_frame));
34812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
34822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
3483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
34842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
3485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
34862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
34872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
34882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
34892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
34902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
34912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags (entropy)
34922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x01,
34932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
34942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin and no length)
34951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xDF,
34962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
34972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04, 0x03, 0x02, 0x01,
34982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
34992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
35002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
35012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
35022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
35032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
35042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
35052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
35062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
350746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
35082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(data != NULL);
35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      data->data(), data->length(),
35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_P(QuicFramerTest, BuildStreamFramePacketInFecGroup) {
3516c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  QuicPacketHeader header;
3517c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
3518c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  header.public_header.reset_flag = false;
3519c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  header.public_header.version_flag = false;
3520c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  header.fec_flag = false;
3521c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  header.entropy_flag = true;
3522c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
3523c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  header.is_in_fec_group = IN_FEC_GROUP;
3524c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  header.fec_group = GG_UINT64_C(0x77123456789ABC);
3525c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3526c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  QuicStreamFrame stream_frame;
3527c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  stream_frame.stream_id = 0x01020304;
3528c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  stream_frame.fin = true;
3529c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
3530c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  stream_frame.data = MakeIOVector("hello world!");
3531c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3532c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  QuicFrames frames;
3533c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  frames.push_back(QuicFrame(&stream_frame));
3534c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  unsigned char packet[] = {
3535c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // public flags (8 byte connection_id)
3536c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x3C,
3537c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // connection_id
3538c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x10, 0x32, 0x54, 0x76,
3539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
3540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // packet sequence number
3541c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
3542c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x34, 0x12,
3543c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // private flags (entropy, is_in_fec_group)
3544c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x03,
3545c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // FEC group
3546c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x00,
3547c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // frame type (stream frame with fin and data length field)
3548c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0xFF,
3549c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // stream id
3550c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x04, 0x03, 0x02, 0x01,
3551c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // offset
3552c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x54, 0x76, 0x10, 0x32,
3553c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
3554c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // data length (since packet is in an FEC group)
3555c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    0x0C, 0x00,
3556c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // data
3557c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    'h',  'e',  'l',  'l',
3558c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    'o',  ' ',  'w',  'o',
3559c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    'r',  'l',  'd',  '!',
3560c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  };
3561c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
356246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
3563c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ASSERT_TRUE(data != NULL);
3564c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3565c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  test::CompareCharArraysWithHexError("constructed packet",
3566c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                      data->data(), data->length(),
3567c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                      AsChars(packet), arraysize(packet));
3568c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
3569c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
35702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
3572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
35732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.reset_flag = false;
35742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.version_flag = true;
35752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_flag = false;
35762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.entropy_flag = true;
35772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header.fec_group = 0;
35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicStreamFrame stream_frame;
35812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_frame.stream_id = 0x01020304;
35822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_frame.fin = true;
35832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
3584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stream_frame.data = MakeIOVector("hello world!");
35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
35872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(&stream_frame));
35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
3590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (version, 8 byte connection_id)
3591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3D,
3592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
35952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // version tag
359658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
35972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
36002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags (entropy)
3601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x01,
36022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin and no length)
36041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xDF,
36052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // stream id
36062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
36072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // offset
36082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x54, 0x76, 0x10, 0x32,
36092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xDC, 0xFE, 0x98, 0xBA,
36102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // data
36112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'h',  'e',  'l',  'l',
36122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'o',  ' ',  'w',  'o',
36132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'r',  'l',  'd',  '!',
36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicFramerPeer::SetIsServer(&framer_, false);
36171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
36181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(data != NULL);
36191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test::CompareCharArraysWithHexError("constructed packet",
36211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      data->data(), data->length(),
36221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      AsChars(packet), arraysize(packet));
36231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
36241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
36261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketPublicHeader header;
36271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
36281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.reset_flag = false;
36291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.version_flag = true;
36301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
36321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (version, 8 byte connection_id)
36331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0D,
36341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
36351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
36361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
36371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // version tag
36381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
36391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
36401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicVersionVector versions;
36421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  versions.push_back(GetParam());
36431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<QuicEncryptedPacket> data(
36441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      framer_.BuildVersionNegotiationPacket(header, versions));
36451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test::CompareCharArraysWithHexError("constructed packet",
36471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      data->data(), data->length(),
36481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      AsChars(packet), arraysize(packet));
36491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
36501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, BuildAckFramePacketv22) {
36521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ > QUIC_VERSION_22) {
36531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
36541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
36551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketHeader header;
36561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
36571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.reset_flag = false;
36581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.version_flag = false;
36591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.fec_flag = false;
36601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.entropy_flag = true;
36611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
36621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.fec_group = 0;
36631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicAckFrame ack_frame;
36651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.entropy_hash = 0x43;
36661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.largest_observed = GG_UINT64_C(0x770123456789ABF);
36671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
36681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.missing_packets.insert(
36691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GG_UINT64_C(0x770123456789ABE));
36701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicFrames frames;
36721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frames.push_back(QuicFrame(&ack_frame));
36731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
36751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
36761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
36771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
36781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
36791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
36801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
36811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
36821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
36831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
36841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
36851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
36871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
36881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x6C,
36891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets.
36901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x43,
36911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // largest observed packet sequence number
36921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xBF, 0x9A, 0x78, 0x56,
36931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
36941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
36951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
36961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num missing packet ranges
36971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
36981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // missing packet delta
36991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
37001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 0 more missing packets in range.
37011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
37021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 0 revived packets.
37031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
37041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
37051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
370646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
37072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(data != NULL);
37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      data->data(), data->length(),
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
37122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
37132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_P(QuicFramerTest, BuildAckFramePacket) {
37151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
37161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
37171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
37185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicPacketHeader header;
3719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
37205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.public_header.reset_flag = false;
37215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.public_header.version_flag = false;
37225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.fec_flag = false;
37235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.entropy_flag = true;
37245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
37255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.fec_group = 0;
37265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicAckFrame ack_frame;
37285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.entropy_hash = 0x43;
37295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.largest_observed = GG_UINT64_C(0x770123456789ABF);
37305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
37315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.missing_packets.insert(
37325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GG_UINT64_C(0x770123456789ABE));
37335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicFrames frames;
37355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frames.push_back(QuicFrame(&ack_frame));
37365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
3738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
37395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
3740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
37415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
37425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
37435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // packet sequence number
37445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
37455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
37465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags (entropy)
37475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01,
37485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (ack frame)
37505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
37515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x6C,
37525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // entropy hash of all received packets.
37535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x43,
37545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // largest observed packet sequence number
37555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBF, 0x9A, 0x78, 0x56,
37565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
37575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Zero delta time.
37585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x0, 0x0,
37591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num received packets.
37601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
37615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // num missing packet ranges
37625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01,
37635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // missing packet delta
37645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01,
37655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 0 more missing packets in range.
37665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
37675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 0 revived packets.
37685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
37695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
37705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
377146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
37725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
37735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
37755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      data->data(), data->length(),
37765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
37775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
37785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// TODO(jri): Add test for tuncated packets in which the original ack frame had
3780cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// revived packets. (In both the large and small packet cases below).
37811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
37821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacketv22) {
37831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ > QUIC_VERSION_22) {
37841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
37851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
37861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketHeader header;
37871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
37881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.reset_flag = false;
37891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.version_flag = false;
37901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.fec_flag = false;
37911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.entropy_flag = true;
37921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
37931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.fec_group = 0;
37941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
37951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicAckFrame ack_frame;
37961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This entropy hash is different from what shows up in the packet below,
37971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // since entropy is recomputed by the framer on ack truncation (by
37981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TestEntropyCalculator for this test.)
37991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.entropy_hash = 0x43;
38001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.largest_observed = 2 * 300;
38011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
38021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 1; i < 2 * 300; i += 2) {
38031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ack_frame.missing_packets.insert(i);
38041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
38051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicFrames frames;
38071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frames.push_back(QuicFrame(&ack_frame));
38081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
38101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
38111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
38121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
38131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
38141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
38151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
38161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
38171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
38181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
38191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
38201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
38221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
38231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x74,
38241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets, set to 1 by TestEntropyCalculator
38251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // since ack is truncated.
38261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
38271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 2-byte largest observed packet sequence number.
38281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Expected to be 510 (0x1FE), since only 255 nack ranges can fit.
38291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xFE, 0x01,
38301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
38311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
38321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num missing packet ranges (limited to 255 by size of this field).
38331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xFF,
38341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // {missing packet delta, further missing packets in range}
38351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 6 nack ranges x 42 + 3 nack ranges
38361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
38831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 0 revived packets.
38851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
38861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
38871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<QuicPacket> data(
38891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      framer_.BuildDataPacket(header, frames, kMaxPacketSize).packet);
38901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(data != NULL);
38911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
38921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test::CompareCharArraysWithHexError("constructed packet",
38931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      data->data(), data->length(),
38941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      AsChars(packet), arraysize(packet));
38951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
38961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacket) {
38981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
38991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
39001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicPacketHeader header;
3902cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
3903cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.reset_flag = false;
3904cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.version_flag = false;
3905cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.fec_flag = false;
3906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.entropy_flag = true;
3907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
3908cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.fec_group = 0;
3909cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3910cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicAckFrame ack_frame;
3911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This entropy hash is different from what shows up in the packet below,
3912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // since entropy is recomputed by the framer on ack truncation (by
3913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TestEntropyCalculator for this test.)
39145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.entropy_hash = 0x43;
39155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.largest_observed = 2 * 300;
39165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
3917cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 1; i < 2 * 300; i += 2) {
39185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ack_frame.missing_packets.insert(i);
3919cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3920cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3921cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicFrames frames;
3922cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frames.push_back(QuicFrame(&ack_frame));
3923cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3924cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unsigned char packet[] = {
3925cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // public flags (8 byte connection_id)
3926cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x3C,
3927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // connection_id
3928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
3929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
3930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // packet sequence number
3931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
3932cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x34, 0x12,
3933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // private flags (entropy)
3934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01,
3935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // frame type (ack frame)
3937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
3938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x74,
3939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // entropy hash of all received packets, set to 1 by TestEntropyCalculator
3940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // since ack is truncated.
3941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01,
3942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 2-byte largest observed packet sequence number.
3943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Expected to be 510 (0x1FE), since only 255 nack ranges can fit.
3944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0xFE, 0x01,
3945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Zero delta time.
3946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x0, 0x0,
3947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // num missing packet ranges (limited to 255 by size of this field).
3948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0xFF,
3949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // {missing packet delta, further missing packets in range}
3950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 6 nack ranges x 42 + 3 nack ranges
3951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3956cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3962cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3964cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3965cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3971cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3975cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3980cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3986cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3989cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3990cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3991cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3994cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3995cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
3998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 0 revived packets.
4000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x00,
4001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
4002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<QuicPacket> data(
4004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      framer_.BuildDataPacket(header, frames, kMaxPacketSize).packet);
4005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
4006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
4008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      data->data(), data->length(),
4009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
4010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
4011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
40131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacketv22) {
40141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ > QUIC_VERSION_22) {
40151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
40161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
40171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketHeader header;
40181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
40191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.reset_flag = false;
40201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.version_flag = false;
40211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.fec_flag = false;
40221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.entropy_flag = true;
40231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
40241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.fec_group = 0;
40251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
40261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicAckFrame ack_frame;
40271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This entropy hash is different from what shows up in the packet below,
40281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // since entropy is recomputed by the framer on ack truncation (by
40291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TestEntropyCalculator for this test.)
40301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.entropy_hash = 0x43;
40311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.largest_observed = 2 * 300;
40321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
40331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 1; i < 2 * 300; i += 2) {
40341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ack_frame.missing_packets.insert(i);
40351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
40361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
40371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicFrames frames;
40381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frames.push_back(QuicFrame(&ack_frame));
40391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
40401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned char packet[] = {
40411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // public flags (8 byte connection_id)
40421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x3C,
40431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // connection_id
40441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x10, 0x32, 0x54, 0x76,
40451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x98, 0xBA, 0xDC, 0xFE,
40461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet sequence number
40471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0xA8, 0x9A, 0x78, 0x56,
40481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x34, 0x12,
40491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // private flags (entropy)
40501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
40511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
40521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // frame type (ack frame)
40531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
40541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x74,
40551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // entropy hash of all received packets, set to 1 by TestEntropyCalculator
40561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // since ack is truncated.
40571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01,
40581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 2-byte largest observed packet sequence number.
40591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Expected to be 12 (0x0C), since only 6 nack ranges can fit.
40601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0C, 0x00,
40611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Zero delta time.
40621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x0, 0x0,
40631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // num missing packet ranges (limited to 6 by packet size of 37).
40641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x06,
40651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // {missing packet delta, further missing packets in range}
40661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 6 nack ranges
40671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
40681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // 0 revived packets.
40691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    0x00,
40701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
40711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
40721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<QuicPacket> data(
40731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      framer_.BuildDataPacket(header, frames, 37u).packet);
40741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(data != NULL);
40751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Expect 1 byte unused since at least 2 bytes are needed to fit more nacks.
40761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(36u, data->length());
40771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test::CompareCharArraysWithHexError("constructed packet",
40781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      data->data(), data->length(),
40791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      AsChars(packet), arraysize(packet));
40801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
40811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4082cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacket) {
40831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
40841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
40851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4086cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicPacketHeader header;
4087cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
4088cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.reset_flag = false;
4089cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.version_flag = false;
4090cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.fec_flag = false;
4091cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.entropy_flag = true;
4092cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
4093cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.fec_group = 0;
4094cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4095cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicAckFrame ack_frame;
4096cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This entropy hash is different from what shows up in the packet below,
4097cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // since entropy is recomputed by the framer on ack truncation (by
4098cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TestEntropyCalculator for this test.)
40995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.entropy_hash = 0x43;
41005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.largest_observed = 2 * 300;
41015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
4102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 1; i < 2 * 300; i += 2) {
41035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ack_frame.missing_packets.insert(i);
4104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
4105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicFrames frames;
4107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frames.push_back(QuicFrame(&ack_frame));
4108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unsigned char packet[] = {
4110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // public flags (8 byte connection_id)
4111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x3C,
4112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // connection_id
4113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
4114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
4115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // packet sequence number
4116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
4117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x34, 0x12,
4118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // private flags (entropy)
4119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01,
4120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // frame type (ack frame)
4122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
4123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x74,
4124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // entropy hash of all received packets, set to 1 by TestEntropyCalculator
4125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // since ack is truncated.
4126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01,
4127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 2-byte largest observed packet sequence number.
4128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Expected to be 12 (0x0C), since only 6 nack ranges can fit.
4129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x0C, 0x00,
4130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Zero delta time.
4131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x0, 0x0,
4132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // num missing packet ranges (limited to 6 by packet size of 37).
4133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x06,
4134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // {missing packet delta, further missing packets in range}
4135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 6 nack ranges
4136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
4137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 0 revived packets.
4138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    0x00,
4139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
4140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<QuicPacket> data(
4142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      framer_.BuildDataPacket(header, frames, 37u).packet);
4143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
4144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Expect 1 byte unused since at least 2 bytes are needed to fit more nacks.
4145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(36u, data->length());
4146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
4147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      data->data(), data->length(),
4148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
4149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
4150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
41515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCP) {
41525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicPacketHeader header;
4153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
41545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.public_header.reset_flag = false;
41555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.public_header.version_flag = false;
41565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.fec_flag = false;
41575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.entropy_flag = false;
41585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
41595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.fec_group = 0;
41605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
41615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicCongestionFeedbackFrame congestion_feedback_frame;
41625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  congestion_feedback_frame.type = kTCP;
41635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  congestion_feedback_frame.tcp.receive_window = 0x4030;
41640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
41650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicFrames frames;
41665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frames.push_back(QuicFrame(&congestion_feedback_frame));
41670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
41680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  unsigned char packet[] = {
4169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
41700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x3C,
4171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
41720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
41730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
41740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // packet sequence number
41755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
41760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x34, 0x12,
41775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags
41785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00,
41790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
41805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (congestion feedback frame)
41815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x20,
41825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // congestion feedback type (TCP)
41830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x00,
41845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TCP receive window
41855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x04,
41860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  };
41870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
418846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
41890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
41900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
41910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
41920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                      data->data(), data->length(),
41930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
41940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
41950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(QuicFramerTest, BuildStopWaitingPacket) {
4197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicPacketHeader header;
4198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
4199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.reset_flag = false;
4200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.version_flag = false;
4201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.fec_flag = false;
4202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.entropy_flag = true;
4203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
4204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.fec_group = 0;
4205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicStopWaitingFrame stop_waiting_frame;
4207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  stop_waiting_frame.entropy_hash = 0x14;
4208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  stop_waiting_frame.least_unacked = GG_UINT64_C(0x770123456789AA0);
4209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicFrames frames;
4211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frames.push_back(QuicFrame(&stop_waiting_frame));
4212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unsigned char packet[] = {
4214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
4215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x3C,
4216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
4217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
4218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
4219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // packet sequence number
4220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0xA8, 0x9A, 0x78, 0x56,
4221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x34, 0x12,
4222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // private flags (entropy)
4223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x01,
4224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // frame type (stop waiting frame)
4226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x06,
4227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // entropy hash of sent packets till least awaiting - 1.
4228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x14,
4229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // least packet sequence number awaiting an ack, delta from sequence number.
4230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x08, 0x00, 0x00, 0x00,
4231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    0x00, 0x00,
4232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
4233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
423446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
4235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
4236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
4238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      data->data(), data->length(),
4239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
4240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
4241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
42422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInvalidFeedback) {
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
4244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
42452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.reset_flag = false;
42462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.version_flag = false;
42472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_flag = false;
42482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.entropy_flag = false;
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header.fec_group = 0;
42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicCongestionFeedbackFrame congestion_feedback_frame;
42532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  congestion_feedback_frame.type =
42541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<CongestionFeedbackType>(kTCP + 1);
42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
42572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(&congestion_feedback_frame));
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<QuicPacket> data;
42605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_DFATAL(
426146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      data.reset(BuildDataPacket(header, frames)),
4262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "AppendCongestionFeedbackFrame failed");
42635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(data == NULL);
42645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
42655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
42665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
4268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
42692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.reset_flag = false;
42702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.version_flag = false;
42712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_flag = false;
42722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.entropy_flag = false;
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header.fec_group = 0;
42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicRstStreamFrame rst_frame;
42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rst_frame.stream_id = 0x01020304;
4278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rst_frame.error_details = "because I can";
42805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rst_frame.byte_offset = 0x0807060504030201;
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
4283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
4284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
4285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
42882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
42912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // private flags
42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,
42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // frame type (rst stream frame)
42951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x01,
42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // stream id
42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
42985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // sent byte offset
42995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x02, 0x03, 0x04,
43005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05, 0x06, 0x07, 0x08,
43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // error code
43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x08, 0x07, 0x06, 0x05,
43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // error details length
43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0d, 0x00,
43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // error details
43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'b',  'e',  'c',  'a',
43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'u',  's',  'e',  ' ',
43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'I',  ' ',  'c',  'a',
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'n',
43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
43132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(&rst_frame));
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
431546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
43162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(data != NULL);
43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      data->data(), data->length(),
43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_P(QuicFramerTest, BuildCloseFramePacket) {
43240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicPacketHeader header;
4325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
43260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  header.public_header.reset_flag = false;
43270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  header.public_header.version_flag = false;
43280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  header.fec_flag = false;
43290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  header.entropy_flag = true;
43300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
43310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  header.fec_group = 0;
43320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
43330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicConnectionCloseFrame close_frame;
43340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  close_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
43350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  close_frame.error_details = "because I can";
43360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
43370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicFrames frames;
43380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  frames.push_back(QuicFrame(&close_frame));
43390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
43400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  unsigned char packet[] = {
4341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
43420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x3C,
4343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
43440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
43450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
43460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // packet sequence number
43470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
43480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x34, 0x12,
43490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // private flags (entropy)
43500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x01,
43510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
43520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // frame type (connection close frame)
43530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x02,
43540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // error code
43550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x08, 0x07, 0x06, 0x05,
43560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // error details length
43570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    0x0d, 0x00,
43580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // error details
43590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    'b',  'e',  'c',  'a',
43600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    'u',  's',  'e',  ' ',
43610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    'I',  ' ',  'c',  'a',
43620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    'n',
43630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  };
43640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
436546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
43660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
43670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
43680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
43690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                      data->data(), data->length(),
43700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
43710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
43720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
43732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, BuildGoAwayPacket) {
43742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketHeader header;
4375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
43762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.reset_flag = false;
43772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.version_flag = false;
43782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_flag = false;
43792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.entropy_flag = true;
43802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
43812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_group = 0;
43822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicGoAwayFrame goaway_frame;
43842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
43852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  goaway_frame.last_good_stream_id = 0x01020304;
43862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  goaway_frame.reason_phrase = "because I can";
43872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFrames frames;
43892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(&goaway_frame));
43902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
4392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
4393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
4394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
43952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
43962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
43972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
43982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
4400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags(entropy)
4401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x01,
44022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // frame type (go away frame)
44041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x03,
44052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // error code
44062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x08, 0x07, 0x06, 0x05,
44072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // stream id
44082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
44092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // error details length
44102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x0d, 0x00,
44112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // error details
44122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'b',  'e',  'c',  'a',
44132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'u',  's',  'e',  ' ',
44142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'I',  ' ',  'c',  'a',
44152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'n',
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
441846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
44192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(data != NULL);
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      data->data(), data->length(),
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
44242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
44275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicPacketHeader header;
4428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
44295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.public_header.reset_flag = false;
44305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.public_header.version_flag = false;
44315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.fec_flag = false;
44325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.entropy_flag = true;
44335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
44345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.fec_group = 0;
44355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicWindowUpdateFrame window_update_frame;
44375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_update_frame.stream_id = 0x01020304;
44385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_update_frame.byte_offset = 0x1122334455667788;
44395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicFrames frames;
44415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frames.push_back(QuicFrame(&window_update_frame));
44425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
4444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
44455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
4446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
44475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
44485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
44495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // packet sequence number
44505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
44515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
44525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags(entropy)
44535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01,
44545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (window update frame)
44565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04,
44575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // stream id
44585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
44595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // byte offset
44605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x88, 0x77, 0x66, 0x55,
44615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x44, 0x33, 0x22, 0x11,
44625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
44635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
446446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
44655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_TRUE(data != NULL);
44665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
44675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  test::CompareCharArraysWithHexError("constructed packet", data->data(),
44685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                      data->length(), AsChars(packet),
44695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                      arraysize(packet));
44705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
44715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, BuildBlockedPacket) {
44735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicPacketHeader header;
4474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
44755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.public_header.reset_flag = false;
44765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.public_header.version_flag = false;
44775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.fec_flag = false;
44785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.entropy_flag = true;
44795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
44805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header.fec_group = 0;
44815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicBlockedFrame blocked_frame;
44835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blocked_frame.stream_id = 0x01020304;
44845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicFrames frames;
44865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frames.push_back(QuicFrame(&blocked_frame));
44875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
4489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
44905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x3C,
4491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
44925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
44935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
44945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // packet sequence number
44955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
44965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12,
44975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // private flags(entropy)
44985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01,
44995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
45005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // frame type (blocked frame)
45015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05,
45025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // stream id
45035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
45045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
45055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
450646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
45075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_TRUE(data != NULL);
45085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
45095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  test::CompareCharArraysWithHexError("constructed packet", data->data(),
45105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                      data->length(), AsChars(packet),
45115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                      arraysize(packet));
45125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
45135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
45140529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(QuicFramerTest, BuildPingPacket) {
45150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicPacketHeader header;
45160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
45170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  header.public_header.reset_flag = false;
45180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  header.public_header.version_flag = false;
45190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  header.fec_flag = false;
45200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  header.entropy_flag = true;
45210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
45220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  header.fec_group = 0;
45230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
45240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicPingFrame ping_frame;
45250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
45260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicFrames frames;
45270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  frames.push_back(QuicFrame(&ping_frame));
45280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
45290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  unsigned char packet[] = {
45300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // public flags (8 byte connection_id)
45310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x3C,
45320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // connection_id
45330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x10, 0x32, 0x54, 0x76,
45340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
45350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // packet sequence number
45360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
45370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x34, 0x12,
45380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // private flags(entropy)
45390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x01,
45400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
45410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // frame type (ping frame)
45420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    0x07,
45430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
45440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4545116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (version_ >= QUIC_VERSION_18) {
454646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
45470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ASSERT_TRUE(data != NULL);
45480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
45490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    test::CompareCharArraysWithHexError("constructed packet", data->data(),
45500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                        data->length(), AsChars(packet),
45510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                        arraysize(packet));
45520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
45530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    string expected_error =
45540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        "Attempt to add a PingFrame in " + QuicVersionToString(version_);
455546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_DFATAL(BuildDataPacket(header, frames),
45560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  expected_error);
45570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
45580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
45590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
45600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
45612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, BuildPublicResetPacket) {
45622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPublicResetPacket reset_packet;
4563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  reset_packet.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
45642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  reset_packet.public_header.reset_flag = true;
45652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  reset_packet.public_header.version_flag = false;
45662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  reset_packet.rejected_sequence_number = GG_UINT64_C(0x123456789ABC);
45672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  reset_packet.nonce_proof = GG_UINT64_C(0xABCDEF0123456789);
45682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
4570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (public reset, 8 byte ConnectionId)
45715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x0E,
4572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
45735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
45745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
45755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // message tag (kPRST)
45765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'P', 'R', 'S', 'T',
45775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // num_entries (2) + padding
45785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x02, 0x00, 0x00, 0x00,
45795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRNON
45805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'N', 'O', 'N',
45815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 8
45825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x08, 0x00, 0x00, 0x00,
45835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRSEQ
45845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'S', 'E', 'Q',
45855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 16
45865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x00, 0x00, 0x00,
45875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // nonce proof
45885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x89, 0x67, 0x45, 0x23,
45895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0xEF, 0xCD, 0xAB,
45905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // rejected sequence number
45915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
45925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12, 0x00, 0x00,
45935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
45945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
45955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<QuicEncryptedPacket> data(
45965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      framer_.BuildPublicResetPacket(reset_packet));
45975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(data != NULL);
45985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
45995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
46005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      data->data(), data->length(),
46015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
46025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
46035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
46045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
46055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicPublicResetPacket reset_packet;
4606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  reset_packet.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
46075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reset_packet.public_header.reset_flag = true;
46085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reset_packet.public_header.version_flag = false;
46095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reset_packet.rejected_sequence_number = GG_UINT64_C(0x123456789ABC);
46105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reset_packet.nonce_proof = GG_UINT64_C(0xABCDEF0123456789);
46115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reset_packet.client_address = IPEndPoint(Loopback4(), 0x1234);
46125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
46135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned char packet[] = {
4614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (public reset, 8 byte ConnectionId)
46155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x0E,
4616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
46172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
46182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
46195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // message tag (kPRST)
46205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'P', 'R', 'S', 'T',
46215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // num_entries (3) + padding
46225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x00, 0x00, 0x00,
46235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRNON
46245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'N', 'O', 'N',
46255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 8
46265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x08, 0x00, 0x00, 0x00,
46275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kRSEQ
46285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'R', 'S', 'E', 'Q',
46295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 16
46305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x10, 0x00, 0x00, 0x00,
46315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tag kCADR
46325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'C', 'A', 'D', 'R',
46335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // end offset 24
46345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x18, 0x00, 0x00, 0x00,
46352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // nonce proof
46362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x89, 0x67, 0x45, 0x23,
46372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x01, 0xEF, 0xCD, 0xAB,
46382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // rejected sequence number
46392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
46405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x34, 0x12, 0x00, 0x00,
46415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // client address
46425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x02, 0x00,
46435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x7F, 0x00, 0x00, 0x01,
46442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x34, 0x12,
46452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
46462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
46472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicEncryptedPacket> data(
46482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      framer_.BuildPublicResetPacket(reset_packet));
46492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(data != NULL);
46502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
46512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
46522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      data->data(), data->length(),
46532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      AsChars(packet), arraysize(packet));
46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, BuildFecPacket) {
46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
4658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
46592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.reset_flag = false;
46602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.version_flag = false;
46612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_flag = true;
46622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.entropy_flag = true;
46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header.packet_sequence_number = (GG_UINT64_C(0x123456789ABC));
4664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header.is_in_fec_group = IN_FEC_GROUP;
46652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_group = GG_UINT64_C(0x123456789ABB);;
46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFecData fec_data;
46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fec_data.fec_group = 1;
46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fec_data.redundancy = "abcdefghijklmnop";
46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
4672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
4673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
4674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
46772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
4680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags (entropy & fec group & fec packet)
4681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x07,
46822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // first fec protected packet offset
46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,
46842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // redundancy
46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'a',  'b',  'c',  'd',
46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'e',  'f',  'g',  'h',
46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'i',  'j',  'k',  'l',
46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'm',  'n',  'o',  'p',
46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicPacket> data(
46932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      framer_.BuildFecPacket(header, fec_data).packet);
46942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(data != NULL);
46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet",
46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      data->data(), data->length(),
46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      AsChars(packet), arraysize(packet));
46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4701558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, EncryptPacket) {
47022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC);
47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
4704a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
4705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3C,
4706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
47092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
4712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags (fec group & fec packet)
4713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x06,
47142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // first fec protected packet offset
47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,
47162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // redundancy
47182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'a',  'b',  'c',  'd',
47192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'e',  'f',  'g',  'h',
47202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'i',  'j',  'k',  'l',
47212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'm',  'n',  'o',  'p',
47222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
47232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicPacket> raw(
47252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      QuicPacket::NewDataPacket(AsChars(packet), arraysize(packet), false,
4726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
4727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER));
47282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicEncryptedPacket> encrypted(
4729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw));
47302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(encrypted.get() != NULL);
47322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(CheckEncryption(sequence_number, raw.get()));
47332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
47342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4735558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
47362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC);
47372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
4738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (version, 8 byte connection_id)
4739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x3D,
4740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
47412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x10, 0x32, 0x54, 0x76,
47422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x98, 0xBA, 0xDC, 0xFE,
47432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // version tag
47442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'Q', '.', '1', '0',
47452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // packet sequence number
47462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xBC, 0x9A, 0x78, 0x56,
47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 0x12,
4748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // private flags (fec group & fec flags)
4749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x06,
47502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // first fec protected packet offset
47512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x01,
47522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // redundancy
47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'a',  'b',  'c',  'd',
47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'e',  'f',  'g',  'h',
47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'i',  'j',  'k',  'l',
47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'm',  'n',  'o',  'p',
47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicPacket> raw(
47612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      QuicPacket::NewDataPacket(AsChars(packet), arraysize(packet), false,
4762a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
4763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                PACKET_6BYTE_SEQUENCE_NUMBER));
47642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicEncryptedPacket> encrypted(
4765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw));
47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(encrypted.get() != NULL);
47682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(CheckEncryption(sequence_number, raw.get()));
47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(QuicFramerTest, AckTruncationLargePacket) {
4772a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicPacketHeader header;
4773a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
4774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.reset_flag = false;
4775a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.version_flag = false;
4776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.fec_flag = false;
4777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.entropy_flag = false;
4778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
4779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.fec_group = 0;
4780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4781cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a packet with just the ack.
4782cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u);
4783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicFrame frame;
4784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frame.type = ACK_FRAME;
4785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frame.ack_frame = &ack_frame;
4786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicFrames frames;
4787a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frames.push_back(frame);
4788a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Build an ack packet with truncation due to limit in number of nack ranges.
4790a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<QuicPacket> raw_ack_packet(
4791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      framer_.BuildDataPacket(header, frames, kMaxPacketSize).packet);
4792a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(raw_ack_packet != NULL);
4793a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<QuicEncryptedPacket> ack_packet(
4794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
4795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            *raw_ack_packet));
4796cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Now make sure we can turn our ack packet back into an ack frame.
4797a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
4798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1u, visitor_.ack_frames_.size());
4799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
48005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(processed_ack_frame.is_truncated);
48015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(510u, processed_ack_frame.largest_observed);
48025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(255u, processed_ack_frame.missing_packets.size());
4803a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SequenceNumberSet::const_iterator missing_iter =
48045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      processed_ack_frame.missing_packets.begin();
4805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1u, *missing_iter);
4806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SequenceNumberSet::const_reverse_iterator last_missing_iter =
48075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      processed_ack_frame.missing_packets.rbegin();
4808a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(509u, *last_missing_iter);
4809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
4810a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
48111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicFramerTest, AckTruncationSmallPacketv22) {
48121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ > QUIC_VERSION_22) {
48131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
48141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
48151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketHeader header;
48161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
48171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.reset_flag = false;
48181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.public_header.version_flag = false;
48191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.fec_flag = false;
48201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.entropy_flag = false;
48211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
48221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  header.fec_group = 0;
48231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
48241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a packet with just the ack.
48251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u);
48261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicFrame frame;
48271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frame.type = ACK_FRAME;
48281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frame.ack_frame = &ack_frame;
48291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicFrames frames;
48301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frames.push_back(frame);
48311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
48321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Build an ack packet with truncation due to limit in number of nack ranges.
48331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<QuicPacket> raw_ack_packet(
48341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      framer_.BuildDataPacket(header, frames, 500).packet);
48351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(raw_ack_packet != NULL);
48361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<QuicEncryptedPacket> ack_packet(
48371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
48381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            *raw_ack_packet));
48391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now make sure we can turn our ack packet back into an ack frame.
48401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
48411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1u, visitor_.ack_frames_.size());
48421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
48431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(processed_ack_frame.is_truncated);
48441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(476u, processed_ack_frame.largest_observed);
48451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(238u, processed_ack_frame.missing_packets.size());
48461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SequenceNumberSet::const_iterator missing_iter =
48471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      processed_ack_frame.missing_packets.begin();
48481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, *missing_iter);
48491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SequenceNumberSet::const_reverse_iterator last_missing_iter =
48501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      processed_ack_frame.missing_packets.rbegin();
48511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(475u, *last_missing_iter);
48521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
48531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
48541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
48561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (version_ <= QUIC_VERSION_22) {
48571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
48581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4859cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicPacketHeader header;
4860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
4861cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.reset_flag = false;
4862cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.public_header.version_flag = false;
4863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.fec_flag = false;
4864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.entropy_flag = false;
4865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
4866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  header.fec_group = 0;
4867cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4868cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a packet with just the ack.
4869cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u);
4870cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicFrame frame;
4871cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame.type = ACK_FRAME;
4872cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame.ack_frame = &ack_frame;
4873cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicFrames frames;
4874cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frames.push_back(frame);
4875cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4876cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Build an ack packet with truncation due to limit in number of nack ranges.
4877cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<QuicPacket> raw_ack_packet(
4878cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      framer_.BuildDataPacket(header, frames, 500).packet);
4879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(raw_ack_packet != NULL);
4880cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<QuicEncryptedPacket> ack_packet(
4881cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
4882cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            *raw_ack_packet));
4883cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Now make sure we can turn our ack packet back into an ack frame.
4884cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
4885cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(1u, visitor_.ack_frames_.size());
4886cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
48875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(processed_ack_frame.is_truncated);
48885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(476u, processed_ack_frame.largest_observed);
48895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(238u, processed_ack_frame.missing_packets.size());
4890cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SequenceNumberSet::const_iterator missing_iter =
48915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      processed_ack_frame.missing_packets.begin();
4892cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1u, *missing_iter);
4893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SequenceNumberSet::const_reverse_iterator last_missing_iter =
48945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      processed_ack_frame.missing_packets.rbegin();
4895cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(475u, *last_missing_iter);
4896cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
4897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4898558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_P(QuicFramerTest, CleanTruncation) {
48992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketHeader header;
4900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
49012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.reset_flag = false;
49022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.public_header.version_flag = false;
49032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_flag = false;
49042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.entropy_flag = true;
49052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
49062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.fec_group = 0;
49072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4908f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  QuicAckFrame ack_frame;
49095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ack_frame.largest_observed = 201;
49105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (uint64 i = 1; i < ack_frame.largest_observed; ++i) {
49115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ack_frame.missing_packets.insert(i);
49122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
49132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4914cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a packet with just the ack.
49152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFrame frame;
49162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame.type = ACK_FRAME;
4917f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  frame.ack_frame = &ack_frame;
49182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFrames frames;
49192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(frame);
49202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
49222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(raw_ack_packet != NULL);
49232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<QuicEncryptedPacket> ack_packet(
4925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
4926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            *raw_ack_packet));
49272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Now make sure we can turn our ack packet back into an ack frame.
49292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
49302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test for clean truncation of the ack by comparing the length of the
49322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // original packets to the re-serialized packets.
49332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.clear();
49342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame.type = ACK_FRAME;
49352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame.ack_frame = visitor_.ack_frames_[0];
49362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(frame);
49372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t original_raw_length = raw_ack_packet->length();
493946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  raw_ack_packet.reset(BuildDataPacket(header, frames));
49402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(raw_ack_packet != NULL);
49412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(original_raw_length, raw_ack_packet->length());
49422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(raw_ack_packet != NULL);
49432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
49442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, EntropyFlagTest) {
49462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
4947a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
49482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
4949a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
49502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
49512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
49522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
49532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
49542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
49552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags (Entropy)
49562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x01,
49572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
49582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin and no length)
49591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xDF,
49602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
49612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04, 0x03, 0x02, 0x01,
49622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
49632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
49642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
49652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
49662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
49672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
49682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
49692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
49702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
49712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
49722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
49732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
49742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
49752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.header_->entropy_flag);
49762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(1 << 4, visitor_.header_->entropy_hash);
49772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_FALSE(visitor_.header_->fec_flag);
49782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch};
49792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
49802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, FecEntropyTest) {
49812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
4982a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
49832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
4984a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
49852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
49862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
49872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
49882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
49892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
49902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // private flags (Entropy & fec group & FEC)
49912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x07,
49922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // first fec protected packet offset
49932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xFF,
49942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
49952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin and no length)
49961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xDF,
49972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
49982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04, 0x03, 0x02, 0x01,
49992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
50002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
50012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
50022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
50032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
50042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
50052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
50062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
50072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
50082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
50092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
50102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
50112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(visitor_.header_.get());
50122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.header_->fec_flag);
50132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(visitor_.header_->entropy_flag);
50142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(1 << 4, visitor_.header_->entropy_hash);
50152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch};
50162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
50172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_P(QuicFramerTest, StopPacketProcessing) {
50182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  unsigned char packet[] = {
5019a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // public flags (8 byte connection_id)
50202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x3C,
5021a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // connection_id
50222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x10, 0x32, 0x54, 0x76,
50232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x98, 0xBA, 0xDC, 0xFE,
50242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // packet sequence number
50252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBC, 0x9A, 0x78, 0x56,
50262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
50272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // Entropy
50282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x01,
50292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
50302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (stream frame with fin)
50311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0xFF,
50322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // stream id
50332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x04, 0x03, 0x02, 0x01,
50342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // offset
50352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x54, 0x76, 0x10, 0x32,
50362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xDC, 0xFE, 0x98, 0xBA,
50372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data length
50382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x0c, 0x00,
50392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // data
50402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'h',  'e',  'l',  'l',
50412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'o',  ' ',  'w',  'o',
50422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    'r',  'l',  'd',  '!',
50432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
50442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // frame type (ack frame)
50451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    0x40,
50462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // entropy hash of sent packets till least awaiting - 1.
50472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x14,
50482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // least packet sequence number awaiting an ack
50492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xA0, 0x9A, 0x78, 0x56,
50502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
50512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // entropy hash of all received packets.
50522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x43,
50532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // largest observed packet sequence number
50542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBF, 0x9A, 0x78, 0x56,
50552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
50562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // num missing packets
50572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x01,
50582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // missing packet
50592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0xBE, 0x9A, 0x78, 0x56,
50602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    0x34, 0x12,
50612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  };
50622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
50632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  MockFramerVisitor visitor;
50642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  framer_.set_visitor(&visitor);
50652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_CALL(visitor, OnPacket());
50662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_CALL(visitor, OnPacketHeader(_));
50672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_CALL(visitor, OnStreamFrame(_)).WillOnce(Return(false));
50682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_CALL(visitor, OnAckFrame(_)).Times(0);
50692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_CALL(visitor, OnPacketComplete());
50705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)).WillOnce(Return(true));
50712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
50722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
50732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
50742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
50752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
50762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
50772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
50785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
5079