Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_framer_test.cc
index f9c2de7..b2dc6eb 100644 (file)
@@ -39,52 +39,54 @@ namespace test {
 const QuicPacketSequenceNumber kEpoch = GG_UINT64_C(1) << 48;
 const QuicPacketSequenceNumber kMask = kEpoch - 1;
 
-// Index into the guid offset in the header.
-const size_t kGuidOffset = kPublicFlagsSize;
+// Index into the connection_id offset in the header.
+const size_t kConnectionIdOffset = kPublicFlagsSize;
 // Index into the version string in the header. (if present).
-const size_t kVersionOffset = kGuidOffset + PACKET_8BYTE_GUID;
+const size_t kVersionOffset = kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID;
 
 // Size in bytes of the stream frame fields for an arbitrary StreamID and
 // offset and the last frame in a packet.
-size_t GetMinStreamFrameSize(QuicVersion version) {
+size_t GetMinStreamFrameSize() {
   return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
 }
 
 // Index into the sequence number offset in the header.
-size_t GetSequenceNumberOffset(QuicGuidLength guid_length,
+size_t GetSequenceNumberOffset(QuicConnectionIdLength connection_id_length,
                                bool include_version) {
-  return kGuidOffset + guid_length +
+  return kConnectionIdOffset + connection_id_length +
       (include_version ? kQuicVersionSize : 0);
 }
 
 size_t GetSequenceNumberOffset(bool include_version) {
-  return GetSequenceNumberOffset(PACKET_8BYTE_GUID, include_version);
+  return GetSequenceNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
 }
 
 // Index into the private flags offset in the data packet header.
-size_t GetPrivateFlagsOffset(QuicGuidLength guid_length, bool include_version) {
-  return GetSequenceNumberOffset(guid_length, include_version) +
+size_t GetPrivateFlagsOffset(QuicConnectionIdLength connection_id_length,
+                             bool include_version) {
+  return GetSequenceNumberOffset(connection_id_length, include_version) +
       PACKET_6BYTE_SEQUENCE_NUMBER;
 }
 
 size_t GetPrivateFlagsOffset(bool include_version) {
-  return GetPrivateFlagsOffset(PACKET_8BYTE_GUID, include_version);
+  return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
 }
 
 size_t GetPrivateFlagsOffset(bool include_version,
                              QuicSequenceNumberLength sequence_number_length) {
-  return GetSequenceNumberOffset(PACKET_8BYTE_GUID, include_version) +
+  return GetSequenceNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
       sequence_number_length;
 }
 
 // Index into the fec group offset in the header.
-size_t GetFecGroupOffset(QuicGuidLength guid_length, bool include_version) {
-  return GetPrivateFlagsOffset(guid_length, include_version) +
+size_t GetFecGroupOffset(QuicConnectionIdLength connection_id_length,
+                         bool include_version) {
+  return GetPrivateFlagsOffset(connection_id_length, include_version) +
       kPrivateFlagsSize;
 }
 
 size_t GetFecGroupOffset(bool include_version) {
-  return GetPrivateFlagsOffset(PACKET_8BYTE_GUID, include_version) +
+  return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
       kPrivateFlagsSize;
 }
 
@@ -95,63 +97,40 @@ size_t GetFecGroupOffset(bool include_version,
 }
 
 // Index into the message tag of the public reset packet.
-// Public resets always have full guids.
+// Public resets always have full connection_ids.
 const size_t kPublicResetPacketMessageTagOffset =
-    kGuidOffset + PACKET_8BYTE_GUID;
-
-// TODO(wtc): remove this when we drop support for QUIC_VERSION_13.
-// Index into the nonce proof of the public reset packet.
-// Public resets always have full guids.
-const size_t kPublicResetPacketNonceProofOffset =
-    kGuidOffset + PACKET_8BYTE_GUID;
-
-// TODO(wtc): remove this when we drop support for QUIC_VERSION_13.
-// Index into the rejected sequence number of the public reset packet.
-const size_t kPublicResetPacketRejectedSequenceNumberOffset =
-    kPublicResetPacketNonceProofOffset + kPublicResetNonceSize;
+    kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID;
 
 class TestEncrypter : public QuicEncrypter {
  public:
-  virtual ~TestEncrypter() {}
-  virtual bool SetKey(StringPiece key) OVERRIDE {
-    return true;
-  }
-  virtual bool SetNoncePrefix(StringPiece nonce_prefix) OVERRIDE {
-    return true;
-  }
-  virtual bool Encrypt(StringPiece nonce,
-                       StringPiece associated_data,
-                       StringPiece plaintext,
-                       unsigned char* output) OVERRIDE {
+  ~TestEncrypter() override {}
+  bool SetKey(StringPiece key) override { return true; }
+  bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; }
+  bool Encrypt(StringPiece nonce,
+               StringPiece associated_data,
+               StringPiece plaintext,
+               unsigned char* output) override {
     CHECK(false) << "Not implemented";
     return false;
   }
-  virtual QuicData* EncryptPacket(QuicPacketSequenceNumber sequence_number,
-                                  StringPiece associated_data,
-                                  StringPiece plaintext) OVERRIDE {
+  QuicData* EncryptPacket(QuicPacketSequenceNumber sequence_number,
+                          StringPiece associated_data,
+                          StringPiece plaintext) override {
     sequence_number_ = sequence_number;
     associated_data_ = associated_data.as_string();
     plaintext_ = plaintext.as_string();
     return new QuicData(plaintext.data(), plaintext.length());
   }
-  virtual size_t GetKeySize() const OVERRIDE {
-    return 0;
-  }
-  virtual size_t GetNoncePrefixSize() const OVERRIDE {
-    return 0;
-  }
-  virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) const OVERRIDE {
+  size_t GetKeySize() const override { return 0; }
+  size_t GetNoncePrefixSize() const override { return 0; }
+  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
     return ciphertext_size;
   }
-  virtual size_t GetCiphertextSize(size_t plaintext_size) const OVERRIDE {
+  size_t GetCiphertextSize(size_t plaintext_size) const override {
     return plaintext_size;
   }
-  virtual StringPiece GetKey() const OVERRIDE {
-    return StringPiece();
-  }
-  virtual StringPiece GetNoncePrefix() const OVERRIDE {
-    return StringPiece();
-  }
+  StringPiece GetKey() const override { return StringPiece(); }
+  StringPiece GetNoncePrefix() const override { return StringPiece(); }
   QuicPacketSequenceNumber sequence_number_;
   string associated_data_;
   string plaintext_;
@@ -159,35 +138,27 @@ class TestEncrypter : public QuicEncrypter {
 
 class TestDecrypter : public QuicDecrypter {
  public:
-  virtual ~TestDecrypter() {}
-  virtual bool SetKey(StringPiece key) OVERRIDE {
-    return true;
-  }
-  virtual bool SetNoncePrefix(StringPiece nonce_prefix) OVERRIDE {
-    return true;
-  }
-  virtual bool Decrypt(StringPiece nonce,
-                       StringPiece associated_data,
-                       StringPiece ciphertext,
-                       unsigned char* output,
-                       size_t* output_length) OVERRIDE {
+  ~TestDecrypter() override {}
+  bool SetKey(StringPiece key) override { return true; }
+  bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; }
+  bool Decrypt(StringPiece nonce,
+               StringPiece associated_data,
+               StringPiece ciphertext,
+               unsigned char* output,
+               size_t* output_length) override {
     CHECK(false) << "Not implemented";
     return false;
   }
-  virtual QuicData* DecryptPacket(QuicPacketSequenceNumber sequence_number,
-                                  StringPiece associated_data,
-                                  StringPiece ciphertext) OVERRIDE {
+  QuicData* DecryptPacket(QuicPacketSequenceNumber sequence_number,
+                          StringPiece associated_data,
+                          StringPiece ciphertext) override {
     sequence_number_ = sequence_number;
     associated_data_ = associated_data.as_string();
     ciphertext_ = ciphertext.as_string();
     return new QuicData(ciphertext.data(), ciphertext.length());
   }
-  virtual StringPiece GetKey() const OVERRIDE {
-    return StringPiece();
-  }
-  virtual StringPiece GetNoncePrefix() const OVERRIDE {
-    return StringPiece();
-  }
+  StringPiece GetKey() const override { return StringPiece(); }
+  StringPiece GetNoncePrefix() const override { return StringPiece(); }
   QuicPacketSequenceNumber sequence_number_;
   string associated_data_;
   string ciphertext_;
@@ -207,114 +178,122 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface {
         accept_public_header_(true) {
   }
 
-  virtual ~TestQuicVisitor() {
+  ~TestQuicVisitor() override {
     STLDeleteElements(&stream_frames_);
     STLDeleteElements(&ack_frames_);
     STLDeleteElements(&congestion_feedback_frames_);
+    STLDeleteElements(&stop_waiting_frames_);
+    STLDeleteElements(&ping_frames_);
     STLDeleteElements(&fec_data_);
   }
 
-  virtual void OnError(QuicFramer* f) OVERRIDE {
+  void OnError(QuicFramer* f) override {
     DVLOG(1) << "QuicFramer Error: " << QuicUtils::ErrorToString(f->error())
              << " (" << f->error() << ")";
-    error_count_++;
+    ++error_count_;
   }
 
-  virtual void OnPacket() OVERRIDE {}
+  void OnPacket() override {}
 
-  virtual void OnPublicResetPacket(
-      const QuicPublicResetPacket& packet) OVERRIDE {
+  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
     public_reset_packet_.reset(new QuicPublicResetPacket(packet));
   }
 
-  virtual void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& packet) OVERRIDE {
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& packet) override {
     version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
   }
 
-  virtual void OnRevivedPacket() OVERRIDE {
-    revived_packets_++;
-  }
+  void OnRevivedPacket() override { ++revived_packets_; }
 
-  virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE {
+  bool OnProtocolVersionMismatch(QuicVersion version) override {
     DVLOG(1) << "QuicFramer Version Mismatch, version: " << version;
-    version_mismatch_++;
+    ++version_mismatch_;
     return true;
   }
 
-  virtual bool OnUnauthenticatedPublicHeader(
-      const QuicPacketPublicHeader& header) OVERRIDE {
+  bool OnUnauthenticatedPublicHeader(
+      const QuicPacketPublicHeader& header) override {
     public_header_.reset(new QuicPacketPublicHeader(header));
     return accept_public_header_;
   }
 
-  virtual bool OnUnauthenticatedHeader(
-      const QuicPacketHeader& header) OVERRIDE {
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
     return true;
   }
 
-  virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE {
-    packet_count_++;
+  void OnDecryptedPacket(EncryptionLevel level) override {}
+
+  bool OnPacketHeader(const QuicPacketHeader& header) override {
+    ++packet_count_;
     header_.reset(new QuicPacketHeader(header));
     return accept_packet_;
   }
 
-  virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE {
-    frame_count_++;
+  bool OnStreamFrame(const QuicStreamFrame& frame) override {
+    ++frame_count_;
     stream_frames_.push_back(new QuicStreamFrame(frame));
     return true;
   }
 
-  virtual void OnFecProtectedPayload(StringPiece payload) OVERRIDE {
+  void OnFecProtectedPayload(StringPiece payload) override {
     fec_protected_payload_ = payload.as_string();
   }
 
-  virtual bool OnAckFrame(const QuicAckFrame& frame) OVERRIDE {
-    frame_count_++;
+  bool OnAckFrame(const QuicAckFrame& frame) override {
+    ++frame_count_;
     ack_frames_.push_back(new QuicAckFrame(frame));
     return true;
   }
 
-  virtual bool OnCongestionFeedbackFrame(
-      const QuicCongestionFeedbackFrame& frame) OVERRIDE {
-    frame_count_++;
+  bool OnCongestionFeedbackFrame(
+      const QuicCongestionFeedbackFrame& frame) override {
+    ++frame_count_;
     congestion_feedback_frames_.push_back(
         new QuicCongestionFeedbackFrame(frame));
     return true;
   }
 
-  virtual void OnFecData(const QuicFecData& fec) OVERRIDE {
-    fec_count_++;
-    fec_data_.push_back(new QuicFecData(fec));
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
+    ++frame_count_;
+    stop_waiting_frames_.push_back(new QuicStopWaitingFrame(frame));
+    return true;
   }
 
-  virtual void OnPacketComplete() OVERRIDE {
-    complete_packets_++;
+  bool OnPingFrame(const QuicPingFrame& frame) override {
+    ++frame_count_;
+    ping_frames_.push_back(new QuicPingFrame(frame));
+    return true;
+  }
+
+  void OnFecData(const QuicFecData& fec) override {
+    ++fec_count_;
+    fec_data_.push_back(new QuicFecData(fec));
   }
 
-  virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) OVERRIDE {
+  void OnPacketComplete() override { ++complete_packets_; }
+
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
     rst_stream_frame_ = frame;
     return true;
   }
 
-  virtual bool OnConnectionCloseFrame(
-      const QuicConnectionCloseFrame& frame) OVERRIDE {
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
     connection_close_frame_ = frame;
     return true;
   }
 
-  virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) OVERRIDE {
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
     goaway_frame_ = frame;
     return true;
   }
 
-  virtual bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame)
-      OVERRIDE {
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
     window_update_frame_ = frame;
     return true;
   }
 
-  virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) OVERRIDE {
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
     blocked_frame_ = frame;
     return true;
   }
@@ -337,6 +316,8 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface {
   vector<QuicStreamFrame*> stream_frames_;
   vector<QuicAckFrame*> ack_frames_;
   vector<QuicCongestionFeedbackFrame*> congestion_feedback_frames_;
+  vector<QuicStopWaitingFrame*> stop_waiting_frames_;
+  vector<QuicPingFrame*> ping_frames_;
   vector<QuicFecData*> fec_data_;
   string fec_protected_payload_;
   QuicRstStreamFrame rst_stream_frame_;
@@ -355,7 +336,7 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
         framer_(QuicSupportedVersions(), start_, true) {
     version_ = GetParam();
     framer_.set_version(version_);
-    framer_.SetDecrypter(decrypter_);
+    framer_.SetDecrypter(decrypter_, ENCRYPTION_NONE);
     framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_);
     framer_.set_visitor(&visitor_);
     framer_.set_received_entropy_calculator(&entropy_calculator_);
@@ -406,18 +387,18 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
       return false;
     }
     if (QuicFramer::GetAssociatedDataFromEncryptedPacket(
-            encrypted, PACKET_8BYTE_GUID,
+            encrypted, PACKET_8BYTE_CONNECTION_ID,
             includes_version, PACKET_6BYTE_SEQUENCE_NUMBER) !=
         decrypter_->associated_data_) {
       LOG(ERROR) << "Decrypted incorrect associated data.  expected "
                  << QuicFramer::GetAssociatedDataFromEncryptedPacket(
-                     encrypted, PACKET_8BYTE_GUID,
+                     encrypted, PACKET_8BYTE_CONNECTION_ID,
                      includes_version, PACKET_6BYTE_SEQUENCE_NUMBER)
                  << " actual: " << decrypter_->associated_data_;
       return false;
     }
     StringPiece ciphertext(encrypted.AsStringPiece().substr(
-        GetStartOfEncryptedData(PACKET_8BYTE_GUID, includes_version,
+        GetStartOfEncryptedData(PACKET_8BYTE_CONNECTION_ID, includes_version,
                                 PACKET_6BYTE_SEQUENCE_NUMBER)));
     if (ciphertext != decrypter_->ciphertext_) {
       LOG(ERROR) << "Decrypted incorrect ciphertext data.  expected "
@@ -451,9 +432,8 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
   void CheckStreamFrameBoundaries(unsigned char* packet,
                                   size_t stream_id_size,
                                   bool include_version) {
-    // Now test framing boundaries
-    for (size_t i = kQuicFrameTypeSize;
-         i < GetMinStreamFrameSize(framer_.version()); ++i) {
+    // Now test framing boundaries.
+    for (size_t i = kQuicFrameTypeSize; i < GetMinStreamFrameSize(); ++i) {
       string expected_error;
       if (i < kQuicFrameTypeSize + stream_id_size) {
         expected_error = "Unable to read stream_id.";
@@ -465,7 +445,7 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
       }
       CheckProcessingFails(
           packet,
-          i + GetPacketHeaderSize(PACKET_8BYTE_GUID, include_version,
+          i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, include_version,
                                   PACKET_6BYTE_SEQUENCE_NUMBER,
                                   NOT_IN_FEC_GROUP),
           expected_error, QUIC_INVALID_STREAM_DATA);
@@ -485,6 +465,11 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
         << " wire_sequence_number: " << wire_sequence_number;
   }
 
+  QuicPacket* BuildDataPacket(const QuicPacketHeader& header,
+                              const QuicFrames& frames) {
+    return BuildUnsizedDataPacket(&framer_, header, frames).packet;
+  }
+
   test::TestEncrypter* encrypter_;
   test::TestDecrypter* decrypter_;
   QuicVersion version_;
@@ -609,9 +594,9 @@ TEST_P(QuicFramerTest, EmptyPacket) {
 
 TEST_P(QuicFramerTest, LargePacket) {
   unsigned char packet[kMaxPacketSize + 1] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -622,10 +607,10 @@ TEST_P(QuicFramerTest, LargePacket) {
   };
 
   memset(packet + GetPacketHeaderSize(
-             PACKET_8BYTE_GUID, !kIncludeVersion,
+             PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
              PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), 0,
          kMaxPacketSize - GetPacketHeaderSize(
-             PACKET_8BYTE_GUID, !kIncludeVersion,
+             PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
              PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP) + 1);
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -634,16 +619,16 @@ TEST_P(QuicFramerTest, LargePacket) {
   ASSERT_TRUE(visitor_.header_.get());
   // Make sure we've parsed the packet header, so we can send an error.
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   // Make sure the correct error is propagated.
   EXPECT_EQ(QUIC_PACKET_TOO_LARGE, framer_.error());
 }
 
 TEST_P(QuicFramerTest, PacketHeader) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -658,7 +643,7 @@ TEST_P(QuicFramerTest, PacketHeader) {
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.header_->public_header.version_flag);
   EXPECT_FALSE(visitor_.header_->fec_flag);
@@ -669,16 +654,16 @@ TEST_P(QuicFramerTest, PacketHeader) {
   EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(0x00u, visitor_.header_->fec_group);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0;
-       i < GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
        ++i) {
     string expected_error;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
     } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
-      expected_error = "Unable to read GUID.";
+      expected_error = "Unable to read ConnectionId.";
     } else if (i < GetPrivateFlagsOffset(!kIncludeVersion)) {
       expected_error = "Unable to read sequence number.";
     } else if (i < GetFecGroupOffset(!kIncludeVersion)) {
@@ -690,14 +675,14 @@ TEST_P(QuicFramerTest, PacketHeader) {
   }
 }
 
-TEST_P(QuicFramerTest, PacketHeaderWith4ByteGuid) {
-  QuicFramerPeer::SetLastSerializedGuid(&framer_,
-                                        GG_UINT64_C(0xFEDCBA9876543210));
+TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) {
+  QuicFramerPeer::SetLastSerializedConnectionId(
+      &framer_, GG_UINT64_C(0xFEDCBA9876543210));
 
   unsigned char packet[] = {
-    // public flags (4 byte guid)
+    // public flags (4 byte connection_id)
     0x38,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     // packet sequence number
     0xBC, 0x9A, 0x78, 0x56,
@@ -711,7 +696,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteGuid) {
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.header_->public_header.version_flag);
   EXPECT_FALSE(visitor_.header_->fec_flag);
@@ -722,21 +707,22 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteGuid) {
   EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(0x00u, visitor_.header_->fec_group);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0;
-       i < GetPacketHeaderSize(PACKET_4BYTE_GUID, !kIncludeVersion,
+       i < GetPacketHeaderSize(PACKET_4BYTE_CONNECTION_ID, !kIncludeVersion,
                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
        ++i) {
     string expected_error;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
-    } else if (i < GetSequenceNumberOffset(PACKET_4BYTE_GUID,
+    } else if (i < GetSequenceNumberOffset(PACKET_4BYTE_CONNECTION_ID,
                                            !kIncludeVersion)) {
-      expected_error = "Unable to read GUID.";
-    } else if (i < GetPrivateFlagsOffset(PACKET_4BYTE_GUID,
+      expected_error = "Unable to read ConnectionId.";
+    } else if (i < GetPrivateFlagsOffset(PACKET_4BYTE_CONNECTION_ID,
                                          !kIncludeVersion)) {
       expected_error = "Unable to read sequence number.";
-    } else if (i < GetFecGroupOffset(PACKET_4BYTE_GUID, !kIncludeVersion)) {
+    } else if (i < GetFecGroupOffset(PACKET_4BYTE_CONNECTION_ID,
+                                     !kIncludeVersion)) {
       expected_error = "Unable to read private flags.";
     } else {
       expected_error = "Unable to read first fec protected packet offset.";
@@ -745,14 +731,14 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteGuid) {
   }
 }
 
-TEST_P(QuicFramerTest, PacketHeader1ByteGuid) {
-  QuicFramerPeer::SetLastSerializedGuid(&framer_,
-                                        GG_UINT64_C(0xFEDCBA9876543210));
+TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) {
+  QuicFramerPeer::SetLastSerializedConnectionId(
+      &framer_, GG_UINT64_C(0xFEDCBA9876543210));
 
   unsigned char packet[] = {
-    // public flags (1 byte guid)
+    // public flags (1 byte connection_id)
     0x34,
-    // guid
+    // connection_id
     0x10,
     // packet sequence number
     0xBC, 0x9A, 0x78, 0x56,
@@ -766,7 +752,7 @@ TEST_P(QuicFramerTest, PacketHeader1ByteGuid) {
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.header_->public_header.version_flag);
   EXPECT_FALSE(visitor_.header_->fec_flag);
@@ -777,20 +763,22 @@ TEST_P(QuicFramerTest, PacketHeader1ByteGuid) {
   EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(0x00u, visitor_.header_->fec_group);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0;
-       i < GetPacketHeaderSize(PACKET_1BYTE_GUID, !kIncludeVersion,
+       i < GetPacketHeaderSize(PACKET_1BYTE_CONNECTION_ID, !kIncludeVersion,
                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
        ++i) {
     string expected_error;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
-    } else if (i < GetSequenceNumberOffset(PACKET_1BYTE_GUID,
+    } else if (i < GetSequenceNumberOffset(PACKET_1BYTE_CONNECTION_ID,
                                            !kIncludeVersion)) {
-      expected_error = "Unable to read GUID.";
-    } else if (i < GetPrivateFlagsOffset(PACKET_1BYTE_GUID, !kIncludeVersion)) {
+      expected_error = "Unable to read ConnectionId.";
+    } else if (i < GetPrivateFlagsOffset(PACKET_1BYTE_CONNECTION_ID,
+                                         !kIncludeVersion)) {
       expected_error = "Unable to read sequence number.";
-    } else if (i < GetFecGroupOffset(PACKET_1BYTE_GUID, !kIncludeVersion)) {
+    } else if (i < GetFecGroupOffset(PACKET_1BYTE_CONNECTION_ID,
+                                     !kIncludeVersion)) {
       expected_error = "Unable to read private flags.";
     } else {
       expected_error = "Unable to read first fec protected packet offset.";
@@ -799,14 +787,14 @@ TEST_P(QuicFramerTest, PacketHeader1ByteGuid) {
   }
 }
 
-TEST_P(QuicFramerTest, PacketHeaderWith0ByteGuid) {
-  QuicFramerPeer::SetLastSerializedGuid(&framer_,
-                                        GG_UINT64_C(0xFEDCBA9876543210));
+TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
+  QuicFramerPeer::SetLastSerializedConnectionId(
+      &framer_, GG_UINT64_C(0xFEDCBA9876543210));
 
   unsigned char packet[] = {
-    // public flags (0 byte guid)
+    // public flags (0 byte connection_id)
     0x30,
-    // guid
+    // connection_id
     // packet sequence number
     0xBC, 0x9A, 0x78, 0x56,
     0x34, 0x12,
@@ -819,7 +807,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith0ByteGuid) {
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.header_->public_header.version_flag);
   EXPECT_FALSE(visitor_.header_->fec_flag);
@@ -830,20 +818,22 @@ TEST_P(QuicFramerTest, PacketHeaderWith0ByteGuid) {
   EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(0x00u, visitor_.header_->fec_group);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0;
-       i < GetPacketHeaderSize(PACKET_0BYTE_GUID, !kIncludeVersion,
+       i < GetPacketHeaderSize(PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
        ++i) {
     string expected_error;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
-    } else if (i < GetSequenceNumberOffset(PACKET_0BYTE_GUID,
+    } else if (i < GetSequenceNumberOffset(PACKET_0BYTE_CONNECTION_ID,
                                            !kIncludeVersion)) {
-      expected_error = "Unable to read GUID.";
-    } else if (i < GetPrivateFlagsOffset(PACKET_0BYTE_GUID, !kIncludeVersion)) {
+      expected_error = "Unable to read ConnectionId.";
+    } else if (i < GetPrivateFlagsOffset(PACKET_0BYTE_CONNECTION_ID,
+                                         !kIncludeVersion)) {
       expected_error = "Unable to read sequence number.";
-    } else if (i < GetFecGroupOffset(PACKET_0BYTE_GUID, !kIncludeVersion)) {
+    } else if (i < GetFecGroupOffset(PACKET_0BYTE_CONNECTION_ID,
+                                     !kIncludeVersion)) {
       expected_error = "Unable to read private flags.";
     } else {
       expected_error = "Unable to read first fec protected packet offset.";
@@ -856,7 +846,7 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
   unsigned char packet[] = {
     // public flags (version)
     0x3D,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // version tag
@@ -873,7 +863,7 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_TRUE(visitor_.header_->public_header.version_flag);
   EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]);
@@ -885,16 +875,16 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
   EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(0x00u, visitor_.header_->fec_group);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0;
-       i < GetPacketHeaderSize(PACKET_8BYTE_GUID, kIncludeVersion,
+       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
        ++i) {
     string expected_error;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
     } else if (i < kVersionOffset) {
-      expected_error = "Unable to read GUID.";
+      expected_error = "Unable to read ConnectionId.";
     } else if (i <  GetSequenceNumberOffset(kIncludeVersion)) {
       expected_error = "Unable to read protocol version.";
     } else if (i < GetPrivateFlagsOffset(kIncludeVersion)) {
@@ -913,9 +903,9 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) {
                                         GG_UINT64_C(0x123456789ABA));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid and 4 byte sequence number)
+    // public flags (8 byte connection_id and 4 byte sequence number)
     0x2C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -929,7 +919,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) {
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.header_->public_header.version_flag);
   EXPECT_FALSE(visitor_.header_->fec_flag);
@@ -940,16 +930,16 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) {
   EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(0x00u, visitor_.header_->fec_group);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0;
-       i < GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
        ++i) {
     string expected_error;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
     } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
-      expected_error = "Unable to read GUID.";
+      expected_error = "Unable to read ConnectionId.";
     } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
                                          PACKET_4BYTE_SEQUENCE_NUMBER)) {
       expected_error = "Unable to read sequence number.";
@@ -968,9 +958,9 @@ TEST_P(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) {
                                         GG_UINT64_C(0x123456789ABA));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid and 2 byte sequence number)
+    // public flags (8 byte connection_id and 2 byte sequence number)
     0x1C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -984,7 +974,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) {
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.header_->public_header.version_flag);
   EXPECT_FALSE(visitor_.header_->fec_flag);
@@ -995,16 +985,16 @@ TEST_P(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) {
   EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(0x00u, visitor_.header_->fec_group);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0;
-       i < GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
        ++i) {
     string expected_error;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
     } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
-      expected_error = "Unable to read GUID.";
+      expected_error = "Unable to read ConnectionId.";
     } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
                                          PACKET_2BYTE_SEQUENCE_NUMBER)) {
       expected_error = "Unable to read sequence number.";
@@ -1023,9 +1013,9 @@ TEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) {
                                         GG_UINT64_C(0x123456789ABA));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid and 1 byte sequence number)
+    // public flags (8 byte connection_id and 1 byte sequence number)
     0x0C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1039,7 +1029,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) {
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.header_->public_header.version_flag);
   EXPECT_FALSE(visitor_.header_->fec_flag);
@@ -1050,16 +1040,16 @@ TEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) {
   EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(0x00u, visitor_.header_->fec_group);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0;
-       i < GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+       i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
        ++i) {
     string expected_error;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
     } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
-      expected_error = "Unable to read GUID.";
+      expected_error = "Unable to read ConnectionId.";
     } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
                                          PACKET_1BYTE_SEQUENCE_NUMBER)) {
       expected_error = "Unable to read sequence number.";
@@ -1075,9 +1065,9 @@ TEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) {
 
 TEST_P(QuicFramerTest, InvalidPublicFlag) {
   unsigned char packet[] = {
-    // public flags, unknown flag at bit 6
-    0x40,
-    // guid
+    // public flags: all flags set but the public reset flag and version flag.
+    0xFC,
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1094,13 +1084,18 @@ TEST_P(QuicFramerTest, InvalidPublicFlag) {
                        arraysize(packet),
                        "Illegal public flags value.",
                        QUIC_INVALID_PACKET_HEADER);
+
+  // Now turn off validation.
+  framer_.set_validate_flags(false);
+  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
 };
 
 TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) {
   unsigned char packet[] = {
-    // public flags (8 byte guid and version flag and an unknown flag)
+    // public flags (8 byte connection_id and version flag and an unknown flag)
     0x4D,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // version tag
@@ -1123,9 +1118,9 @@ TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) {
 
 TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
   unsigned char packet[] = {
-    // public flags (8 byte guid, version flag and an unknown flag)
+    // public flags (8 byte connection_id, version flag and an unknown flag)
     0x7D,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // version tag
@@ -1150,9 +1145,9 @@ TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
 
 TEST_P(QuicFramerTest, InvalidPrivateFlag) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1173,9 +1168,9 @@ TEST_P(QuicFramerTest, InvalidPrivateFlag) {
 
 TEST_P(QuicFramerTest, InvalidFECGroupOffset) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1195,9 +1190,9 @@ TEST_P(QuicFramerTest, InvalidFECGroupOffset) {
 
 TEST_P(QuicFramerTest, PaddingFrame) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1235,16 +1230,16 @@ TEST_P(QuicFramerTest, PaddingFrame) {
   // A packet with no frames is not acceptable.
   CheckProcessingFails(
       packet,
-      GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                           PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
       "Packet has no frames.", QUIC_MISSING_PAYLOAD);
 }
 
 TEST_P(QuicFramerTest, StreamFrame) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1284,15 +1279,15 @@ TEST_P(QuicFramerTest, StreamFrame) {
             visitor_.stream_frames_[0]->offset);
   CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, !kIncludeVersion);
 }
 
 TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1332,16 +1327,16 @@ TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
             visitor_.stream_frames_[0]->offset);
   CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   const size_t stream_id_size = 3;
   CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
 }
 
 TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1381,16 +1376,16 @@ TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
             visitor_.stream_frames_[0]->offset);
   CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   const size_t stream_id_size = 2;
   CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
 }
 
 TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1430,16 +1425,16 @@ TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
             visitor_.stream_frames_[0]->offset);
   CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   const size_t stream_id_size = 1;
   CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
 }
 
 TEST_P(QuicFramerTest, StreamFrameWithVersion) {
   unsigned char packet[] = {
-    // public flags (version, 8 byte guid)
+    // public flags (version, 8 byte connection_id)
     0x3D,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // version tag
@@ -1470,8 +1465,8 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) {
 
   EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(visitor_.header_.get()->public_header.version_flag);
-  EXPECT_EQ(GetParam(), visitor_.header_.get()->public_header.versions[0]);
+  EXPECT_TRUE(visitor_.header_->public_header.version_flag);
+  EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]);
   EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion));
 
   ASSERT_EQ(1u, visitor_.stream_frames_.size());
@@ -1483,7 +1478,7 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) {
             visitor_.stream_frames_[0]->offset);
   CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, kIncludeVersion);
 }
 
@@ -1491,9 +1486,9 @@ TEST_P(QuicFramerTest, RejectPacket) {
   visitor_.accept_packet_ = false;
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1532,9 +1527,9 @@ TEST_P(QuicFramerTest, RejectPublicHeader) {
   visitor_.accept_public_header_ = false;
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
   };
@@ -1565,7 +1560,7 @@ TEST_P(QuicFramerTest, RevivedStreamFrame) {
   };
 
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = true;
@@ -1582,7 +1577,7 @@ TEST_P(QuicFramerTest, RevivedStreamFrame) {
   ASSERT_EQ(1, visitor_.revived_packets_);
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.header_->public_header.guid);
+            visitor_.header_->public_header.connection_id);
   EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.header_->public_header.version_flag);
   EXPECT_TRUE(visitor_.header_->fec_flag);
@@ -1605,9 +1600,9 @@ TEST_P(QuicFramerTest, RevivedStreamFrame) {
 
 TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1642,8 +1637,10 @@ TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
   EXPECT_EQ(IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
   EXPECT_EQ(GG_UINT64_C(0x341256789ABA),
             visitor_.header_->fec_group);
-  const size_t fec_offset = GetStartOfFecProtectedData(
-      PACKET_8BYTE_GUID, !kIncludeVersion, PACKET_6BYTE_SEQUENCE_NUMBER);
+  const size_t fec_offset =
+      GetStartOfFecProtectedData(PACKET_8BYTE_CONNECTION_ID,
+                                 !kIncludeVersion,
+                                 PACKET_6BYTE_SEQUENCE_NUMBER);
   EXPECT_EQ(
       string(AsChars(packet) + fec_offset, arraysize(packet) - fec_offset),
       visitor_.fec_protected_payload_);
@@ -1657,15 +1654,14 @@ TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
   CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
 }
 
-TEST_P(QuicFramerTest, AckFrameV14) {
-  if (framer_.version() > QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, AckFramev22) {
+  if (version_ > QUIC_VERSION_22) {
     return;
   }
-
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1677,11 +1673,6 @@ TEST_P(QuicFramerTest, AckFrameV14) {
     // frame type (ack frame)
     // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
     0x6C,
-    // entropy hash of sent packets till least awaiting - 1.
-    0xAB,
-    // least packet sequence number awaiting an ack, delta from sequence number.
-    0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00,
     // entropy hash of all received packets.
     0xBA,
     // largest observed packet sequence number
@@ -1695,6 +1686,8 @@ TEST_P(QuicFramerTest, AckFrameV14) {
     0x01,
     // 0 more missing packets in range.
     0x00,
+    // Number of revived packets.
+    0x00,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -1707,19 +1700,14 @@ TEST_P(QuicFramerTest, AckFrameV14) {
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(0xAB, frame.sent_info.entropy_hash);
-  EXPECT_EQ(0xBA, frame.received_info.entropy_hash);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.received_info.largest_observed);
-  ASSERT_EQ(1u, frame.received_info.missing_packets.size());
+  EXPECT_EQ(0xBA, frame.entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
+  ASSERT_EQ(1u, frame.missing_packets.size());
   SequenceNumberSet::const_iterator missing_iter =
-      frame.received_info.missing_packets.begin();
+      frame.missing_packets.begin();
   EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.sent_info.least_unacked);
 
-  const size_t kSentEntropyOffset = kQuicFrameTypeSize;
-  const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize;
-  const size_t kReceivedEntropyOffset = kLeastUnackedOffset +
-      PACKET_6BYTE_SEQUENCE_NUMBER;
+  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
   const size_t kLargestObservedOffset = kReceivedEntropyOffset +
       kQuicEntropyHashSize;
   const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
@@ -1727,19 +1715,17 @@ TEST_P(QuicFramerTest, AckFrameV14) {
   const size_t kNumMissingPacketOffset = kMissingDeltaTimeOffset +
       kQuicDeltaTimeLargestObservedSize;
   const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
-      kNumberOfMissingPacketsSize;
+      kNumberOfNackRangesSize;
   const size_t kMissingPacketsRange = kMissingPacketsOffset +
       PACKET_1BYTE_SEQUENCE_NUMBER;
-  // Now test framing boundaries
-  const size_t ack_frame_size = kMissingPacketsRange +
+  const size_t kRevivedPacketsLength = kMissingPacketsRange +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  // Now test framing boundaries.
+  const size_t ack_frame_size = kRevivedPacketsLength +
       PACKET_1BYTE_SEQUENCE_NUMBER;
   for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
     string expected_error;
-    if (i < kLeastUnackedOffset) {
-      expected_error = "Unable to read entropy hash for sent packets.";
-    } else if (i < kReceivedEntropyOffset) {
-      expected_error = "Unable to read least unacked delta.";
-    } else if (i < kLargestObservedOffset) {
+    if (i < kLargestObservedOffset) {
       expected_error = "Unable to read entropy hash for received packets.";
     } else if (i < kMissingDeltaTimeOffset) {
       expected_error = "Unable to read largest observed.";
@@ -1749,26 +1735,28 @@ TEST_P(QuicFramerTest, AckFrameV14) {
       expected_error = "Unable to read num missing packet ranges.";
     } else if (i < kMissingPacketsRange) {
       expected_error = "Unable to read missing sequence number delta.";
-    } else {
+    } else if (i < kRevivedPacketsLength) {
       expected_error = "Unable to read missing sequence number range.";
+    } else {
+      expected_error = "Unable to read num revived packets.";
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_ACK_DATA);
   }
 }
 
-TEST_P(QuicFramerTest, AckFrame) {
-  if (framer_.version() <= QUIC_VERSION_14) {
+
+TEST_P(QuicFramerTest, AckFrameTwoTimestamp) {
+  if (version_ <= QUIC_VERSION_22) {
     return;
   }
-
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1780,11 +1768,6 @@ TEST_P(QuicFramerTest, AckFrame) {
     // frame type (ack frame)
     // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
     0x6C,
-    // entropy hash of sent packets till least awaiting - 1.
-    0xAB,
-    // least packet sequence number awaiting an ack, delta from sequence number.
-    0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00,
     // entropy hash of all received packets.
     0xBA,
     // largest observed packet sequence number
@@ -1792,6 +1775,16 @@ TEST_P(QuicFramerTest, AckFrame) {
     0x34, 0x12,
     // Zero delta time.
     0x0, 0x0,
+    // Number of timestamps.
+    0x02,
+    // Delta from largest observed.
+    0x01,
+    // Delta time.
+    0x10, 0x32, 0x54, 0x76,
+    // Delta from largest observed.
+    0x02,
+    // Delta time.
+    0x10, 0x32,
     // num missing packets
     0x01,
     // missing packet delta
@@ -1812,46 +1805,59 @@ TEST_P(QuicFramerTest, AckFrame) {
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(0xAB, frame.sent_info.entropy_hash);
-  EXPECT_EQ(0xBA, frame.received_info.entropy_hash);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.received_info.largest_observed);
-  ASSERT_EQ(1u, frame.received_info.missing_packets.size());
+  EXPECT_EQ(0xBA, frame.entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
+  ASSERT_EQ(1u, frame.missing_packets.size());
+  ASSERT_EQ(2u, frame.received_packet_times.size());
   SequenceNumberSet::const_iterator missing_iter =
-      frame.received_info.missing_packets.begin();
+      frame.missing_packets.begin();
   EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.sent_info.least_unacked);
 
-  const size_t kSentEntropyOffset = kQuicFrameTypeSize;
-  const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize;
-  const size_t kReceivedEntropyOffset = kLeastUnackedOffset +
-      PACKET_6BYTE_SEQUENCE_NUMBER;
+  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
   const size_t kLargestObservedOffset = kReceivedEntropyOffset +
       kQuicEntropyHashSize;
   const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
       PACKET_6BYTE_SEQUENCE_NUMBER;
-  const size_t kNumMissingPacketOffset = kMissingDeltaTimeOffset +
+  const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
       kQuicDeltaTimeLargestObservedSize;
+  const size_t kTimestampDeltaLargestObserved1 = kNumTimestampsOffset +
+      kQuicNumTimestampsSize;
+  const size_t kTimestampTimeDeltaLargestObserved1 =
+      kTimestampDeltaLargestObserved1 + 1;
+  const size_t kTimestampDeltaLargestObserved2 =
+      kTimestampTimeDeltaLargestObserved1 + 4;
+  const size_t kTimestampTimeDeltaLargestObserved2 =
+      kTimestampDeltaLargestObserved2 + 1;
+  const size_t kNumMissingPacketOffset =
+      kTimestampTimeDeltaLargestObserved2 + 2;
   const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
-      kNumberOfMissingPacketsSize;
+      kNumberOfNackRangesSize;
   const size_t kMissingPacketsRange = kMissingPacketsOffset +
       PACKET_1BYTE_SEQUENCE_NUMBER;
   const size_t kRevivedPacketsLength = kMissingPacketsRange +
       PACKET_1BYTE_SEQUENCE_NUMBER;
-  // Now test framing boundaries
+  // Now test framing boundaries.
   const size_t ack_frame_size = kRevivedPacketsLength +
       PACKET_1BYTE_SEQUENCE_NUMBER;
   for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
     string expected_error;
-    if (i < kLeastUnackedOffset) {
-      expected_error = "Unable to read entropy hash for sent packets.";
-    } else if (i < kReceivedEntropyOffset) {
-      expected_error = "Unable to read least unacked delta.";
-    } else if (i < kLargestObservedOffset) {
+    if (i < kLargestObservedOffset) {
       expected_error = "Unable to read entropy hash for received packets.";
     } else if (i < kMissingDeltaTimeOffset) {
       expected_error = "Unable to read largest observed.";
-    } else if (i < kNumMissingPacketOffset) {
+    } else if (i < kNumTimestampsOffset) {
       expected_error = "Unable to read delta time largest observed.";
+    } else if (i < kTimestampDeltaLargestObserved1) {
+      expected_error = "Unable to read num received packets.";
+    } else if (i < kTimestampTimeDeltaLargestObserved1) {
+      expected_error = "Unable to read sequence delta in received packets.";
+    } else if (i < kTimestampDeltaLargestObserved2) {
+      expected_error = "Unable to read time delta in received packets.";
+    } else if (i < kTimestampTimeDeltaLargestObserved2) {
+      expected_error = "Unable to read sequence delta in received packets.";
+    } else if (i < kNumMissingPacketOffset) {
+      expected_error =
+          "Unable to read incremental time delta in received packets.";
     } else if (i < kMissingPacketsOffset) {
       expected_error = "Unable to read num missing packet ranges.";
     } else if (i < kMissingPacketsRange) {
@@ -1863,21 +1869,21 @@ TEST_P(QuicFramerTest, AckFrame) {
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_ACK_DATA);
   }
 }
 
-TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
-  if (framer_.version() <= QUIC_VERSION_14) {
+
+TEST_P(QuicFramerTest, AckFrameOneTimestamp) {
+  if (version_ <= QUIC_VERSION_22) {
     return;
   }
-
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1889,11 +1895,6 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
     // frame type (ack frame)
     // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
     0x6C,
-    // entropy hash of sent packets till least awaiting - 1.
-    0xAB,
-    // least packet sequence number awaiting an ack, delta from sequence number.
-    0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00,
     // entropy hash of all received packets.
     0xBA,
     // largest observed packet sequence number
@@ -1901,6 +1902,12 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
     0x34, 0x12,
     // Zero delta time.
     0x0, 0x0,
+    // Number of timestamps.
+    0x01,
+    // Delta from largest observed.
+    0x01,
+    // Delta time.
+    0x10, 0x32, 0x54, 0x76,
     // num missing packets
     0x01,
     // missing packet delta
@@ -1908,10 +1915,7 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
     // 0 more missing packets in range.
     0x00,
     // Number of revived packets.
-    0x01,
-    // Revived packet sequence number.
-    0xBE, 0x9A, 0x78, 0x56,
-    0x34, 0x12,
+    0x00,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -1924,72 +1928,75 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(0xAB, frame.sent_info.entropy_hash);
-  EXPECT_EQ(0xBA, frame.received_info.entropy_hash);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.received_info.largest_observed);
-  ASSERT_EQ(1u, frame.received_info.missing_packets.size());
+  EXPECT_EQ(0xBA, frame.entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
+  ASSERT_EQ(1u, frame.missing_packets.size());
+  ASSERT_EQ(1u, frame.received_packet_times.size());
   SequenceNumberSet::const_iterator missing_iter =
-      frame.received_info.missing_packets.begin();
+      frame.missing_packets.begin();
   EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.sent_info.least_unacked);
 
-  const size_t kSentEntropyOffset = kQuicFrameTypeSize;
-  const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize;
-  const size_t kReceivedEntropyOffset = kLeastUnackedOffset +
-      PACKET_6BYTE_SEQUENCE_NUMBER;
+  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
   const size_t kLargestObservedOffset = kReceivedEntropyOffset +
       kQuicEntropyHashSize;
   const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
       PACKET_6BYTE_SEQUENCE_NUMBER;
-  const size_t kNumMissingPacketOffset = kMissingDeltaTimeOffset +
+  const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
       kQuicDeltaTimeLargestObservedSize;
+  const size_t kTimestampDeltaLargestObserved = kNumTimestampsOffset +
+      kQuicNumTimestampsSize;
+  const size_t kTimestampTimeDeltaLargestObserved =
+    kTimestampDeltaLargestObserved + 1;
+  const size_t kNumMissingPacketOffset = kTimestampTimeDeltaLargestObserved + 4;
   const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
-      kNumberOfMissingPacketsSize;
+      kNumberOfNackRangesSize;
   const size_t kMissingPacketsRange = kMissingPacketsOffset +
       PACKET_1BYTE_SEQUENCE_NUMBER;
   const size_t kRevivedPacketsLength = kMissingPacketsRange +
       PACKET_1BYTE_SEQUENCE_NUMBER;
-  const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength +
+  // Now test framing boundaries.
+  const size_t ack_frame_size = kRevivedPacketsLength +
       PACKET_1BYTE_SEQUENCE_NUMBER;
-  // Now test framing boundaries
-  const size_t ack_frame_size = kRevivedPacketSequenceNumberLength +
-      PACKET_6BYTE_SEQUENCE_NUMBER;
   for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
     string expected_error;
-    if (i < kLeastUnackedOffset) {
-      expected_error = "Unable to read entropy hash for sent packets.";
-    } else if (i < kReceivedEntropyOffset) {
-      expected_error = "Unable to read least unacked delta.";
-    } else if (i < kLargestObservedOffset) {
+    if (i < kLargestObservedOffset) {
       expected_error = "Unable to read entropy hash for received packets.";
     } else if (i < kMissingDeltaTimeOffset) {
       expected_error = "Unable to read largest observed.";
-    } else if (i < kNumMissingPacketOffset) {
+    } else if (i < kNumTimestampsOffset) {
       expected_error = "Unable to read delta time largest observed.";
+    } else if (i < kTimestampDeltaLargestObserved) {
+      expected_error = "Unable to read num received packets.";
+    } else if (i < kTimestampTimeDeltaLargestObserved) {
+      expected_error = "Unable to read sequence delta in received packets.";
+    } else if (i < kNumMissingPacketOffset) {
+      expected_error = "Unable to read time delta in received packets.";
     } else if (i < kMissingPacketsOffset) {
       expected_error = "Unable to read num missing packet ranges.";
     } else if (i < kMissingPacketsRange) {
       expected_error = "Unable to read missing sequence number delta.";
     } else if (i < kRevivedPacketsLength) {
       expected_error = "Unable to read missing sequence number range.";
-    } else if (i < kRevivedPacketSequenceNumberLength) {
-      expected_error = "Unable to read num revived packets.";
     } else {
-      expected_error = "Unable to read revived packet.";
+      expected_error = "Unable to read num revived packets.";
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_ACK_DATA);
   }
 }
 
-TEST_P(QuicFramerTest, AckFrameNoNacks) {
+
+TEST_P(QuicFramerTest, AckFrame) {
+  if (version_ <= QUIC_VERSION_22) {
+    return;
+  }
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -1999,13 +2006,8 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) {
     0x01,
 
     // frame type (ack frame)
-    // (no nacks, not truncated, 6 byte largest observed, 1 byte delta)
-    0x4C,
-    // entropy hash of sent packets till least awaiting - 1.
-    0xAB,
-    // least packet sequence number awaiting an ack, delta from sequence number.
-    0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00,
+    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
+    0x6C,
     // entropy hash of all received packets.
     0xBA,
     // largest observed packet sequence number
@@ -2013,6 +2015,16 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) {
     0x34, 0x12,
     // Zero delta time.
     0x0, 0x0,
+    // Number of timestamps.
+    0x00,
+    // num missing packets
+    0x01,
+    // missing packet delta
+    0x01,
+    // 0 more missing packets in range.
+    0x00,
+    // Number of revived packets.
+    0x00,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -2024,34 +2036,67 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) {
 
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  QuicAckFrame* frame = visitor_.ack_frames_[0];
-  EXPECT_EQ(0xAB, frame->sent_info.entropy_hash);
-  EXPECT_EQ(0xBA, frame->received_info.entropy_hash);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF),
-            frame->received_info.largest_observed);
-  ASSERT_EQ(0u, frame->received_info.missing_packets.size());
-  EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame->sent_info.least_unacked);
-
-  // Verify that the packet re-serializes identically.
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame));
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(*visitor_.header_, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(0xBA, frame.entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
+  ASSERT_EQ(1u, frame.missing_packets.size());
+  SequenceNumberSet::const_iterator missing_iter =
+      frame.missing_packets.begin();
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
 
-  test::CompareCharArraysWithHexError("constructed packet",
-                                      data->data(), data->length(),
-                                      AsChars(packet), arraysize(packet));
+  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
+  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
+      kQuicEntropyHashSize;
+  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
+      PACKET_6BYTE_SEQUENCE_NUMBER;
+  const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
+      kQuicDeltaTimeLargestObservedSize;
+  const size_t kNumMissingPacketOffset = kNumTimestampsOffset +
+      kQuicNumTimestampsSize;
+  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
+      kNumberOfNackRangesSize;
+  const size_t kMissingPacketsRange = kMissingPacketsOffset +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  const size_t kRevivedPacketsLength = kMissingPacketsRange +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  // Now test framing boundaries.
+  const size_t ack_frame_size = kRevivedPacketsLength +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
+    string expected_error;
+    if (i < kLargestObservedOffset) {
+      expected_error = "Unable to read entropy hash for received packets.";
+    } else if (i < kMissingDeltaTimeOffset) {
+      expected_error = "Unable to read largest observed.";
+    } else if (i < kNumTimestampsOffset) {
+      expected_error = "Unable to read delta time largest observed.";
+    } else if (i < kNumMissingPacketOffset) {
+      expected_error = "Unable to read num received packets.";
+    } else if (i < kMissingPacketsOffset) {
+      expected_error = "Unable to read num missing packet ranges.";
+    } else if (i < kMissingPacketsRange) {
+      expected_error = "Unable to read missing sequence number delta.";
+    } else if (i < kRevivedPacketsLength) {
+      expected_error = "Unable to read missing sequence number range.";
+    } else {
+      expected_error = "Unable to read num revived packets.";
+    }
+    CheckProcessingFails(
+        packet,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
+        expected_error, QUIC_INVALID_ACK_DATA);
+  }
 }
 
-TEST_P(QuicFramerTest, AckFrame500Nacks) {
-  if (framer_.version() <= QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
+  if (version_ <= QUIC_VERSION_22) {
     return;
   }
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -2063,11 +2108,6 @@ TEST_P(QuicFramerTest, AckFrame500Nacks) {
     // frame type (ack frame)
     // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
     0x6C,
-    // entropy hash of sent packets till least awaiting - 1.
-    0xAB,
-    // least packet sequence number awaiting an ack, delta from sequence number.
-    0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00,
     // entropy hash of all received packets.
     0xBA,
     // largest observed packet sequence number
@@ -2075,18 +2115,20 @@ TEST_P(QuicFramerTest, AckFrame500Nacks) {
     0x34, 0x12,
     // Zero delta time.
     0x0, 0x0,
-    // num missing packet ranges
-    0x02,
+    // num received packets.
+    0x00,
+    // num missing packets
+    0x01,
     // missing packet delta
     0x01,
-    // 243 more missing packets in range.
-    // The ranges are listed in this order so the re-constructed packet matches.
-    0xF3,
-    // No gap between ranges
+    // 0 more missing packets in range.
     0x00,
-    // 255 more missing packets in range.
-    0xFF,
-    // No revived packets.
+    // Number of revived packets.
+    0x01,
+    // Revived packet sequence number.
+    0xBE, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // Number of revived packets.
     0x00,
   };
 
@@ -2099,75 +2141,104 @@ TEST_P(QuicFramerTest, AckFrame500Nacks) {
 
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  QuicAckFrame* frame = visitor_.ack_frames_[0];
-  EXPECT_EQ(0xAB, frame->sent_info.entropy_hash);
-  EXPECT_EQ(0xBA, frame->received_info.entropy_hash);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF),
-            frame->received_info.largest_observed);
-  EXPECT_EQ(0u, frame->received_info.revived_packets.size());
-  ASSERT_EQ(500u, frame->received_info.missing_packets.size());
-  SequenceNumberSet::const_iterator first_missing_iter =
-      frame->received_info.missing_packets.begin();
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter);
-  SequenceNumberSet::const_reverse_iterator last_missing_iter =
-      frame->received_info.missing_packets.rbegin();
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame->sent_info.least_unacked);
-
-  // Verify that the packet re-serializes identically.
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame));
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(*visitor_.header_, frames).packet);
-  ASSERT_TRUE(data != NULL);
-
-  test::CompareCharArraysWithHexError("constructed packet",
-                                      data->data(), data->length(),
-                                      AsChars(packet), arraysize(packet));
-}
-
-TEST_P(QuicFramerTest, AckFrame500NacksV14) {
-  if (framer_.version() > QUIC_VERSION_14) {
-    return;
-  }
-  unsigned char packet[] = {
-    // public flags (8 byte guid)
-    0x3C,
-    // guid
-    0x10, 0x32, 0x54, 0x76,
-    0x98, 0xBA, 0xDC, 0xFE,
-    // packet sequence number
-    0xA8, 0x9A, 0x78, 0x56,
-    0x34, 0x12,
-    // private flags (entropy)
-    0x01,
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(0xBA, frame.entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
+  ASSERT_EQ(1u, frame.missing_packets.size());
+  SequenceNumberSet::const_iterator missing_iter =
+      frame.missing_packets.begin();
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
 
-    // frame type (ack frame)
-    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
-    0x6C,
-    // entropy hash of sent packets till least awaiting - 1.
-    0xAB,
-    // least packet sequence number awaiting an ack, delta from sequence number.
-    0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00,
-    // entropy hash of all received packets.
-    0xBA,
+  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
+  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
+      kQuicEntropyHashSize;
+  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
+      PACKET_6BYTE_SEQUENCE_NUMBER;
+  const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
+      kQuicDeltaTimeLargestObservedSize;
+  const size_t kNumMissingPacketOffset = kNumTimestampsOffset +
+      kQuicNumTimestampsSize;
+  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
+      kNumberOfNackRangesSize;
+  const size_t kMissingPacketsRange = kMissingPacketsOffset +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  const size_t kRevivedPacketsLength = kMissingPacketsRange +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  // Now test framing boundaries.
+  const size_t ack_frame_size = kRevivedPacketSequenceNumberLength +
+      PACKET_6BYTE_SEQUENCE_NUMBER;
+  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
+    string expected_error;
+    if (i < kReceivedEntropyOffset) {
+      expected_error = "Unable to read least unacked delta.";
+    } else if (i < kLargestObservedOffset) {
+      expected_error = "Unable to read entropy hash for received packets.";
+    } else if (i < kMissingDeltaTimeOffset) {
+      expected_error = "Unable to read largest observed.";
+    } else if (i < kNumTimestampsOffset) {
+      expected_error = "Unable to read delta time largest observed.";
+    } else if (i < kNumMissingPacketOffset) {
+      expected_error = "Unable to read num received packets.";
+    } else if (i < kMissingPacketsOffset) {
+      expected_error = "Unable to read num missing packet ranges.";
+    } else if (i < kMissingPacketsRange) {
+      expected_error = "Unable to read missing sequence number delta.";
+    } else if (i < kRevivedPacketsLength) {
+      expected_error = "Unable to read missing sequence number range.";
+    } else if (i < kRevivedPacketSequenceNumberLength) {
+      expected_error = "Unable to read num revived packets.";
+    } else {
+      expected_error = "Unable to read revived packet.";
+    }
+    CheckProcessingFails(
+        packet,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
+        expected_error, QUIC_INVALID_ACK_DATA);
+  }
+}
+
+TEST_P(QuicFramerTest, AckFrameRevivedPacketsv22) {
+  if (version_ > QUIC_VERSION_22) {
+    return;
+  }
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x3C,
+    // connection_id
+    0x10, 0x32, 0x54, 0x76,
+    0x98, 0xBA, 0xDC, 0xFE,
+    // packet sequence number
+    0xA8, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // private flags (entropy)
+    0x01,
+
+    // frame type (ack frame)
+    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
+    0x6C,
+    // entropy hash of all received packets.
+    0xBA,
     // largest observed packet sequence number
     0xBF, 0x9A, 0x78, 0x56,
     0x34, 0x12,
     // Zero delta time.
     0x0, 0x0,
-    // num missing packet ranges
-    0x02,
+    // num missing packets
+    0x01,
     // missing packet delta
     0x01,
-    // 243 more missing packets in range.
-    // The ranges are listed in this order so the re-constructed packet matches.
-    0xF3,
-    // No gap between ranges
+    // 0 more missing packets in range.
+    0x00,
+    // Number of revived packets.
+    0x01,
+    // Revived packet sequence number.
+    0xBE, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // Number of revived packets.
     0x00,
-    // 255 more missing packets in range.
-    0xFF,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -2179,54 +2250,87 @@ TEST_P(QuicFramerTest, AckFrame500NacksV14) {
 
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  QuicAckFrame* frame = visitor_.ack_frames_[0];
-  EXPECT_EQ(0xAB, frame->sent_info.entropy_hash);
-  EXPECT_EQ(0xBA, frame->received_info.entropy_hash);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF),
-            frame->received_info.largest_observed);
-  ASSERT_EQ(500u, frame->received_info.missing_packets.size());
-  SequenceNumberSet::const_iterator first_missing_iter =
-      frame->received_info.missing_packets.begin();
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter);
-  SequenceNumberSet::const_reverse_iterator last_missing_iter =
-      frame->received_info.missing_packets.rbegin();
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter);
-  EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame->sent_info.least_unacked);
-
-  // Verify that the packet re-serializes identically.
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame));
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(*visitor_.header_, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(0xBA, frame.entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
+  ASSERT_EQ(1u, frame.missing_packets.size());
+  SequenceNumberSet::const_iterator missing_iter =
+      frame.missing_packets.begin();
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
 
-  test::CompareCharArraysWithHexError("constructed packet",
-                                      data->data(), data->length(),
-                                      AsChars(packet), arraysize(packet));
+  const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
+  const size_t kLargestObservedOffset = kReceivedEntropyOffset +
+      kQuicEntropyHashSize;
+  const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
+      PACKET_6BYTE_SEQUENCE_NUMBER;
+  const size_t kNumMissingPacketOffset = kMissingDeltaTimeOffset +
+      kQuicDeltaTimeLargestObservedSize;
+  const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
+      kNumberOfNackRangesSize;
+  const size_t kMissingPacketsRange = kMissingPacketsOffset +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  const size_t kRevivedPacketsLength = kMissingPacketsRange +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength +
+      PACKET_1BYTE_SEQUENCE_NUMBER;
+  // Now test framing boundaries.
+  const size_t ack_frame_size = kRevivedPacketSequenceNumberLength +
+      PACKET_6BYTE_SEQUENCE_NUMBER;
+  for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
+    string expected_error;
+    if (i < kReceivedEntropyOffset) {
+      expected_error = "Unable to read least unacked delta.";
+    } else if (i < kLargestObservedOffset) {
+      expected_error = "Unable to read entropy hash for received packets.";
+    } else if (i < kMissingDeltaTimeOffset) {
+      expected_error = "Unable to read largest observed.";
+    } else if (i < kNumMissingPacketOffset) {
+      expected_error = "Unable to read delta time largest observed.";
+    } else if (i < kMissingPacketsOffset) {
+      expected_error = "Unable to read num missing packet ranges.";
+    } else if (i < kMissingPacketsRange) {
+      expected_error = "Unable to read missing sequence number delta.";
+    } else if (i < kRevivedPacketsLength) {
+      expected_error = "Unable to read missing sequence number range.";
+    } else if (i < kRevivedPacketSequenceNumberLength) {
+      expected_error = "Unable to read num revived packets.";
+    } else {
+      expected_error = "Unable to read revived packet.";
+    }
+    CheckProcessingFails(
+        packet,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
+        expected_error, QUIC_INVALID_ACK_DATA);
+  }
 }
 
-TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) {
-  if (framer_.version() <= QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, AckFrameNoNacksv22) {
+  if (version_ > QUIC_VERSION_22) {
     return;
   }
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
-    0x00,
+    // private flags (entropy)
+    0x01,
 
-    // frame type (congestion feedback frame)
-    0x20,
-    // congestion feedback type (tcp)
-    0x00,
-    // ack_frame.feedback.tcp.receive_window
-    0x03, 0x04,
+    // frame type (ack frame)
+    // (no nacks, not truncated, 6 byte largest observed, 1 byte delta)
+    0x4C,
+    // entropy hash of all received packets.
+    0xBA,
+    // largest observed packet sequence number
+    0xBF, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // Zero delta time.
+    0x0, 0x0,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -2237,52 +2341,51 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) {
   EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
 
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
-  const QuicCongestionFeedbackFrame& frame =
-      *visitor_.congestion_feedback_frames_[0];
-  ASSERT_EQ(kTCP, frame.type);
-  EXPECT_EQ(0x4030u, frame.tcp.receive_window);
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame* frame = visitor_.ack_frames_[0];
+  EXPECT_EQ(0xBA, frame->entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
+  ASSERT_EQ(0u, frame->missing_packets.size());
 
-  // Now test framing boundaries
-  for (size_t i = kQuicFrameTypeSize; i < 4; ++i) {
-    string expected_error;
-    if (i < 2) {
-      expected_error = "Unable to read congestion feedback type.";
-    } else if (i < 4) {
-      expected_error = "Unable to read receive window.";
-    }
-    CheckProcessingFails(
-        packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
-                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
-        expected_error, QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
-  }
+  // Verify that the packet re-serializes identically.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame));
+  scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet",
+                                      data->data(), data->length(),
+                                      AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, CongestionFeedbackFrameTCPV14) {
-  if (framer_.version() > QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, AckFrameNoNacks) {
+  if (version_ <= QUIC_VERSION_22) {
     return;
   }
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
-    0x00,
+    // private flags (entropy)
+    0x01,
 
-    // frame type (congestion feedback frame)
-    0x20,
-    // congestion feedback type (tcp)
+    // frame type (ack frame)
+    // (no nacks, not truncated, 6 byte largest observed, 1 byte delta)
+    0x4C,
+    // entropy hash of all received packets.
+    0xBA,
+    // largest observed packet sequence number
+    0xBF, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // Zero delta time.
+    0x0, 0x0,
+    // Number of received packets.
     0x00,
-    // ack_frame.feedback.tcp.accumulated_number_of_lost_packets
-    0x01, 0x02,
-    // ack_frame.feedback.tcp.receive_window
-    0x03, 0x04,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -2293,66 +2396,62 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameTCPV14) {
   EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
 
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
-  const QuicCongestionFeedbackFrame& frame =
-      *visitor_.congestion_feedback_frames_[0];
-  ASSERT_EQ(kTCP, frame.type);
-  EXPECT_EQ(0x4030u, frame.tcp.receive_window);
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame* frame = visitor_.ack_frames_[0];
+  EXPECT_EQ(0xBA, frame->entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
+  ASSERT_EQ(0u, frame->missing_packets.size());
 
-  // Now test framing boundaries
-  for (size_t i = kQuicFrameTypeSize; i < 6; ++i) {
-    string expected_error;
-    if (i < 2) {
-      expected_error = "Unable to read congestion feedback type.";
-    } else if (i < 4) {
-      expected_error = "Unable to read accumulated number of lost packets.";
-    } else if (i < 6) {
-      expected_error = "Unable to read receive window.";
-    }
-    CheckProcessingFails(
-        packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
-                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
-        expected_error, QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
-  }
+  // Verify that the packet re-serializes identically.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame));
+  scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet",
+                                      data->data(), data->length(),
+                                      AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrival) {
-  if (framer_.version() <= QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, AckFrame500Nacksv22) {
+  if (version_ > QUIC_VERSION_22) {
     return;
   }
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
-    0x00,
-
-    // frame type (congestion feedback frame)
-    0x20,
-    // congestion feedback type (inter arrival)
+    // private flags (entropy)
     0x01,
-    // num received packets
-    0x03,
-    // lowest sequence number
-    0xBA, 0x9A, 0x78, 0x56,
+
+    // frame type (ack frame)
+    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
+    0x6C,
+    // entropy hash of all received packets.
+    0xBA,
+    // largest observed packet sequence number
+    0xBF, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // receive time
-    0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0x07,
-    // sequence delta
-    0x01, 0x00,
-    // time delta
-    0x01, 0x00, 0x00, 0x00,
-    // sequence delta (skip one packet)
-    0x03, 0x00,
-    // time delta
-    0x02, 0x00, 0x00, 0x00,
+    // Zero delta time.
+    0x0, 0x0,
+    // num missing packet ranges
+    0x02,
+    // missing packet delta
+    0x01,
+    // 243 more missing packets in range.
+    // The ranges are listed in this order so the re-constructed packet matches.
+    0xF3,
+    // No gap between ranges
+    0x00,
+    // 255 more missing packets in range.
+    0xFF,
+    // No revived packets.
+    0x00,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -2363,91 +2462,71 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrival) {
   EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
 
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
-  const QuicCongestionFeedbackFrame& frame =
-      *visitor_.congestion_feedback_frames_[0];
-  ASSERT_EQ(kInterArrival, frame.type);
-  ASSERT_EQ(3u, frame.inter_arrival.received_packet_times.size());
-  TimeMap::const_iterator iter =
-      frame.inter_arrival.received_packet_times.begin();
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABA), iter->first);
-  EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59687),
-            iter->second.Subtract(start_).ToMicroseconds());
-  ++iter;
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), iter->first);
-  EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59688),
-            iter->second.Subtract(start_).ToMicroseconds());
-  ++iter;
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABD), iter->first);
-  EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59689),
-            iter->second.Subtract(start_).ToMicroseconds());
-
-  // Now test framing boundaries
-  for (size_t i = kQuicFrameTypeSize; i < 29; ++i) {
-    string expected_error;
-    if (i < 2) {
-      expected_error = "Unable to read congestion feedback type.";
-    } else if (i < 3) {
-      expected_error = "Unable to read num received packets.";
-    } else if (i < 9) {
-      expected_error = "Unable to read smallest received.";
-    } else if (i < 17) {
-      expected_error = "Unable to read time received.";
-    } else if (i < 19) {
-      expected_error = "Unable to read sequence delta in received packets.";
-    } else if (i < 23) {
-      expected_error = "Unable to read time delta in received packets.";
-    } else if (i < 25) {
-      expected_error = "Unable to read sequence delta in received packets.";
-    } else if (i < 29) {
-      expected_error = "Unable to read time delta in received packets.";
-    }
-    CheckProcessingFails(
-        packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
-                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
-        expected_error, QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
-  }
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame* frame = visitor_.ack_frames_[0];
+  EXPECT_EQ(0xBA, frame->entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
+  EXPECT_EQ(0u, frame->revived_packets.size());
+  ASSERT_EQ(500u, frame->missing_packets.size());
+  SequenceNumberSet::const_iterator first_missing_iter =
+      frame->missing_packets.begin();
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter);
+  SequenceNumberSet::const_reverse_iterator last_missing_iter =
+      frame->missing_packets.rbegin();
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter);
+
+  // Verify that the packet re-serializes identically.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame));
+  scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet",
+                                      data->data(), data->length(),
+                                      AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrivalV14) {
-  if (framer_.version() > QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, AckFrame500Nacks) {
+  if (version_ <= QUIC_VERSION_22) {
     return;
   }
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
-    0x00,
-
-    // frame type (congestion feedback frame)
-    0x20,
-    // congestion feedback type (inter arrival)
+    // private flags (entropy)
     0x01,
-    // accumulated_number_of_lost_packets
-    0x02, 0x03,
-    // num received packets
-    0x03,
-    // lowest sequence number
-    0xBA, 0x9A, 0x78, 0x56,
+
+    // frame type (ack frame)
+    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
+    0x6C,
+    // entropy hash of all received packets.
+    0xBA,
+    // largest observed packet sequence number
+    0xBF, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // receive time
-    0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0x07,
-    // sequence delta
-    0x01, 0x00,
-    // time delta
-    0x01, 0x00, 0x00, 0x00,
-    // sequence delta (skip one packet)
-    0x03, 0x00,
-    // time delta
-    0x02, 0x00, 0x00, 0x00,
+    // Zero delta time.
+    0x0, 0x0,
+    // No received packets.
+    0x00,
+    // num missing packet ranges
+    0x02,
+    // missing packet delta
+    0x01,
+    // 243 more missing packets in range.
+    // The ranges are listed in this order so the re-constructed packet matches.
+    0xF3,
+    // No gap between ranges
+    0x00,
+    // 255 more missing packets in range.
+    0xFF,
+    // No revived packets.
+    0x00,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -2458,60 +2537,35 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrivalV14) {
   EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
 
   EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
-  const QuicCongestionFeedbackFrame& frame =
-      *visitor_.congestion_feedback_frames_[0];
-  ASSERT_EQ(kInterArrival, frame.type);
-  ASSERT_EQ(3u, frame.inter_arrival.received_packet_times.size());
-  TimeMap::const_iterator iter =
-      frame.inter_arrival.received_packet_times.begin();
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABA), iter->first);
-  EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59687),
-            iter->second.Subtract(start_).ToMicroseconds());
-  ++iter;
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), iter->first);
-  EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59688),
-            iter->second.Subtract(start_).ToMicroseconds());
-  ++iter;
-  EXPECT_EQ(GG_UINT64_C(0x0123456789ABD), iter->first);
-  EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59689),
-            iter->second.Subtract(start_).ToMicroseconds());
-
-  // Now test framing boundaries
-  for (size_t i = kQuicFrameTypeSize; i < 31; ++i) {
-    string expected_error;
-    if (i < 2) {
-      expected_error = "Unable to read congestion feedback type.";
-    } else if (i < 4) {
-      expected_error = "Unable to read accumulated number of lost packets.";
-    } else if (i < 5) {
-      expected_error = "Unable to read num received packets.";
-    } else if (i < 11) {
-      expected_error = "Unable to read smallest received.";
-    } else if (i < 19) {
-      expected_error = "Unable to read time received.";
-    } else if (i < 21) {
-      expected_error = "Unable to read sequence delta in received packets.";
-    } else if (i < 25) {
-      expected_error = "Unable to read time delta in received packets.";
-    } else if (i < 27) {
-      expected_error = "Unable to read sequence delta in received packets.";
-    } else if (i < 31) {
-      expected_error = "Unable to read time delta in received packets.";
-    }
-    CheckProcessingFails(
-        packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
-                                PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
-        expected_error, QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
-  }
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame* frame = visitor_.ack_frames_[0];
+  EXPECT_EQ(0xBA, frame->entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
+  EXPECT_EQ(0u, frame->revived_packets.size());
+  ASSERT_EQ(500u, frame->missing_packets.size());
+  SequenceNumberSet::const_iterator first_missing_iter =
+      frame->missing_packets.begin();
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter);
+  SequenceNumberSet::const_reverse_iterator last_missing_iter =
+      frame->missing_packets.rbegin();
+  EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter);
+
+  // Verify that the packet re-serializes identically.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame));
+  scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet",
+                                      data->data(), data->length(),
+                                      AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, CongestionFeedbackFrameFixRate) {
+TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -2522,10 +2576,10 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameFixRate) {
 
     // frame type (congestion feedback frame)
     0x20,
-    // congestion feedback type (fix rate)
-    0x02,
-    // bitrate_in_bytes_per_second;
-    0x01, 0x02, 0x03, 0x04,
+    // congestion feedback type (tcp)
+    0x00,
+    // ack_frame.feedback.tcp.receive_window
+    0x03, 0x04,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -2539,21 +2593,20 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameFixRate) {
   ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
   const QuicCongestionFeedbackFrame& frame =
       *visitor_.congestion_feedback_frames_[0];
-  ASSERT_EQ(kFixRate, frame.type);
-  EXPECT_EQ(static_cast<uint32>(0x04030201),
-            frame.fix_rate.bitrate.ToBytesPerSecond());
+  ASSERT_EQ(kTCP, frame.type);
+  EXPECT_EQ(0x4030u, frame.tcp.receive_window);
 
-  // Now test framing boundaries
-  for (size_t i = kQuicFrameTypeSize; i < 6; ++i) {
+  // Now test framing boundaries.
+  for (size_t i = kQuicFrameTypeSize; i < 4; ++i) {
     string expected_error;
     if (i < 2) {
       expected_error = "Unable to read congestion feedback type.";
-    } else if (i < 6) {
-      expected_error = "Unable to read bitrate.";
+    } else if (i < 4) {
+      expected_error = "Unable to read receive window.";
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
   }
@@ -2561,9 +2614,9 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameFixRate) {
 
 TEST_P(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -2584,37 +2637,27 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) {
   EXPECT_EQ(QUIC_INVALID_CONGESTION_FEEDBACK_DATA, framer_.error());
 }
 
-TEST_P(QuicFramerTest, RstStreamFrameVersion13) {
-  if (version_ > QUIC_VERSION_13) {
-    return;
-  }
-
+TEST_P(QuicFramerTest, StopWaitingFrame) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
-    0x00,
-
-    // frame type (rst stream frame)
+    // private flags (entropy)
     0x01,
-    // stream id
-    0x04, 0x03, 0x02, 0x01,
-    // error code
-    0x01, 0x00, 0x00, 0x00,
 
-    // error details length
-    0x0d, 0x00,
-    // error details
-    'b',  'e',  'c',  'a',
-    'u',  's',  'e',  ' ',
-    'I',  ' ',  'c',  'a',
-    'n',
+    // frame type (ack frame)
+    // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
+    0x06,
+    // entropy hash of sent packets till least awaiting - 1.
+    0xAB,
+    // least packet sequence number awaiting an ack, delta from sequence number.
+    0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00,
   };
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -2624,39 +2667,35 @@ TEST_P(QuicFramerTest, RstStreamFrameVersion13) {
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
 
-  EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.rst_stream_frame_.stream_id);
-  EXPECT_EQ(0x01, visitor_.rst_stream_frame_.error_code);
-  EXPECT_EQ("because I can", visitor_.rst_stream_frame_.error_details);
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size());
+  const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0];
+  EXPECT_EQ(0xAB, frame.entropy_hash);
+  EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.least_unacked);
 
-  // Now test framing boundaries
-  for (size_t i = kQuicFrameTypeSize;
-       i < QuicFramer::GetMinRstStreamFrameSize(version_); ++i) {
+  const size_t kSentEntropyOffset = kQuicFrameTypeSize;
+  const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize;
+  const size_t frame_size = 7;
+  for (size_t i = kQuicFrameTypeSize; i < frame_size; ++i) {
     string expected_error;
-    if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) {
-      expected_error = "Unable to read stream_id.";
-    } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize +
-               kQuicErrorCodeSize) {
-      expected_error = "Unable to read rst stream error code.";
+    if (i < kLeastUnackedOffset) {
+      expected_error = "Unable to read entropy hash for sent packets.";
     } else {
-      expected_error = "Unable to read rst stream error details.";
+      expected_error = "Unable to read least unacked delta.";
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
-        expected_error, QUIC_INVALID_RST_STREAM_DATA);
+        expected_error, QUIC_INVALID_STOP_WAITING_DATA);
   }
 }
 
 TEST_P(QuicFramerTest, RstStreamFrameQuic) {
-  if (version_ <= QUIC_VERSION_13) {
-    return;
-  }
-
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -2699,9 +2738,9 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) {
   EXPECT_EQ(GG_UINT64_C(0x0807060504030201),
             visitor_.rst_stream_frame_.byte_offset);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = kQuicFrameTypeSize;
-       i < QuicFramer::GetMinRstStreamFrameSize(version_); ++i) {
+       i < QuicFramer::GetMinRstStreamFrameSize(); ++i) {
     string expected_error;
     if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) {
       expected_error = "Unable to read stream_id.";
@@ -2716,7 +2755,7 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) {
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_RST_STREAM_DATA);
   }
@@ -2724,9 +2763,9 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) {
 
 TEST_P(QuicFramerTest, ConnectionCloseFrame) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -2763,7 +2802,7 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) {
 
   ASSERT_EQ(0u, visitor_.ack_frames_.size());
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = kQuicFrameTypeSize;
        i < QuicFramer::GetMinConnectionCloseFrameSize(); ++i) {
     string expected_error;
@@ -2774,7 +2813,7 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) {
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_CONNECTION_CLOSE_DATA);
   }
@@ -2782,9 +2821,9 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) {
 
 TEST_P(QuicFramerTest, GoAwayFrame) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -2821,7 +2860,7 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
   EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
 
   const size_t reason_size = arraysize("because I can") - 1;
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = kQuicFrameTypeSize;
        i < QuicFramer::GetMinGoAwayFrameSize() + reason_size; ++i) {
     string expected_error;
@@ -2835,7 +2874,7 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_GOAWAY_DATA);
   }
@@ -2843,9 +2882,9 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
 
 TEST_P(QuicFramerTest, WindowUpdateFrame) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -2865,14 +2904,6 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
 
-  // WINDOW_UPDATE frame introduced in QUIC_VERSION_14.
-  if (version_ <= QUIC_VERSION_13) {
-    string expected_error = "Trying to read a WindowUpdateFrame in " +
-                            QuicVersionToString(version_);
-    EXPECT_DFATAL(framer_.ProcessPacket(encrypted), expected_error);
-    return;
-  }
-
   EXPECT_TRUE(framer_.ProcessPacket(encrypted));
 
   EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
@@ -2884,7 +2915,7 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
   EXPECT_EQ(GG_UINT64_C(0x0c0b0a0908070605),
             visitor_.window_update_frame_.byte_offset);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = kQuicFrameTypeSize;
        i < QuicFramer::GetWindowUpdateFrameSize(); ++i) {
     string expected_error;
@@ -2895,7 +2926,7 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
     }
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_WINDOW_UPDATE_DATA);
   }
@@ -2903,9 +2934,9 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
 
 TEST_P(QuicFramerTest, BlockedFrame) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -2922,14 +2953,6 @@ TEST_P(QuicFramerTest, BlockedFrame) {
 
   QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
 
-  // BLOCKED frame introduced in QUIC_VERSION_14.
-  if (version_ <= QUIC_VERSION_13) {
-    string expected_error =
-        "Trying to read a BlockedFrame in " + QuicVersionToString(version_);
-    EXPECT_DFATAL(framer_.ProcessPacket(encrypted), expected_error);
-    return;
-  }
-
   EXPECT_TRUE(framer_.ProcessPacket(encrypted));
 
   EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
@@ -2939,23 +2962,52 @@ TEST_P(QuicFramerTest, BlockedFrame) {
   EXPECT_EQ(GG_UINT64_C(0x01020304),
             visitor_.blocked_frame_.stream_id);
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetBlockedFrameSize();
        ++i) {
     string expected_error = "Unable to read stream_id.";
     CheckProcessingFails(
         packet,
-        i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+        i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
         expected_error, QUIC_INVALID_BLOCKED_DATA);
   }
 }
 
+TEST_P(QuicFramerTest, PingFrame) {
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x3C,
+    // connection_id
+    0x10, 0x32, 0x54, 0x76,
+    0x98, 0xBA, 0xDC, 0xFE,
+    // packet sequence number
+    0xBC, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // private flags
+    0x00,
+
+    // frame type (ping frame)
+    0x07,
+  };
+
+  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
+
+  EXPECT_EQ(1u, visitor_.ping_frames_.size());
+
+  // No need to check the PING frame boundaries because it has no payload.
+}
+
 TEST_P(QuicFramerTest, PublicResetPacket) {
   unsigned char packet[] = {
-    // public flags (public reset, 8 byte guid)
+    // public flags (public reset, 8 byte connection_id)
     0x0E,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // message tag (kPRST)
@@ -2983,7 +3035,7 @@ TEST_P(QuicFramerTest, PublicResetPacket) {
   ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
   ASSERT_TRUE(visitor_.public_reset_packet_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.public_reset_packet_->public_header.guid);
+            visitor_.public_reset_packet_->public_header.connection_id);
   EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
   EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789),
@@ -2993,16 +3045,16 @@ TEST_P(QuicFramerTest, PublicResetPacket) {
   EXPECT_TRUE(
       visitor_.public_reset_packet_->client_address.address().empty());
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0; i < arraysize(packet); ++i) {
     string expected_error;
     DVLOG(1) << "iteration: " << i;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
       CheckProcessingFails(packet, i, expected_error,
                            QUIC_INVALID_PACKET_HEADER);
     } else if (i < kPublicResetPacketMessageTagOffset) {
-      expected_error = "Unable to read GUID.";
+      expected_error = "Unable to read ConnectionId.";
       CheckProcessingFails(packet, i, expected_error,
                            QUIC_INVALID_PACKET_HEADER);
     } else {
@@ -3015,9 +3067,9 @@ TEST_P(QuicFramerTest, PublicResetPacket) {
 
 TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) {
   unsigned char packet[] = {
-    // public flags (public reset, 8 byte guid)
+    // public flags (public reset, 8 byte connection_id)
     0x0E,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // message tag (kPRST)
@@ -3049,9 +3101,9 @@ TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) {
 
 TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
   unsigned char packet[] = {
-    // public flags (public reset, 8 byte guid)
+    // public flags (public reset, 8 byte connection_id)
     0x0E,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // message tag (kPRST)
@@ -3087,7 +3139,7 @@ TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
   ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
   ASSERT_TRUE(visitor_.public_reset_packet_.get());
   EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.public_reset_packet_->public_header.guid);
+            visitor_.public_reset_packet_->public_header.connection_id);
   EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
   EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
   EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789),
@@ -3099,16 +3151,16 @@ TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
                 client_address.address()));
   EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port());
 
-  // Now test framing boundaries
+  // Now test framing boundaries.
   for (size_t i = 0; i < arraysize(packet); ++i) {
     string expected_error;
     DVLOG(1) << "iteration: " << i;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
       CheckProcessingFails(packet, i, expected_error,
                            QUIC_INVALID_PACKET_HEADER);
     } else if (i < kPublicResetPacketMessageTagOffset) {
-      expected_error = "Unable to read GUID.";
+      expected_error = "Unable to read ConnectionId.";
       CheckProcessingFails(packet, i, expected_error,
                            QUIC_INVALID_PACKET_HEADER);
     } else {
@@ -3119,66 +3171,11 @@ TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
   }
 }
 
-// TODO(wtc): remove this test when we drop support for QUIC_VERSION_13.
-TEST_P(QuicFramerTest, PublicResetPacketOld) {
-  unsigned char packet[] = {
-    // public flags (public reset, 8 byte guid)
-    0x3E,
-    // guid
-    0x10, 0x32, 0x54, 0x76,
-    0x98, 0xBA, 0xDC, 0xFE,
-    // nonce proof
-    0x89, 0x67, 0x45, 0x23,
-    0x01, 0xEF, 0xCD, 0xAB,
-    // rejected sequence number
-    0xBC, 0x9A, 0x78, 0x56,
-    0x34, 0x12,
-  };
-
-  QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
-  ASSERT_TRUE(visitor_.public_reset_packet_.get());
-  EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
-            visitor_.public_reset_packet_->public_header.guid);
-  EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
-  EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
-  EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789),
-            visitor_.public_reset_packet_->nonce_proof);
-  EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
-            visitor_.public_reset_packet_->rejected_sequence_number);
-  EXPECT_TRUE(
-      visitor_.public_reset_packet_->client_address.address().empty());
-
-  // Now test framing boundaries
-  for (size_t i = 0; i < arraysize(packet); ++i) {
-    string expected_error;
-    DVLOG(1) << "iteration: " << i;
-    if (i < kGuidOffset) {
-      expected_error = "Unable to read public flags.";
-      CheckProcessingFails(packet, i, expected_error,
-                           QUIC_INVALID_PACKET_HEADER);
-    } else if (i < kPublicResetPacketNonceProofOffset) {
-      expected_error = "Unable to read GUID.";
-      CheckProcessingFails(packet, i, expected_error,
-                           QUIC_INVALID_PACKET_HEADER);
-    } else if (i < kPublicResetPacketRejectedSequenceNumberOffset) {
-      expected_error = "Unable to read nonce proof.";
-      CheckProcessingFails(packet, i, expected_error,
-                           QUIC_INVALID_PUBLIC_RST_PACKET);
-    } else {
-      expected_error = "Unable to read rejected sequence number.";
-      CheckProcessingFails(packet, i, expected_error,
-                           QUIC_INVALID_PUBLIC_RST_PACKET);
-    }
-  }
-}
-
 TEST_P(QuicFramerTest, VersionNegotiationPacket) {
   unsigned char packet[] = {
-    // public flags (version, 8 byte guid)
+    // public flags (version, 8 byte connection_id)
     0x3D,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // version tag
@@ -3195,13 +3192,13 @@ TEST_P(QuicFramerTest, VersionNegotiationPacket) {
   EXPECT_EQ(2u, visitor_.version_negotiation_packet_->versions.size());
   EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
 
-  for (size_t i = 0; i <= kPublicFlagsSize + PACKET_8BYTE_GUID; ++i) {
+  for (size_t i = 0; i <= kPublicFlagsSize + PACKET_8BYTE_CONNECTION_ID; ++i) {
     string expected_error;
     QuicErrorCode error_code = QUIC_INVALID_PACKET_HEADER;
-    if (i < kGuidOffset) {
+    if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
     } else if (i < kVersionOffset) {
-      expected_error = "Unable to read GUID.";
+      expected_error = "Unable to read ConnectionId.";
     } else {
       expected_error = "Unable to read supported version in negotiation.";
       error_code = QUIC_INVALID_VERSION_NEGOTIATION_PACKET;
@@ -3212,9 +3209,9 @@ TEST_P(QuicFramerTest, VersionNegotiationPacket) {
 
 TEST_P(QuicFramerTest, FecPacket) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3249,7 +3246,7 @@ TEST_P(QuicFramerTest, FecPacket) {
 
 TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -3263,9 +3260,9 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
   frames.push_back(QuicFrame(&padding_frame));
 
   unsigned char packet[kMaxPacketSize] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3280,13 +3277,12 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
   };
 
   uint64 header_size =
-      GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                           PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
   memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -3296,7 +3292,7 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
 
 TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -3311,9 +3307,9 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
   frames.push_back(QuicFrame(&padding_frame));
 
   unsigned char packet[kMaxPacketSize] = {
-    // public flags (8 byte guid and 4 byte sequence number)
+    // public flags (8 byte connection_id and 4 byte sequence number)
     0x2C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3327,13 +3323,12 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
   };
 
   uint64 header_size =
-      GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                           PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
   memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -3343,7 +3338,7 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
 
 TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -3358,9 +3353,9 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
   frames.push_back(QuicFrame(&padding_frame));
 
   unsigned char packet[kMaxPacketSize] = {
-    // public flags (8 byte guid and 2 byte sequence number)
+    // public flags (8 byte connection_id and 2 byte sequence number)
     0x1C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3374,13 +3369,12 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
   };
 
   uint64 header_size =
-      GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                           PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
   memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -3390,7 +3384,7 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
 
 TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -3405,9 +3399,9 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
   frames.push_back(QuicFrame(&padding_frame));
 
   unsigned char packet[kMaxPacketSize] = {
-    // public flags (8 byte guid and 1 byte sequence number)
+    // public flags (8 byte connection_id and 1 byte sequence number)
     0x0C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3421,13 +3415,12 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
   };
 
   uint64 header_size =
-      GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
+      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                           PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
   memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -3437,7 +3430,7 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
 
 TEST_P(QuicFramerTest, BuildStreamFramePacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -3455,9 +3448,9 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
   frames.push_back(QuicFrame(&stream_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3479,9 +3472,63 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
     'r',  'l',  'd',  '!',
   };
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet",
+                                      data->data(), data->length(),
+                                      AsChars(packet), arraysize(packet));
+}
+
+TEST_P(QuicFramerTest, BuildStreamFramePacketInFecGroup) {
+  QuicPacketHeader header;
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.reset_flag = false;
+  header.public_header.version_flag = false;
+  header.fec_flag = false;
+  header.entropy_flag = true;
+  header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
+  header.is_in_fec_group = IN_FEC_GROUP;
+  header.fec_group = GG_UINT64_C(0x77123456789ABC);
+
+  QuicStreamFrame stream_frame;
+  stream_frame.stream_id = 0x01020304;
+  stream_frame.fin = true;
+  stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
+  stream_frame.data = MakeIOVector("hello world!");
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(&stream_frame));
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x3C,
+    // connection_id
+    0x10, 0x32, 0x54, 0x76,
+    0x98, 0xBA, 0xDC, 0xFE,
+    // packet sequence number
+    0xBC, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // private flags (entropy, is_in_fec_group)
+    0x03,
+    // FEC group
+    0x00,
+    // frame type (stream frame with fin and data length field)
+    0xFF,
+    // stream id
+    0x04, 0x03, 0x02, 0x01,
+    // offset
+    0x54, 0x76, 0x10, 0x32,
+    0xDC, 0xFE, 0x98, 0xBA,
+    // data length (since packet is in an FEC group)
+    0x0C, 0x00,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -3490,7 +3537,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
 
 TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = true;
   header.fec_flag = false;
@@ -3508,9 +3555,9 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
   frames.push_back(QuicFrame(&stream_frame));
 
   unsigned char packet[] = {
-    // public flags (version, 8 byte guid)
+    // public flags (version, 8 byte connection_id)
     0x3D,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // version tag
@@ -3535,9 +3582,8 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
   };
 
   QuicFramerPeer::SetIsServer(&framer_, false);
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -3546,14 +3592,14 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
 
 TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
   QuicPacketPublicHeader header;
-  header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.reset_flag = false;
   header.version_flag = true;
 
   unsigned char packet[] = {
-    // public flags (version, 8 byte guid)
+    // public flags (version, 8 byte connection_id)
     0x0D,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // version tag
@@ -3570,12 +3616,12 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
                                       AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, BuildAckFramePacket) {
-  if (version_ <= QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, BuildAckFramePacketv22) {
+  if (version_ > QUIC_VERSION_22) {
     return;
   }
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -3584,21 +3630,19 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) {
   header.fec_group = 0;
 
   QuicAckFrame ack_frame;
-  ack_frame.received_info.entropy_hash = 0x43;
-  ack_frame.received_info.largest_observed = GG_UINT64_C(0x770123456789ABF);
-  ack_frame.received_info.delta_time_largest_observed = QuicTime::Delta::Zero();
-  ack_frame.received_info.missing_packets.insert(
+  ack_frame.entropy_hash = 0x43;
+  ack_frame.largest_observed = GG_UINT64_C(0x770123456789ABF);
+  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
+  ack_frame.missing_packets.insert(
       GG_UINT64_C(0x770123456789ABE));
-  ack_frame.sent_info.entropy_hash = 0x14;
-  ack_frame.sent_info.least_unacked = GG_UINT64_C(0x770123456789AA0);
 
   QuicFrames frames;
   frames.push_back(QuicFrame(&ack_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3610,11 +3654,6 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) {
     // frame type (ack frame)
     // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
     0x6C,
-    // entropy hash of sent packets till least awaiting - 1.
-    0x14,
-    // least packet sequence number awaiting an ack, delta from sequence number.
-    0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00,
     // entropy hash of all received packets.
     0x43,
     // largest observed packet sequence number
@@ -3632,21 +3671,20 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) {
     0x00,
   };
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
                                       AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, BuildAckFramePacketV14) {
-  if (version_ > QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, BuildAckFramePacket) {
+  if (version_ <= QUIC_VERSION_22) {
     return;
   }
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -3655,21 +3693,19 @@ TEST_P(QuicFramerTest, BuildAckFramePacketV14) {
   header.fec_group = 0;
 
   QuicAckFrame ack_frame;
-  ack_frame.received_info.entropy_hash = 0x43;
-  ack_frame.received_info.largest_observed = GG_UINT64_C(0x770123456789ABF);
-  ack_frame.received_info.delta_time_largest_observed = QuicTime::Delta::Zero();
-  ack_frame.received_info.missing_packets.insert(
+  ack_frame.entropy_hash = 0x43;
+  ack_frame.largest_observed = GG_UINT64_C(0x770123456789ABF);
+  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
+  ack_frame.missing_packets.insert(
       GG_UINT64_C(0x770123456789ABE));
-  ack_frame.sent_info.entropy_hash = 0x14;
-  ack_frame.sent_info.least_unacked = GG_UINT64_C(0x770123456789AA0);
 
   QuicFrames frames;
   frames.push_back(QuicFrame(&ack_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3681,11 +3717,6 @@ TEST_P(QuicFramerTest, BuildAckFramePacketV14) {
     // frame type (ack frame)
     // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
     0x6C,
-    // entropy hash of sent packets till least awaiting - 1.
-    0x14,
-    // least packet sequence number awaiting an ack, delta from sequence number.
-    0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00,
     // entropy hash of all received packets.
     0x43,
     // largest observed packet sequence number
@@ -3693,202 +3724,401 @@ TEST_P(QuicFramerTest, BuildAckFramePacketV14) {
     0x34, 0x12,
     // Zero delta time.
     0x0, 0x0,
+    // num received packets.
+    0x00,
     // num missing packet ranges
     0x01,
     // missing packet delta
     0x01,
     // 0 more missing packets in range.
     0x00,
+    // 0 revived packets.
+    0x00,
   };
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
                                       AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCP) {
-  if (version_ <= QUIC_VERSION_14) {
+// TODO(jri): Add test for tuncated packets in which the original ack frame had
+// revived packets. (In both the large and small packet cases below).
+
+TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacketv22) {
+  if (version_ > QUIC_VERSION_22) {
     return;
   }
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
-  header.entropy_flag = false;
-  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
+  header.entropy_flag = true;
+  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
   header.fec_group = 0;
 
-  QuicCongestionFeedbackFrame congestion_feedback_frame;
-  congestion_feedback_frame.type = kTCP;
-  congestion_feedback_frame.tcp.receive_window = 0x4030;
+  QuicAckFrame ack_frame;
+  // This entropy hash is different from what shows up in the packet below,
+  // since entropy is recomputed by the framer on ack truncation (by
+  // TestEntropyCalculator for this test.)
+  ack_frame.entropy_hash = 0x43;
+  ack_frame.largest_observed = 2 * 300;
+  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
+  for (size_t i = 1; i < 2 * 300; i += 2) {
+    ack_frame.missing_packets.insert(i);
+  }
 
   QuicFrames frames;
-  frames.push_back(QuicFrame(&congestion_feedback_frame));
+  frames.push_back(QuicFrame(&ack_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
+    // private flags (entropy)
+    0x01,
+
+    // frame type (ack frame)
+    // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
+    0x74,
+    // entropy hash of all received packets, set to 1 by TestEntropyCalculator
+    // since ack is truncated.
+    0x01,
+    // 2-byte largest observed packet sequence number.
+    // Expected to be 510 (0x1FE), since only 255 nack ranges can fit.
+    0xFE, 0x01,
+    // Zero delta time.
+    0x0, 0x0,
+    // num missing packet ranges (limited to 255 by size of this field).
+    0xFF,
+    // {missing packet delta, further missing packets in range}
+    // 6 nack ranges x 42 + 3 nack ranges
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    // 0 revived packets.
     0x00,
+  };
+
+  scoped_ptr<QuicPacket> data(
+      framer_.BuildDataPacket(header, frames, kMaxPacketSize).packet);
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet",
+                                      data->data(), data->length(),
+                                      AsChars(packet), arraysize(packet));
+}
+
+TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacket) {
+  if (version_ <= QUIC_VERSION_22) {
+    return;
+  }
+  QuicPacketHeader header;
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.reset_flag = false;
+  header.public_header.version_flag = false;
+  header.fec_flag = false;
+  header.entropy_flag = true;
+  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
+  header.fec_group = 0;
+
+  QuicAckFrame ack_frame;
+  // This entropy hash is different from what shows up in the packet below,
+  // since entropy is recomputed by the framer on ack truncation (by
+  // TestEntropyCalculator for this test.)
+  ack_frame.entropy_hash = 0x43;
+  ack_frame.largest_observed = 2 * 300;
+  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
+  for (size_t i = 1; i < 2 * 300; i += 2) {
+    ack_frame.missing_packets.insert(i);
+  }
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(&ack_frame));
+
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x3C,
+    // connection_id
+    0x10, 0x32, 0x54, 0x76,
+    0x98, 0xBA, 0xDC, 0xFE,
+    // packet sequence number
+    0xA8, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // private flags (entropy)
+    0x01,
+
+    // frame type (ack frame)
+    // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
+    0x74,
+    // entropy hash of all received packets, set to 1 by TestEntropyCalculator
+    // since ack is truncated.
+    0x01,
+    // 2-byte largest observed packet sequence number.
+    // Expected to be 510 (0x1FE), since only 255 nack ranges can fit.
+    0xFE, 0x01,
+    // Zero delta time.
+    0x0, 0x0,
+    // num missing packet ranges (limited to 255 by size of this field).
+    0xFF,
+    // {missing packet delta, further missing packets in range}
+    // 6 nack ranges x 42 + 3 nack ranges
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
 
-    // frame type (congestion feedback frame)
-    0x20,
-    // congestion feedback type (TCP)
+    // 0 revived packets.
     0x00,
-    // TCP receive window
-    0x03, 0x04,
   };
 
   scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+      framer_.BuildDataPacket(header, frames, kMaxPacketSize).packet);
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
                                       AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCPV14) {
-  if (version_ > QUIC_VERSION_14) {
+
+TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacketv22) {
+  if (version_ > QUIC_VERSION_22) {
     return;
   }
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
-  header.entropy_flag = false;
-  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
+  header.entropy_flag = true;
+  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
   header.fec_group = 0;
 
-  QuicCongestionFeedbackFrame congestion_feedback_frame;
-  congestion_feedback_frame.type = kTCP;
-  congestion_feedback_frame.tcp.receive_window = 0x4030;
+  QuicAckFrame ack_frame;
+  // This entropy hash is different from what shows up in the packet below,
+  // since entropy is recomputed by the framer on ack truncation (by
+  // TestEntropyCalculator for this test.)
+  ack_frame.entropy_hash = 0x43;
+  ack_frame.largest_observed = 2 * 300;
+  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
+  for (size_t i = 1; i < 2 * 300; i += 2) {
+    ack_frame.missing_packets.insert(i);
+  }
 
   QuicFrames frames;
-  frames.push_back(QuicFrame(&congestion_feedback_frame));
+  frames.push_back(QuicFrame(&ack_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
-    0x00,
+    // private flags (entropy)
+    0x01,
 
-    // frame type (congestion feedback frame)
-    0x20,
-    // congestion feedback type (TCP)
+    // frame type (ack frame)
+    // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
+    0x74,
+    // entropy hash of all received packets, set to 1 by TestEntropyCalculator
+    // since ack is truncated.
+    0x01,
+    // 2-byte largest observed packet sequence number.
+    // Expected to be 12 (0x0C), since only 6 nack ranges can fit.
+    0x0C, 0x00,
+    // Zero delta time.
+    0x0, 0x0,
+    // num missing packet ranges (limited to 6 by packet size of 37).
+    0x06,
+    // {missing packet delta, further missing packets in range}
+    // 6 nack ranges
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    // 0 revived packets.
     0x00,
-    // accumulated number of lost packets
-    0x00, 0x00,
-    // TCP receive window
-    0x03, 0x04,
   };
 
   scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
-
+      framer_.BuildDataPacket(header, frames, 37u).packet);
+  ASSERT_TRUE(data != nullptr);
+  // Expect 1 byte unused since at least 2 bytes are needed to fit more nacks.
+  EXPECT_EQ(36u, data->length());
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
                                       AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrival) {
-  if (version_ <= QUIC_VERSION_14) {
+TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacket) {
+  if (version_ <= QUIC_VERSION_22) {
     return;
   }
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
-  header.entropy_flag = false;
-  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
+  header.entropy_flag = true;
+  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
   header.fec_group = 0;
 
-  QuicCongestionFeedbackFrame frame;
-  frame.type = kInterArrival;
-  frame.inter_arrival.received_packet_times.insert(
-      make_pair(GG_UINT64_C(0x0123456789ABA),
-                start_.Add(QuicTime::Delta::FromMicroseconds(
-                    GG_UINT64_C(0x07E1D2C3B4A59687)))));
-  frame.inter_arrival.received_packet_times.insert(
-      make_pair(GG_UINT64_C(0x0123456789ABB),
-                start_.Add(QuicTime::Delta::FromMicroseconds(
-                    GG_UINT64_C(0x07E1D2C3B4A59688)))));
-  frame.inter_arrival.received_packet_times.insert(
-      make_pair(GG_UINT64_C(0x0123456789ABD),
-                start_.Add(QuicTime::Delta::FromMicroseconds(
-                    GG_UINT64_C(0x07E1D2C3B4A59689)))));
+  QuicAckFrame ack_frame;
+  // This entropy hash is different from what shows up in the packet below,
+  // since entropy is recomputed by the framer on ack truncation (by
+  // TestEntropyCalculator for this test.)
+  ack_frame.entropy_hash = 0x43;
+  ack_frame.largest_observed = 2 * 300;
+  ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
+  for (size_t i = 1; i < 2 * 300; i += 2) {
+    ack_frame.missing_packets.insert(i);
+  }
+
   QuicFrames frames;
-  frames.push_back(QuicFrame(&frame));
+  frames.push_back(QuicFrame(&ack_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
-    0x00,
+    // private flags (entropy)
+    0x01,
 
-    // frame type (congestion feedback frame)
-    0x20,
-    // congestion feedback type (inter arrival)
+    // frame type (ack frame)
+    // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
+    0x74,
+    // entropy hash of all received packets, set to 1 by TestEntropyCalculator
+    // since ack is truncated.
     0x01,
-    // num received packets
-    0x03,
-    // lowest sequence number
-    0xBA, 0x9A, 0x78, 0x56,
-    0x34, 0x12,
-    // receive time
-    0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0x07,
-    // sequence delta
-    0x01, 0x00,
-    // time delta
-    0x01, 0x00, 0x00, 0x00,
-    // sequence delta (skip one packet)
-    0x03, 0x00,
-    // time delta
-    0x02, 0x00, 0x00, 0x00,
+    // 2-byte largest observed packet sequence number.
+    // Expected to be 12 (0x0C), since only 6 nack ranges can fit.
+    0x0C, 0x00,
+    // Zero delta time.
+    0x0, 0x0,
+    // num missing packet ranges (limited to 6 by packet size of 37).
+    0x06,
+    // {missing packet delta, further missing packets in range}
+    // 6 nack ranges
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    // 0 revived packets.
+    0x00,
   };
 
   scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
-
+      framer_.BuildDataPacket(header, frames, 37u).packet);
+  ASSERT_TRUE(data != nullptr);
+  // Expect 1 byte unused since at least 2 bytes are needed to fit more nacks.
+  EXPECT_EQ(36u, data->length());
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
                                       AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrivalV14) {
-  if (version_ > QUIC_VERSION_14) {
-    return;
-  }
+TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCP) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -3896,27 +4126,17 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrivalV14) {
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
   header.fec_group = 0;
 
-  QuicCongestionFeedbackFrame frame;
-  frame.type = kInterArrival;
-  frame.inter_arrival.received_packet_times.insert(
-      make_pair(GG_UINT64_C(0x0123456789ABA),
-                start_.Add(QuicTime::Delta::FromMicroseconds(
-                    GG_UINT64_C(0x07E1D2C3B4A59687)))));
-  frame.inter_arrival.received_packet_times.insert(
-      make_pair(GG_UINT64_C(0x0123456789ABB),
-                start_.Add(QuicTime::Delta::FromMicroseconds(
-                    GG_UINT64_C(0x07E1D2C3B4A59688)))));
-  frame.inter_arrival.received_packet_times.insert(
-      make_pair(GG_UINT64_C(0x0123456789ABD),
-                start_.Add(QuicTime::Delta::FromMicroseconds(
-                    GG_UINT64_C(0x07E1D2C3B4A59689)))));
+  QuicCongestionFeedbackFrame congestion_feedback_frame;
+  congestion_feedback_frame.type = kTCP;
+  congestion_feedback_frame.tcp.receive_window = 0x4030;
+
   QuicFrames frames;
-  frames.push_back(QuicFrame(&frame));
+  frames.push_back(QuicFrame(&congestion_feedback_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -3927,78 +4147,60 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrivalV14) {
 
     // frame type (congestion feedback frame)
     0x20,
-    // congestion feedback type (inter arrival)
-    0x01,
-    // accumulated_number_of_lost_packets
-    0x00, 0x00,
-    // num received packets
-    0x03,
-    // lowest sequence number
-    0xBA, 0x9A, 0x78, 0x56,
-    0x34, 0x12,
-    // receive time
-    0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0x07,
-    // sequence delta
-    0x01, 0x00,
-    // time delta
-    0x01, 0x00, 0x00, 0x00,
-    // sequence delta (skip one packet)
-    0x03, 0x00,
-    // time delta
-    0x02, 0x00, 0x00, 0x00,
+    // congestion feedback type (TCP)
+    0x00,
+    // TCP receive window
+    0x03, 0x04,
   };
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
                                       AsChars(packet), arraysize(packet));
 }
 
-TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketFixRate) {
+TEST_P(QuicFramerTest, BuildStopWaitingPacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
-  header.entropy_flag = false;
-  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
+  header.entropy_flag = true;
+  header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
   header.fec_group = 0;
 
-  QuicCongestionFeedbackFrame congestion_feedback_frame;
-  congestion_feedback_frame.type = kFixRate;
-  congestion_feedback_frame.fix_rate.bitrate
-      = QuicBandwidth::FromBytesPerSecond(0x04030201);
+  QuicStopWaitingFrame stop_waiting_frame;
+  stop_waiting_frame.entropy_hash = 0x14;
+  stop_waiting_frame.least_unacked = GG_UINT64_C(0x770123456789AA0);
 
   QuicFrames frames;
-  frames.push_back(QuicFrame(&congestion_feedback_frame));
+  frames.push_back(QuicFrame(&stop_waiting_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
+    0xA8, 0x9A, 0x78, 0x56,
     0x34, 0x12,
-    // private flags
-    0x00,
+    // private flags (entropy)
+    0x01,
 
-    // frame type (congestion feedback frame)
-    0x20,
-    // congestion feedback type (fix rate)
-    0x02,
-    // bitrate_in_bytes_per_second;
-    0x01, 0x02, 0x03, 0x04,
+    // frame type (stop waiting frame)
+    0x06,
+    // entropy hash of sent packets till least awaiting - 1.
+    0x14,
+    // least packet sequence number awaiting an ack, delta from sequence number.
+    0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00,
   };
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -4007,7 +4209,7 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketFixRate) {
 
 TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInvalidFeedback) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -4017,83 +4219,21 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInvalidFeedback) {
 
   QuicCongestionFeedbackFrame congestion_feedback_frame;
   congestion_feedback_frame.type =
-      static_cast<CongestionFeedbackType>(kFixRate + 1);
+      static_cast<CongestionFeedbackType>(kTCP + 1);
 
   QuicFrames frames;
   frames.push_back(QuicFrame(&congestion_feedback_frame));
 
   scoped_ptr<QuicPacket> data;
   EXPECT_DFATAL(
-      data.reset(framer_.BuildUnsizedDataPacket(header, frames).packet),
-      "AppendQuicCongestionFeedbackFrame failed");
-  ASSERT_TRUE(data == NULL);
-}
-
-TEST_P(QuicFramerTest, BuildRstFramePacketVersion13) {
-  if (version_ > QUIC_VERSION_13) {
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
-  header.public_header.reset_flag = false;
-  header.public_header.version_flag = false;
-  header.fec_flag = false;
-  header.entropy_flag = false;
-  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.fec_group = 0;
-
-  QuicRstStreamFrame rst_frame;
-  rst_frame.stream_id = 0x01020304;
-  rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
-  rst_frame.error_details = "because I can";
-
-  unsigned char packet[] = {
-    // public flags (8 byte guid)
-    0x3C,
-    // guid
-    0x10, 0x32, 0x54, 0x76,
-    0x98, 0xBA, 0xDC, 0xFE,
-    // packet sequence number
-    0xBC, 0x9A, 0x78, 0x56,
-    0x34, 0x12,
-    // private flags
-    0x00,
-
-    // frame type (rst stream frame)
-    0x01,
-    // stream id
-    0x04, 0x03, 0x02, 0x01,
-    // error code
-    0x08, 0x07, 0x06, 0x05,
-    // error details length
-    0x0d, 0x00,
-    // error details
-    'b',  'e',  'c',  'a',
-    'u',  's',  'e',  ' ',
-    'I',  ' ',  'c',  'a',
-    'n',
-  };
-
-  QuicFrames frames;
-  frames.push_back(QuicFrame(&rst_frame));
-
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
-
-  test::CompareCharArraysWithHexError("constructed packet",
-                                      data->data(), data->length(),
-                                      AsChars(packet), arraysize(packet));
+      data.reset(BuildDataPacket(header, frames)),
+      "AppendCongestionFeedbackFrame failed");
+  ASSERT_TRUE(data == nullptr);
 }
 
 TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
-  if (version_ <= QUIC_VERSION_13) {
-    return;
-  }
-
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -4108,9 +4248,9 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
   rst_frame.byte_offset = 0x0807060504030201;
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4140,9 +4280,8 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
   QuicFrames frames;
   frames.push_back(QuicFrame(&rst_frame));
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -4151,7 +4290,7 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
 
 TEST_P(QuicFramerTest, BuildCloseFramePacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -4167,9 +4306,9 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) {
   frames.push_back(QuicFrame(&close_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4191,9 +4330,8 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) {
     'n',
   };
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -4202,7 +4340,7 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) {
 
 TEST_P(QuicFramerTest, BuildGoAwayPacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -4219,9 +4357,9 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) {
   frames.push_back(QuicFrame(&goaway_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4245,9 +4383,8 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) {
     'n',
   };
 
-  scoped_ptr<QuicPacket> data(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(data != NULL);
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -4256,7 +4393,7 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) {
 
 TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -4272,9 +4409,9 @@ TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
   frames.push_back(QuicFrame(&window_update_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4292,26 +4429,17 @@ TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
     0x44, 0x33, 0x22, 0x11,
   };
 
-  if (version_ > QUIC_VERSION_13) {
-    scoped_ptr<QuicPacket> data(
-        framer_.BuildUnsizedDataPacket(header, frames).packet);
-    ASSERT_TRUE(data != NULL);
-
-    test::CompareCharArraysWithHexError("constructed packet", data->data(),
-                                        data->length(), AsChars(packet),
-                                        arraysize(packet));
-  } else {
-    string expected_error = "Attempt to add a WindowUpdateFrame in " +
-                            QuicVersionToString(version_);
-    EXPECT_DFATAL(framer_.BuildUnsizedDataPacket(header, frames),
-                  expected_error);
-    return;
-  }
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet", data->data(),
+                                      data->length(), AsChars(packet),
+                                      arraysize(packet));
 }
 
 TEST_P(QuicFramerTest, BuildBlockedPacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -4326,9 +4454,9 @@ TEST_P(QuicFramerTest, BuildBlockedPacket) {
   frames.push_back(QuicFrame(&blocked_frame));
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4343,35 +4471,65 @@ TEST_P(QuicFramerTest, BuildBlockedPacket) {
     0x04, 0x03, 0x02, 0x01,
   };
 
-  if (version_ > QUIC_VERSION_13) {
-    scoped_ptr<QuicPacket> data(
-        framer_.BuildUnsizedDataPacket(header, frames).packet);
-    ASSERT_TRUE(data != NULL);
-
-    test::CompareCharArraysWithHexError("constructed packet", data->data(),
-                                        data->length(), AsChars(packet),
-                                        arraysize(packet));
-  } else {
-    string expected_error =
-        "Attempt to add a BlockedFrame in " + QuicVersionToString(version_);
-    EXPECT_DFATAL(framer_.BuildUnsizedDataPacket(header, frames),
-                  expected_error);
-    return;
-  }
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet", data->data(),
+                                      data->length(), AsChars(packet),
+                                      arraysize(packet));
+}
+
+TEST_P(QuicFramerTest, BuildPingPacket) {
+  QuicPacketHeader header;
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.reset_flag = false;
+  header.public_header.version_flag = false;
+  header.fec_flag = false;
+  header.entropy_flag = true;
+  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
+  header.fec_group = 0;
+
+  QuicPingFrame ping_frame;
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(&ping_frame));
+
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x3C,
+    // connection_id
+    0x10, 0x32, 0x54, 0x76,
+    0x98, 0xBA, 0xDC, 0xFE,
+    // packet sequence number
+    0xBC, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // private flags(entropy)
+    0x01,
+
+    // frame type (ping frame)
+    0x07,
+  };
+
+  scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  test::CompareCharArraysWithHexError("constructed packet", data->data(),
+                                      data->length(), AsChars(packet),
+                                      arraysize(packet));
 }
 
 TEST_P(QuicFramerTest, BuildPublicResetPacket) {
   QuicPublicResetPacket reset_packet;
-  reset_packet.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  reset_packet.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   reset_packet.public_header.reset_flag = true;
   reset_packet.public_header.version_flag = false;
   reset_packet.rejected_sequence_number = GG_UINT64_C(0x123456789ABC);
   reset_packet.nonce_proof = GG_UINT64_C(0xABCDEF0123456789);
 
   unsigned char packet[] = {
-    // public flags (public reset, 8 byte GUID)
+    // public flags (public reset, 8 byte ConnectionId)
     0x0E,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // message tag (kPRST)
@@ -4396,7 +4554,7 @@ TEST_P(QuicFramerTest, BuildPublicResetPacket) {
 
   scoped_ptr<QuicEncryptedPacket> data(
       framer_.BuildPublicResetPacket(reset_packet));
-  ASSERT_TRUE(data != NULL);
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -4405,7 +4563,7 @@ TEST_P(QuicFramerTest, BuildPublicResetPacket) {
 
 TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
   QuicPublicResetPacket reset_packet;
-  reset_packet.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  reset_packet.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   reset_packet.public_header.reset_flag = true;
   reset_packet.public_header.version_flag = false;
   reset_packet.rejected_sequence_number = GG_UINT64_C(0x123456789ABC);
@@ -4413,9 +4571,9 @@ TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
   reset_packet.client_address = IPEndPoint(Loopback4(), 0x1234);
 
   unsigned char packet[] = {
-    // public flags (public reset, 8 byte GUID)
+    // public flags (public reset, 8 byte ConnectionId)
     0x0E,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // message tag (kPRST)
@@ -4448,7 +4606,7 @@ TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
 
   scoped_ptr<QuicEncryptedPacket> data(
       framer_.BuildPublicResetPacket(reset_packet));
-  ASSERT_TRUE(data != NULL);
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -4457,7 +4615,7 @@ TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
 
 TEST_P(QuicFramerTest, BuildFecPacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = true;
@@ -4471,9 +4629,9 @@ TEST_P(QuicFramerTest, BuildFecPacket) {
   fec_data.redundancy = "abcdefghijklmnop";
 
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4493,7 +4651,7 @@ TEST_P(QuicFramerTest, BuildFecPacket) {
 
   scoped_ptr<QuicPacket> data(
       framer_.BuildFecPacket(header, fec_data).packet);
-  ASSERT_TRUE(data != NULL);
+  ASSERT_TRUE(data != nullptr);
 
   test::CompareCharArraysWithHexError("constructed packet",
                                       data->data(), data->length(),
@@ -4503,9 +4661,9 @@ TEST_P(QuicFramerTest, BuildFecPacket) {
 TEST_P(QuicFramerTest, EncryptPacket) {
   QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC);
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4525,21 +4683,21 @@ TEST_P(QuicFramerTest, EncryptPacket) {
 
   scoped_ptr<QuicPacket> raw(
       QuicPacket::NewDataPacket(AsChars(packet), arraysize(packet), false,
-                                PACKET_8BYTE_GUID, !kIncludeVersion,
+                                PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER));
   scoped_ptr<QuicEncryptedPacket> encrypted(
       framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw));
 
-  ASSERT_TRUE(encrypted.get() != NULL);
+  ASSERT_TRUE(encrypted.get() != nullptr);
   EXPECT_TRUE(CheckEncryption(sequence_number, raw.get()));
 }
 
 TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
   QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC);
   unsigned char packet[] = {
-    // public flags (version, 8 byte guid)
+    // public flags (version, 8 byte connection_id)
     0x3D,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // version tag
@@ -4561,18 +4719,18 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
 
   scoped_ptr<QuicPacket> raw(
       QuicPacket::NewDataPacket(AsChars(packet), arraysize(packet), false,
-                                PACKET_8BYTE_GUID, kIncludeVersion,
+                                PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
                                 PACKET_6BYTE_SEQUENCE_NUMBER));
   scoped_ptr<QuicEncryptedPacket> encrypted(
       framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw));
 
-  ASSERT_TRUE(encrypted.get() != NULL);
+  ASSERT_TRUE(encrypted.get() != nullptr);
   EXPECT_TRUE(CheckEncryption(sequence_number, raw.get()));
 }
 
-TEST_P(QuicFramerTest, Truncation) {
+TEST_P(QuicFramerTest, AckTruncationLargePacket) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -4580,48 +4738,126 @@ TEST_P(QuicFramerTest, Truncation) {
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
   header.fec_group = 0;
 
-  QuicAckFrame ack_frame;
-  ack_frame.received_info.largest_observed = 601;
-  ack_frame.sent_info.least_unacked = header.packet_sequence_number - 1;
-  for (uint64 i = 1; i < ack_frame.received_info.largest_observed; i += 2) {
-    ack_frame.received_info.missing_packets.insert(i);
+  // Create a packet with just the ack.
+  QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u);
+  QuicFrame frame;
+  frame.type = ACK_FRAME;
+  frame.ack_frame = &ack_frame;
+  QuicFrames frames;
+  frames.push_back(frame);
+
+  // Build an ack packet with truncation due to limit in number of nack ranges.
+  scoped_ptr<QuicPacket> raw_ack_packet(
+      framer_.BuildDataPacket(header, frames, kMaxPacketSize).packet);
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  scoped_ptr<QuicEncryptedPacket> ack_packet(
+      framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
+                            *raw_ack_packet));
+  // Now make sure we can turn our ack packet back into an ack frame.
+  ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_TRUE(processed_ack_frame.is_truncated);
+  EXPECT_EQ(510u, processed_ack_frame.largest_observed);
+  ASSERT_EQ(255u, processed_ack_frame.missing_packets.size());
+  SequenceNumberSet::const_iterator missing_iter =
+      processed_ack_frame.missing_packets.begin();
+  EXPECT_EQ(1u, *missing_iter);
+  SequenceNumberSet::const_reverse_iterator last_missing_iter =
+      processed_ack_frame.missing_packets.rbegin();
+  EXPECT_EQ(509u, *last_missing_iter);
+}
+
+TEST_P(QuicFramerTest, AckTruncationSmallPacketv22) {
+  if (version_ > QUIC_VERSION_22) {
+    return;
   }
+  QuicPacketHeader header;
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.reset_flag = false;
+  header.public_header.version_flag = false;
+  header.fec_flag = false;
+  header.entropy_flag = false;
+  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
+  header.fec_group = 0;
 
-  // Create a packet with just the ack
+  // Create a packet with just the ack.
+  QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u);
   QuicFrame frame;
   frame.type = ACK_FRAME;
   frame.ack_frame = &ack_frame;
   QuicFrames frames;
   frames.push_back(frame);
 
+  // Build an ack packet with truncation due to limit in number of nack ranges.
   scoped_ptr<QuicPacket> raw_ack_packet(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(raw_ack_packet != NULL);
-
+      framer_.BuildDataPacket(header, frames, 500).packet);
+  ASSERT_TRUE(raw_ack_packet != nullptr);
   scoped_ptr<QuicEncryptedPacket> ack_packet(
       framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
                             *raw_ack_packet));
+  // Now make sure we can turn our ack packet back into an ack frame.
+  ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_TRUE(processed_ack_frame.is_truncated);
+  EXPECT_EQ(476u, processed_ack_frame.largest_observed);
+  ASSERT_EQ(238u, processed_ack_frame.missing_packets.size());
+  SequenceNumberSet::const_iterator missing_iter =
+      processed_ack_frame.missing_packets.begin();
+  EXPECT_EQ(1u, *missing_iter);
+  SequenceNumberSet::const_reverse_iterator last_missing_iter =
+      processed_ack_frame.missing_packets.rbegin();
+  EXPECT_EQ(475u, *last_missing_iter);
+}
+
+
+TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
+  if (version_ <= QUIC_VERSION_22) {
+    return;
+  }
+  QuicPacketHeader header;
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.reset_flag = false;
+  header.public_header.version_flag = false;
+  header.fec_flag = false;
+  header.entropy_flag = false;
+  header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
+  header.fec_group = 0;
+
+  // Create a packet with just the ack.
+  QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u);
+  QuicFrame frame;
+  frame.type = ACK_FRAME;
+  frame.ack_frame = &ack_frame;
+  QuicFrames frames;
+  frames.push_back(frame);
 
-  // Now make sure we can turn our ack packet back into an ack frame
+  // Build an ack packet with truncation due to limit in number of nack ranges.
+  scoped_ptr<QuicPacket> raw_ack_packet(
+      framer_.BuildDataPacket(header, frames, 500).packet);
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  scoped_ptr<QuicEncryptedPacket> ack_packet(
+      framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
+                            *raw_ack_packet));
+  // Now make sure we can turn our ack packet back into an ack frame.
   ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  const QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(header.packet_sequence_number - 1,
-            processed_ack_frame.sent_info.least_unacked);
-  EXPECT_TRUE(processed_ack_frame.received_info.is_truncated);
-  EXPECT_EQ(510u, processed_ack_frame.received_info.largest_observed);
-  ASSERT_EQ(255u, processed_ack_frame.received_info.missing_packets.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_TRUE(processed_ack_frame.is_truncated);
+  EXPECT_EQ(476u, processed_ack_frame.largest_observed);
+  ASSERT_EQ(238u, processed_ack_frame.missing_packets.size());
   SequenceNumberSet::const_iterator missing_iter =
-      processed_ack_frame.received_info.missing_packets.begin();
+      processed_ack_frame.missing_packets.begin();
   EXPECT_EQ(1u, *missing_iter);
   SequenceNumberSet::const_reverse_iterator last_missing_iter =
-      processed_ack_frame.received_info.missing_packets.rbegin();
-  EXPECT_EQ(509u, *last_missing_iter);
+      processed_ack_frame.missing_packets.rbegin();
+  EXPECT_EQ(475u, *last_missing_iter);
 }
 
 TEST_P(QuicFramerTest, CleanTruncation) {
   QuicPacketHeader header;
-  header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210);
+  header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
   header.public_header.reset_flag = false;
   header.public_header.version_flag = false;
   header.fec_flag = false;
@@ -4630,28 +4866,26 @@ TEST_P(QuicFramerTest, CleanTruncation) {
   header.fec_group = 0;
 
   QuicAckFrame ack_frame;
-  ack_frame.received_info.largest_observed = 201;
-  ack_frame.sent_info.least_unacked = header.packet_sequence_number - 2;
-  for (uint64 i = 1; i < ack_frame.received_info.largest_observed; ++i) {
-    ack_frame.received_info.missing_packets.insert(i);
+  ack_frame.largest_observed = 201;
+  for (uint64 i = 1; i < ack_frame.largest_observed; ++i) {
+    ack_frame.missing_packets.insert(i);
   }
 
-  // Create a packet with just the ack
+  // Create a packet with just the ack.
   QuicFrame frame;
   frame.type = ACK_FRAME;
   frame.ack_frame = &ack_frame;
   QuicFrames frames;
   frames.push_back(frame);
 
-  scoped_ptr<QuicPacket> raw_ack_packet(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(raw_ack_packet != NULL);
+  scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
 
   scoped_ptr<QuicEncryptedPacket> ack_packet(
       framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
                             *raw_ack_packet));
 
-  // Now make sure we can turn our ack packet back into an ack frame
+  // Now make sure we can turn our ack packet back into an ack frame.
   ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
 
   // Test for clean truncation of the ack by comparing the length of the
@@ -4662,18 +4896,17 @@ TEST_P(QuicFramerTest, CleanTruncation) {
   frames.push_back(frame);
 
   size_t original_raw_length = raw_ack_packet->length();
-  raw_ack_packet.reset(
-      framer_.BuildUnsizedDataPacket(header, frames).packet);
-  ASSERT_TRUE(raw_ack_packet != NULL);
+  raw_ack_packet.reset(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
   EXPECT_EQ(original_raw_length, raw_ack_packet->length());
-  ASSERT_TRUE(raw_ack_packet != NULL);
+  ASSERT_TRUE(raw_ack_packet != nullptr);
 }
 
 TEST_P(QuicFramerTest, EntropyFlagTest) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4706,9 +4939,9 @@ TEST_P(QuicFramerTest, EntropyFlagTest) {
 
 TEST_P(QuicFramerTest, FecEntropyTest) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number
@@ -4743,9 +4976,9 @@ TEST_P(QuicFramerTest, FecEntropyTest) {
 
 TEST_P(QuicFramerTest, StopPacketProcessing) {
   unsigned char packet[] = {
-    // public flags (8 byte guid)
+    // public flags (8 byte connection_id)
     0x3C,
-    // guid
+    // connection_id
     0x10, 0x32, 0x54, 0x76,
     0x98, 0xBA, 0xDC, 0xFE,
     // packet sequence number