From 43228bb2c6f4b75b66eea26a85eea66b186315d0 Mon Sep 17 00:00:00 2001 From: "vitalybuka@chromium.org" Date: Wed, 17 Oct 2012 18:34:09 +0000 Subject: Revert 162462 - Add QuicFramer and friends. Also fixes an unsigned constant problem from 162259. Revert 162263 - Revert 162259 - Add QuicFramer and friends. Review URL: https://chromiumcodereview.appspot.com/11188017 TBR=rch@chromium.org git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162468 0039d316-1c4b-4281-b951-d872f2087c98 --- net/net.gyp | 26 - net/quic/crypto/crypto_framer.cc | 156 --- net/quic/crypto/crypto_framer.h | 106 -- net/quic/crypto/crypto_framer_test.cc | 316 ----- net/quic/crypto/crypto_protocol.cc | 12 - net/quic/crypto/crypto_protocol.h | 45 - net/quic/crypto/null_decrypter.cc | 35 - net/quic/crypto/null_decrypter.h | 28 - net/quic/crypto/null_decrypter_test.cc | 77 -- net/quic/crypto/null_encrypter.cc | 37 - net/quic/crypto/null_encrypter.h | 30 - net/quic/crypto/null_encrypter_test.cc | 56 - net/quic/crypto/quic_decrypter.cc | 21 - net/quic/crypto/quic_decrypter.h | 28 - net/quic/crypto/quic_encrypter.cc | 21 - net/quic/crypto/quic_encrypter.h | 38 - net/quic/quic_data_reader.cc | 173 --- net/quic/quic_data_reader.h | 125 -- net/quic/quic_data_writer.cc | 69 - net/quic/quic_data_writer.h | 94 -- net/quic/quic_framer.cc | 784 ------------ net/quic/quic_framer.h | 214 ---- net/quic/quic_framer_test.cc | 2157 -------------------------------- net/quic/quic_protocol.cc | 39 - net/quic/quic_protocol.h | 422 ------- net/quic/quic_utils.cc | 78 -- net/quic/quic_utils.h | 40 - net/quic/test_tools/quic_test_utils.cc | 140 --- net/quic/test_tools/quic_test_utils.h | 69 - net/quic/uint128.h | 39 - 30 files changed, 5475 deletions(-) delete mode 100644 net/quic/crypto/crypto_framer.cc delete mode 100644 net/quic/crypto/crypto_framer.h delete mode 100644 net/quic/crypto/crypto_framer_test.cc delete mode 100644 net/quic/crypto/crypto_protocol.cc delete mode 100644 net/quic/crypto/crypto_protocol.h delete mode 100644 net/quic/crypto/null_decrypter.cc delete mode 100644 net/quic/crypto/null_decrypter.h delete mode 100644 net/quic/crypto/null_decrypter_test.cc delete mode 100644 net/quic/crypto/null_encrypter.cc delete mode 100644 net/quic/crypto/null_encrypter.h delete mode 100644 net/quic/crypto/null_encrypter_test.cc delete mode 100644 net/quic/crypto/quic_decrypter.cc delete mode 100644 net/quic/crypto/quic_decrypter.h delete mode 100644 net/quic/crypto/quic_encrypter.cc delete mode 100644 net/quic/crypto/quic_encrypter.h delete mode 100644 net/quic/quic_data_reader.cc delete mode 100644 net/quic/quic_data_reader.h delete mode 100644 net/quic/quic_data_writer.cc delete mode 100644 net/quic/quic_data_writer.h delete mode 100644 net/quic/quic_framer.cc delete mode 100644 net/quic/quic_framer.h delete mode 100644 net/quic/quic_framer_test.cc delete mode 100644 net/quic/quic_protocol.cc delete mode 100644 net/quic/quic_protocol.h delete mode 100644 net/quic/quic_utils.cc delete mode 100644 net/quic/quic_utils.h delete mode 100644 net/quic/test_tools/quic_test_utils.cc delete mode 100644 net/quic/test_tools/quic_test_utils.h delete mode 100644 net/quic/uint128.h diff --git a/net/net.gyp b/net/net.gyp index 10c9c0a..0a9270c 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -628,26 +628,6 @@ 'proxy/sync_host_resolver.h', 'proxy/sync_host_resolver_bridge.cc', 'proxy/sync_host_resolver_bridge.h', - 'quic/crypto/crypto_framer.cc', - 'quic/crypto/crypto_framer.h', - 'quic/crypto/crypto_protocol.cc', - 'quic/crypto/crypto_protocol.h', - 'quic/crypto/null_decrypter.cc', - 'quic/crypto/null_encrypter.cc', - 'quic/crypto/quic_decrypter.h', - 'quic/crypto/quic_decrypter.cc', - 'quic/crypto/quic_encrypter.h', - 'quic/crypto/quic_encrypter.cc', - 'quic/quic_data_reader.cc', - 'quic/quic_data_reader.h', - 'quic/quic_data_writer.cc', - 'quic/quic_data_writer.h', - 'quic/quic_framer.cc', - 'quic/quic_framer.h', - 'quic/quic_protocol.cc', - 'quic/quic_protocol.h', - 'quic/quic_utils.cc', - 'quic/quic_utils.h', 'socket/buffered_write_stream_socket.cc', 'socket/buffered_write_stream_socket.h', 'socket/client_socket_factory.cc', @@ -1370,12 +1350,6 @@ 'proxy/proxy_server_unittest.cc', 'proxy/proxy_service_unittest.cc', 'proxy/sync_host_resolver_bridge_unittest.cc', - 'quic/crypto/crypto_framer_test.cc', - 'quic/crypto/null_decrypter_test.cc', - 'quic/crypto/null_encrypter_test.cc', - 'quic/test_tools/quic_test_utils.cc', - 'quic/test_tools/quic_test_utils.h', - 'quic/quic_framer_test.cc', 'socket/buffered_write_stream_socket_unittest.cc', 'socket/client_socket_pool_base_unittest.cc', 'socket/deterministic_socket_data_unittest.cc', diff --git a/net/quic/crypto/crypto_framer.cc b/net/quic/crypto/crypto_framer.cc deleted file mode 100644 index 806b336..0000000 --- a/net/quic/crypto/crypto_framer.cc +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/crypto/crypto_framer.h" - -#include "net/quic/quic_data_reader.h" -#include "net/quic/quic_data_writer.h" -#include "net/quic/quic_protocol.h" - -using base::StringPiece; - -namespace net { - -CryptoFramer::CryptoFramer() - : visitor_(NULL) { - Clear(); -} - -CryptoFramer::~CryptoFramer() {} - -bool CryptoFramer::ProcessInput(StringPiece input) { - DCHECK_EQ(QUIC_NO_ERROR, error_); - if (error_ != QUIC_NO_ERROR) { - return false; - } - // Add this data to the buffer. - buffer_.append(input.data(), input.length()); - QuicDataReader reader(buffer_.data(), buffer_.length()); - - switch (state_) { - case STATE_READING_TAG: - if (reader.BytesRemaining() < sizeof(uint32)) { - break; - } - reader.ReadUInt32(&message_tag_); - state_ = STATE_READING_NUM_ENTRIES; - case STATE_READING_NUM_ENTRIES: - if (reader.BytesRemaining() < sizeof(uint16)) { - break; - } - reader.ReadUInt16(&num_entries_); - if (num_entries_ > kMaxEntries) { - error_ = QUIC_CRYPTO_TOO_MANY_ENTRIES; - return false; - } - state_ = STATE_READING_KEY_TAGS; - case STATE_READING_KEY_TAGS: - if (reader.BytesRemaining() < num_entries_ * sizeof(uint32)) { - break; - } - for (int i = 0; i < num_entries_; ++i) { - CryptoTag tag; - reader.ReadUInt32(&tag); - if (i > 0 && tag <= tags_.back()) { - error_ = QUIC_CRYPTO_TAGS_OUT_OF_ORDER; - return false; - } - tags_.push_back(tag); - } - state_ = STATE_READING_LENGTHS; - case STATE_READING_LENGTHS: - if (reader.BytesRemaining() < num_entries_ * sizeof(uint16)) { - break; - } - values_len_ = 0; - for (int i = 0; i < num_entries_; ++i) { - uint16 len; - reader.ReadUInt16(&len); - tag_length_map_[tags_[i]] = len; - values_len_ += len; - if (len == 0 && i != num_entries_ - 1) { - error_ = QUIC_CRYPTO_INVALID_VALUE_LENGTH; - return false; - } - } - state_ = STATE_READING_VALUES; - case STATE_READING_VALUES: - if (reader.BytesRemaining() < values_len_) { - break; - } - for (int i = 0; i < num_entries_; ++i) { - StringPiece value; - reader.ReadStringPiece(&value, tag_length_map_[tags_[i]]); - tag_value_map_[tags_[i]] = value; - } - CryptoHandshakeMessage message; - message.tag = message_tag_; - message.tag_value_map.swap(tag_value_map_); - visitor_->OnHandshakeMessage(message); - Clear(); - state_ = STATE_READING_TAG; - break; - } - // Save any left over data - buffer_ = reader.PeekRemainingPayload().as_string(); - return true; -} - -bool CryptoFramer::ConstructHandshakeMessage( - const CryptoHandshakeMessage& message, - QuicData** packet) { - if (message.tag_value_map.size() > kMaxEntries) { - return false; - } - size_t len = sizeof(uint32); // message tag - len += sizeof(uint16); // number of map entries - CryptoTagValueMap::const_iterator it = message.tag_value_map.begin(); - while (it != message.tag_value_map.end()) { - len += sizeof(uint32); // tag - len += sizeof(uint16); // value len - len += it->second.length(); // value - if (it->second.length() == 0) { - return false; - } - ++it; - } - if (message.tag_value_map.size() % 2 == 1) { - len += sizeof(uint16); // padding - } - - QuicDataWriter writer(len); - CHECK(writer.WriteUInt32(message.tag)); - CHECK(writer.WriteUInt16(message.tag_value_map.size())); - // Tags - for (it = message.tag_value_map.begin(); - it != message.tag_value_map.end(); ++it) { - CHECK(writer.WriteUInt32(it->first)); - } - // Lengths - for (it = message.tag_value_map.begin(); - it != message.tag_value_map.end(); ++it) { - CHECK(writer.WriteUInt16(it->second.length())); - } - // Possible padding - if (message.tag_value_map.size() % 2 == 1) { - CHECK(writer.WriteUInt16(0xABAB)); - } - // Values - for (it = message.tag_value_map.begin(); - it != message.tag_value_map.end(); ++it) { - CHECK(writer.WriteBytes(it->second.data(), it->second.length())); - } - *packet = new QuicData(writer.take(), len, true); - return true; -} - -void CryptoFramer::Clear() { - tag_value_map_.clear(); - tag_length_map_.clear(); - tags_.clear(); - error_ = QUIC_NO_ERROR; - state_ = STATE_READING_TAG; -} - -} // namespace net diff --git a/net/quic/crypto/crypto_framer.h b/net/quic/crypto/crypto_framer.h deleted file mode 100644 index e52b264..0000000 --- a/net/quic/crypto/crypto_framer.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_CRYPTO_CRYPTO_FRAMER_H_ -#define NET_QUIC_CRYPTO_CRYPTO_FRAMER_H_ - -#include -#include - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_piece.h" -#include "net/base/net_export.h" -#include "net/quic/crypto/crypto_protocol.h" -#include "net/quic/quic_protocol.h" - -namespace net { - -class CryptoFramer; -class QuicDataReader; -class QuicData; - -class NET_EXPORT_PRIVATE CryptoFramerVisitorInterface { - public: - virtual ~CryptoFramerVisitorInterface() {} - - // Called if an error is detected. - virtual void OnError(CryptoFramer* framer) = 0; - - // Called when a complete handshake message has been parsed. - virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0; -}; - -// A class for framing the crypto message that are exchanged in a QUIC session. -class NET_EXPORT_PRIVATE CryptoFramer { - public: - CryptoFramer(); - - virtual ~CryptoFramer(); - - // Set callbacks to be called from the framer. A visitor must be set, or - // else the framer will likely crash. It is acceptable for the visitor - // to do nothing. If this is called multiple times, only the last visitor - // will be used. |visitor| will be owned by the framer. - void set_visitor(CryptoFramerVisitorInterface* visitor) { - visitor_ = visitor; - } - - QuicErrorCode error() const { - return error_; - } - - // Processes input data, which must be delievered in order. Returns - // false if there was an error, and true otherwise. - bool ProcessInput(base::StringPiece input); - - // Serializes |message| into |packet|. Returns false if there was an - // error, and true otherwise. - bool ConstructHandshakeMessage(const CryptoHandshakeMessage& message, - QuicData** packet); - - private: - // Clears per-message state. Does not clear the visitor. - void Clear(); - - void set_error(QuicErrorCode error) { - error_ = error; - } - - enum CryptoFramerState { - STATE_READING_TAG, - STATE_READING_NUM_ENTRIES, - STATE_READING_KEY_TAGS, - STATE_READING_LENGTHS, - STATE_READING_VALUES - }; - - // Visitor to send invoke when messages are parsed. - CryptoFramerVisitorInterface* visitor_; - // Last error. - QuicErrorCode error_; - // Remaining unparsed data. - std::string buffer_; - // Current state of the parsing. - CryptoFramerState state_; - // Tag of the message currently being parsed. - CryptoTag message_tag_; - // Number of entires in the message currently being parsed. - uint16 num_entries_; - // Vector of tags in the message currently being parsed. - std::vector tags_; - // Length of the data associated with each tag in the message currently - // being parsed. - std::map tag_length_map_; - // Length of the data associated with each tag in the message currently - // being parsed. - CryptoTagValueMap tag_value_map_; - // Cumulative length of all values in the message currently being parsed. - size_t values_len_; -}; - -} // namespace net - -#endif // NET_QUIC_CRYPTO_CRYPTO_FRAMER_H_ diff --git a/net/quic/crypto/crypto_framer_test.cc b/net/quic/crypto/crypto_framer_test.cc deleted file mode 100644 index 8a32f26..0000000 --- a/net/quic/crypto/crypto_framer_test.cc +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "net/quic/crypto/crypto_framer.h" -#include "net/quic/crypto/crypto_protocol.h" -#include "net/quic/test_tools/quic_test_utils.h" - -using base::StringPiece; -using std::map; -using std::string; -using std::vector; - -namespace net { - -namespace { - -char* AsChars(unsigned char* data) { - return reinterpret_cast(data); -} - -} // namespace - -namespace test { - -class TestCryptoVisitor : public ::net::CryptoFramerVisitorInterface { - public: - TestCryptoVisitor() - : error_count_(0) { - } - - ~TestCryptoVisitor() {} - - virtual void OnError(CryptoFramer* f) { - LOG(INFO) << "CryptoFramer Error: " << f->error(); - error_count_++; - } - - virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) { - message_tags_.push_back(message.tag); - message_maps_.push_back(map()); - CryptoTagValueMap::const_iterator it = message.tag_value_map.begin(); - while (it != message.tag_value_map.end()) { - message_maps_.back()[it->first] = it->second.as_string(); - ++it; - } - } - - CryptoFramer framer_; - - // Counters from the visitor callbacks. - int error_count_; - - vector message_tags_; - vector > message_maps_; -}; - -} // namespace test - -TEST(CryptoFramerTest, ConstructHandshakeMessage) { - CryptoHandshakeMessage message; - message.tag = 0xFFAA7733; - message.tag_value_map[0x12345678] = "abcdef"; - message.tag_value_map[0x12345679] = "ghijk"; - message.tag_value_map[0x1234567A] = "lmnopqr"; - - unsigned char packet[] = { - // tag - 0x33, 0x77, 0xAA, 0xFF, - // num entires - 0x03, 0x00, - // tag 1 - 0x78, 0x56, 0x34, 0x12, - // tag 2 - 0x79, 0x56, 0x34, 0x12, - // tag 3 - 0x7A, 0x56, 0x34, 0x12, - // len 1 - 0x06, 0x00, - // len 2 - 0x05, 0x00, - // len 3 - 0x07, 0x00, - // padding - 0xAB, 0xAB, - // value 1 - 'a', 'b', 'c', 'd', - 'e', 'f', - // value 2 - 'g', 'h', 'i', 'j', - 'k', - // value 3 - 'l', 'm', 'n', 'o', - 'p', 'q', 'r', - }; - - CryptoFramer framer; - QuicData* data; - EXPECT_TRUE(framer.ConstructHandshakeMessage(message, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) { - CryptoHandshakeMessage message; - message.tag = 0xFFAA7733; - message.tag_value_map[0x12345678] = "abcdef"; - message.tag_value_map[0x12345679] = "ghijk"; - - unsigned char packet[] = { - // tag - 0x33, 0x77, 0xAA, 0xFF, - // num entires - 0x02, 0x00, - // tag 1 - 0x78, 0x56, 0x34, 0x12, - // tag 2 - 0x79, 0x56, 0x34, 0x12, - // len 1 - 0x06, 0x00, - // len 2 - 0x05, 0x00, - // value 1 - 'a', 'b', 'c', 'd', - 'e', 'f', - // value 2 - 'g', 'h', 'i', 'j', - 'k', - }; - - CryptoFramer framer; - QuicData* data; - EXPECT_TRUE(framer.ConstructHandshakeMessage(message, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) { - CryptoHandshakeMessage message; - message.tag = 0xFFAA7733; - for (uint32 key = 1; key <= kMaxEntries + 1; key++) { - message.tag_value_map[key] = "abcdef"; - } - - CryptoFramer framer; - QuicData* data = NULL; - EXPECT_FALSE(framer.ConstructHandshakeMessage(message, &data)); - delete data; -} - - -TEST(CryptoFramerTest, ConstructHandshakeMessageInvalidLength) { - CryptoHandshakeMessage message; - message.tag = 0xFFAA7733; - message.tag_value_map[0x12345678] = ""; - - CryptoFramer framer; - QuicData* data = NULL; - EXPECT_FALSE(framer.ConstructHandshakeMessage(message, &data)); - delete data; -} - -TEST(CryptoFramerTest, EmptyPacket) { - test::TestCryptoVisitor visitor; - CryptoFramer framer; - framer.set_visitor(&visitor); -} - -TEST(CryptoFramerTest, ProcessInput) { - test::TestCryptoVisitor visitor; - CryptoFramer framer; - framer.set_visitor(&visitor); - - unsigned char input[] = { - // tag - 0x33, 0x77, 0xAA, 0xFF, - // num entires - 0x02, 0x00, - // tag 1 - 0x78, 0x56, 0x34, 0x12, - // tag 2 - 0x79, 0x56, 0x34, 0x12, - // len 1 - 0x06, 0x00, - // len 2 - 0x05, 0x00, - // value 1 - 'a', 'b', 'c', 'd', - 'e', 'f', - // value 2 - 'g', 'h', 'i', 'j', - 'k', - }; - - EXPECT_TRUE(framer.ProcessInput(StringPiece(AsChars(input), - arraysize(input)))); - ASSERT_EQ(1u, visitor.message_tags_.size()); - EXPECT_EQ(0xFFAA7733, visitor.message_tags_[0]); - EXPECT_EQ(2u, visitor.message_maps_[0].size()); - EXPECT_EQ("abcdef",visitor.message_maps_[0][0x12345678]); - EXPECT_EQ("ghijk", visitor.message_maps_[0][0x12345679]); -} - -TEST(CryptoFramerTest, ProcessInputIncrementally) { - test::TestCryptoVisitor visitor; - CryptoFramer framer; - framer.set_visitor(&visitor); - - unsigned char input[] = { - // tag - 0x33, 0x77, 0xAA, 0xFF, - // num entires - 0x02, 0x00, - // tag 1 - 0x78, 0x56, 0x34, 0x12, - // tag 2 - 0x79, 0x56, 0x34, 0x12, - // len 1 - 0x06, 0x00, - // len 2 - 0x05, 0x00, - // value 1 - 'a', 'b', 'c', 'd', - 'e', 'f', - // value 2 - 'g', 'h', 'i', 'j', - 'k', - }; - - for (size_t i = 0; i < arraysize(input); i++) { - EXPECT_TRUE(framer.ProcessInput(StringPiece(AsChars(input)+ i, 1))); - } - ASSERT_EQ(1u, visitor.message_tags_.size()); - EXPECT_EQ(0xFFAA7733, visitor.message_tags_[0]); - EXPECT_EQ(2u, visitor.message_maps_[0].size()); - EXPECT_EQ("abcdef",visitor.message_maps_[0][0x12345678]); - EXPECT_EQ("ghijk", visitor.message_maps_[0][0x12345679]); -} - -TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) { - test::TestCryptoVisitor visitor; - CryptoFramer framer; - framer.set_visitor(&visitor); - - unsigned char input[] = { - // tag - 0x33, 0x77, 0xAA, 0xFF, - // num entires - 0x02, 0x00, - // tag 1 - 0x79, 0x56, 0x34, 0x12, - // tag 2 - 0x78, 0x56, 0x34, 0x12, - }; - - EXPECT_FALSE(framer.ProcessInput(StringPiece(AsChars(input), - arraysize(input)))); - EXPECT_EQ(QUIC_CRYPTO_TAGS_OUT_OF_ORDER, framer.error()); -} - -TEST(CryptoFramerTest, ProcessInputTooManyEntries) { - test::TestCryptoVisitor visitor; - CryptoFramer framer; - framer.set_visitor(&visitor); - - unsigned char input[] = { - // tag - 0x33, 0x77, 0xAA, 0xFF, - // num entires - 0xA0, 0x00, - }; - - EXPECT_FALSE(framer.ProcessInput(StringPiece(AsChars(input), - arraysize(input)))); - EXPECT_EQ(QUIC_CRYPTO_TOO_MANY_ENTRIES, framer.error()); -} - -TEST(CryptoFramerTest, ProcessInputInvalidLength) { - test::TestCryptoVisitor visitor; - CryptoFramer framer; - framer.set_visitor(&visitor); - - unsigned char input[] = { - // tag - 0x33, 0x77, 0xAA, 0xFF, - // num entires - 0x02, 0x00, - // tag 1 - 0x78, 0x56, 0x34, 0x12, - // tag 2 - 0x79, 0x56, 0x34, 0x12, - // len 1 - 0x00, 0x00, - // len 2 - 0x05, 0x00, - }; - - EXPECT_FALSE(framer.ProcessInput(StringPiece(AsChars(input), - arraysize(input)))); - EXPECT_EQ(QUIC_CRYPTO_INVALID_VALUE_LENGTH, framer.error()); -} - -} // namespace net diff --git a/net/quic/crypto/crypto_protocol.cc b/net/quic/crypto/crypto_protocol.cc deleted file mode 100644 index ba87906..0000000 --- a/net/quic/crypto/crypto_protocol.cc +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/crypto/crypto_protocol.h" - -namespace net { - -CryptoHandshakeMessage::CryptoHandshakeMessage() {} -CryptoHandshakeMessage::~CryptoHandshakeMessage() {} - -} // namespace net diff --git a/net/quic/crypto/crypto_protocol.h b/net/quic/crypto/crypto_protocol.h deleted file mode 100644 index a9c7083..0000000 --- a/net/quic/crypto/crypto_protocol.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_CRYPTO_CRYPTO_PROTOCOL_H_ -#define NET_QUIC_CRYPTO_CRYPTO_PROTOCOL_H_ - -#include - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/string_piece.h" -#include "net/base/net_export.h" - -namespace net { - -typedef uint32 CryptoTag; -typedef std::map CryptoTagValueMap; -struct NET_EXPORT_PRIVATE CryptoHandshakeMessage { - CryptoHandshakeMessage(); - ~CryptoHandshakeMessage(); - CryptoTag tag; - CryptoTagValueMap tag_value_map; -}; - -// Crypto tags are written to the wire with a big-endian -// representation of the name of the tag. For example -// the client hello tag (CHLO) will be written as the -// following 4 bytes: 'C' 'H' 'L' 'O'. Since it is -// stored in memory as a little endian uint32, we need -// to reverse the order of the bytes. -#define MAKE_TAG(a,b,c,d) (d << 24) + (c << 16) + (b << 8) + a - -const CryptoTag kCHLO = MAKE_TAG('C', 'H', 'L', 'O'); // Client hello -const CryptoTag kSHLO = MAKE_TAG('S', 'H', 'L', 'O'); // Server hello - -// AEAD algorithms -const CryptoTag kNULL = MAKE_TAG('N', 'U', 'L', 'L'); // null algorithm -const CryptoTag kAESH = MAKE_TAG('A', 'E', 'S', 'H'); // AES128 + SHA256 - -const size_t kMaxEntries = 16; // Max number of entries in a message. - -} // namespace net - -#endif // NET_QUIC_CRYPTO_CRYPTO_PROTOCOL_H_ diff --git a/net/quic/crypto/null_decrypter.cc b/net/quic/crypto/null_decrypter.cc deleted file mode 100644 index 072c684..0000000 --- a/net/quic/crypto/null_decrypter.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/crypto/null_decrypter.h" -#include "net/quic/quic_utils.h" -#include "net/quic/quic_data_reader.h" - -using base::StringPiece; -using std::string; - -namespace net { - -QuicData* NullDecrypter::Decrypt(StringPiece associated_data, - StringPiece ciphertext) { - QuicDataReader reader(ciphertext.data(), ciphertext.length()); - - uint128 hash; - if (!reader.ReadUInt128(&hash)) { - return NULL; - } - - StringPiece plaintext = reader.ReadRemainingPayload(); - - // TODO(rch): avoid buffer copy here - string buffer = associated_data.as_string(); - plaintext.AppendToString(&buffer); - - if (hash != QuicUtils::FNV1a_128_Hash(buffer.data(), buffer.length())) { - return NULL; - } - return new QuicData(plaintext.data(), plaintext.length()); -} - -} // namespace net diff --git a/net/quic/crypto/null_decrypter.h b/net/quic/crypto/null_decrypter.h deleted file mode 100644 index 5495092..0000000 --- a/net/quic/crypto/null_decrypter.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_CRYPTO_NULL_DECRYPTER_H_ -#define NET_QUIC_CRYPTO_NULL_DECRYPTER_H_ - -#include "base/compiler_specific.h" -#include "net/base/net_export.h" -#include "net/quic/crypto/quic_decrypter.h" - -namespace net { - -// A NullDecrypter is a QuicDecrypter used before a crypto negotiation -// has occurred. It does not actually decrypt the payload, but does -// verify a hash (fnv128) over both the payload and associated data. -class NET_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter { - public: - virtual ~NullDecrypter() {} - - // QuicDecrypter implementation - virtual QuicData* Decrypt(base::StringPiece associated_data, - base::StringPiece ciphertext) OVERRIDE; -}; - -} // namespace net - -#endif // NET_QUIC_CRYPTO_NULL_DECRYPTER_H_ diff --git a/net/quic/crypto/null_decrypter_test.cc b/net/quic/crypto/null_decrypter_test.cc deleted file mode 100644 index 6c914d7..0000000 --- a/net/quic/crypto/null_decrypter_test.cc +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/crypto/null_decrypter.h" -#include "net/quic/test_tools/quic_test_utils.h" - -using base::StringPiece; - -namespace net { - -namespace test { - -TEST(NullDecrypterTest, Decrypt) { - unsigned char expected[] = { - // fnv hash - 0x07, 0x2d, 0x42, 0xf0, - 0xbe, 0x69, 0x12, 0x3d, - 0x20, 0x80, 0x5f, 0x9a, - 0x84, 0x9d, 0xd6, 0x0a, - /* TODO(rch): replace this when uint128 multiplication is implemented. - 0x47, 0x11, 0xea, 0x5f, - 0xcf, 0x1d, 0x66, 0x5b, - 0xba, 0xf0, 0xbc, 0xfd, - 0x88, 0x79, 0xca, 0x37, - */ - // payload - 'g', 'o', 'o', 'd', - 'b', 'y', 'e', '!', - }; - NullDecrypter decrypter; - scoped_ptr decrypted( - decrypter.Decrypt("hello world!", - StringPiece(reinterpret_cast(expected), - arraysize(expected)))); - ASSERT_TRUE(decrypted.get()); - EXPECT_EQ("goodbye!", decrypted->AsStringPiece()); -} - -TEST(NullDecrypterTest, BadHash) { - unsigned char expected[] = { - // fnv hash - 0x46, 0x11, 0xea, 0x5f, - 0xcf, 0x1d, 0x66, 0x5b, - 0xba, 0xf0, 0xbc, 0xfd, - 0x88, 0x79, 0xca, 0x37, - // payload - 'g', 'o', 'o', 'd', - 'b', 'y', 'e', '!', - }; - NullDecrypter decrypter; - scoped_ptr decrypted( - decrypter.Decrypt("hello world!", - StringPiece(reinterpret_cast(expected), - arraysize(expected)))); - ASSERT_FALSE(decrypted.get()); -} - -TEST(NullDecrypterTest, ShortInput) { - unsigned char expected[] = { - // fnv hash (truncated) - 0x46, 0x11, 0xea, 0x5f, - 0xcf, 0x1d, 0x66, 0x5b, - 0xba, 0xf0, 0xbc, 0xfd, - 0x88, 0x79, 0xca, - }; - NullDecrypter decrypter; - scoped_ptr decrypted( - decrypter.Decrypt("hello world!", - StringPiece(reinterpret_cast(expected), - arraysize(expected)))); - ASSERT_FALSE(decrypted.get()); -} - -} // namespace test - -} // namespace net diff --git a/net/quic/crypto/null_encrypter.cc b/net/quic/crypto/null_encrypter.cc deleted file mode 100644 index fda844b..0000000 --- a/net/quic/crypto/null_encrypter.cc +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/crypto/null_encrypter.h" -#include "net/quic/quic_data_writer.h" -#include "net/quic/quic_utils.h" - -using base::StringPiece; -using std::string; - -namespace net { - -const size_t kHashSize = 16; // size of uint128 serialized - -QuicData* NullEncrypter::Encrypt(StringPiece associated_data, - StringPiece plaintext) { - // TODO(rch): avoid buffer copy here - string buffer = associated_data.as_string(); - plaintext.AppendToString(&buffer); - uint128 hash = QuicUtils::FNV1a_128_Hash(buffer.data(), buffer.length()); - QuicDataWriter writer(plaintext.length() + kHashSize); - writer.WriteUInt128(hash); - writer.WriteBytes(plaintext.data(), plaintext.length()); - size_t len = writer.length(); - return new QuicData(writer.take(), len, true); -} - -size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) { - return ciphertext_size - kHashSize; -} - -size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) { - return plaintext_size + kHashSize; -} - -} // namespace net diff --git a/net/quic/crypto/null_encrypter.h b/net/quic/crypto/null_encrypter.h deleted file mode 100644 index e73423d..0000000 --- a/net/quic/crypto/null_encrypter.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_CRYPTO_NULL_ENCRYPTER_H_ -#define NET_QUIC_CRYPTO_NULL_ENCRYPTER_H_ - -#include "base/compiler_specific.h" -#include "net/base/net_export.h" -#include "net/quic/crypto/quic_encrypter.h" - -namespace net { - -// A NullEncrypter is a QuicEncrypter used before a crypto negotiation -// has occurred. It does not actually encrypt the payload, but does -// generate a MAC (fnv128) over both the payload and associated data. -class NET_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter { - public: - virtual ~NullEncrypter() {} - - // QuicEncrypter implementation - virtual QuicData* Encrypt(base::StringPiece associated_data, - base::StringPiece plaintext) OVERRIDE; - virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) OVERRIDE; - virtual size_t GetCiphertextSize(size_t plaintext_size) OVERRIDE; -}; - -} // namespace net - -#endif // NET_QUIC_CRYPTO_NULL_ENCRYPTER_H_ diff --git a/net/quic/crypto/null_encrypter_test.cc b/net/quic/crypto/null_encrypter_test.cc deleted file mode 100644 index a71ee34..0000000 --- a/net/quic/crypto/null_encrypter_test.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/crypto/null_encrypter.h" -#include "net/quic/test_tools/quic_test_utils.h" - -using base::StringPiece; - -namespace net { - -namespace test { - -TEST(NullEncrypterTest, Encrypt) { - unsigned char expected[] = { - // fnv hash - 0x07, 0x2d, 0x42, 0xf0, - 0xbe, 0x69, 0x12, 0x3d, - 0x20, 0x80, 0x5f, 0x9a, - 0x84, 0x9d, 0xd6, 0x0a, - /* TODO(rch): use this when uint128 multiplication is implemented. - 0x47, 0x11, 0xea, 0x5f, - 0xcf, 0x1d, 0x66, 0x5b, - 0xba, 0xf0, 0xbc, 0xfd, - 0x88, 0x79, 0xca, 0x37, - */ - // payload - 'g', 'o', 'o', 'd', - 'b', 'y', 'e', '!', - }; - NullEncrypter encrypter; - scoped_ptr encrypted(encrypter.Encrypt("hello world!", - "goodbye!")); - ASSERT_TRUE(encrypted.get()); - test::CompareCharArraysWithHexError( - "encrypted data", encrypted->data(), encrypted->length(), - reinterpret_cast(expected), arraysize(expected)); -} - -TEST(NullEncrypterTest, GetMaxPlaintextSize) { - NullEncrypter encrypter; - EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016)); - EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116)); - EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26)); -} - -TEST(NullEncrypterTest, GetCiphertextSize) { - NullEncrypter encrypter; - EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000)); - EXPECT_EQ(116u, encrypter.GetCiphertextSize(100)); - EXPECT_EQ(26u, encrypter.GetCiphertextSize(10)); -} - -} // namespace test - -} // namespace net diff --git a/net/quic/crypto/quic_decrypter.cc b/net/quic/crypto/quic_decrypter.cc deleted file mode 100644 index 997a311..0000000 --- a/net/quic/crypto/quic_decrypter.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/crypto/quic_decrypter.h" -#include "net/quic/crypto/null_decrypter.h" - -namespace net { - -// static -QuicDecrypter* QuicDecrypter::Create(CryptoTag algorithm) { - switch (algorithm) { - case kNULL: - return new NullDecrypter(); - default: - LOG(FATAL) << "Unsupported algorithm: " << algorithm; - return NULL; - } -} - -} // namespace net diff --git a/net/quic/crypto/quic_decrypter.h b/net/quic/crypto/quic_decrypter.h deleted file mode 100644 index e5c5635..0000000 --- a/net/quic/crypto/quic_decrypter.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_CRYPTO_QUIC_DECRYPTER_H_ -#define NET_QUIC_CRYPTO_QUIC_DECRYPTER_H_ - -#include "net/base/net_export.h" -#include "net/quic/crypto/crypto_protocol.h" -#include "net/quic/quic_protocol.h" - -namespace net { - -class NET_EXPORT_PRIVATE QuicDecrypter { - public: - virtual ~QuicDecrypter() {} - - static QuicDecrypter* Create(CryptoTag algorithm); - - // Returns a newly created QuicData object containing the decrypted - // |ciphertext| or NULL if there is an error. - virtual QuicData* Decrypt(base::StringPiece associated_data, - base::StringPiece ciphertext) = 0; -}; - -} // namespace net - -#endif // NET_QUIC_CRYPTO_QUIC_DECRYPTER_H_ diff --git a/net/quic/crypto/quic_encrypter.cc b/net/quic/crypto/quic_encrypter.cc deleted file mode 100644 index cc13013..0000000 --- a/net/quic/crypto/quic_encrypter.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/crypto/quic_encrypter.h" -#include "net/quic/crypto/null_encrypter.h" - -namespace net { - -// static -QuicEncrypter* QuicEncrypter::Create(CryptoTag algorithm) { - switch (algorithm) { - case kNULL: - return new NullEncrypter(); - default: - LOG(FATAL) << "Unsupported algorithm: " << algorithm; - return NULL; - } -} - -} // namespace net diff --git a/net/quic/crypto/quic_encrypter.h b/net/quic/crypto/quic_encrypter.h deleted file mode 100644 index f077c1f..0000000 --- a/net/quic/crypto/quic_encrypter.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_CRYPTO_QUIC_ENCRYPTER_H_ -#define NET_QUIC_CRYPTO_QUIC_ENCRYPTER_H_ - -#include "net/base/net_export.h" -#include "net/quic/crypto/crypto_protocol.h" -#include "net/quic/quic_protocol.h" - -namespace net { - -class NET_EXPORT_PRIVATE QuicEncrypter { - public: - virtual ~QuicEncrypter() {} - - static QuicEncrypter* Create(CryptoTag algorithm); - - // Returns a newly created QuicData object containing the encrypted - // |plaintext| as well as a MAC over both |plaintext| and |associated_data|, - // or NULL if there is an error. - virtual QuicData* Encrypt(base::StringPiece associated_data, - base::StringPiece plaintext) = 0; - - // Returns the maximum length of plaintext that can be encrypted - // to ciphertext no larger than |ciphertext_size|. - virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) = 0; - - // Returns the length of the ciphertext that would be generated by encrypting - // to plaintext of size |plaintext_size|. - virtual size_t GetCiphertextSize(size_t plaintext_size) = 0; - -}; - -} // namespace net - -#endif // NET_QUIC_CRYPTO_QUIC_ENCRYPTER_H_ diff --git a/net/quic/quic_data_reader.cc b/net/quic/quic_data_reader.cc deleted file mode 100644 index 263bafb..0000000 --- a/net/quic/quic_data_reader.cc +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/quic_data_reader.h" - -using base::StringPiece; - -namespace net { - -QuicDataReader::QuicDataReader(const char* data, const size_t len) - : data_(data), - len_(len), - pos_(0) { -} - -bool QuicDataReader::ReadUInt16(uint16* result) { - // Make sure that we have the whole uint16. - // TODO(rch): use sizeof instead of magic numbers. - // Refactor to use a common Read(void* buffer, size_t len) - // method that will do the memcpy and the advancement of pos_. - if (!CanRead(2)) { - OnFailure(); - return false; - } - - // Read into result. - memcpy(result, data_ + pos_, 2); - - // Iterate. - pos_ += 2; - - return true; -} - -bool QuicDataReader::ReadUInt32(uint32* result) { - // Make sure that we have the whole uint32. - if (!CanRead(4)) { - OnFailure(); - return false; - } - - // Read into result. - memcpy(result, data_ + pos_, 4); - - // Iterate. - pos_ += 4; - - return true; -} - -bool QuicDataReader::ReadUInt48(uint64* result) { - uint32 lo; - if (!ReadUInt32(&lo)) { - return false; - } - - uint16 hi; - if (!ReadUInt16(&hi)) { - return false; - } - - *result = hi; - *result <<= 32; - *result += lo; - - return true; -} - -bool QuicDataReader::ReadUInt64(uint64* result) { - // Make sure that we have the whole uint64. - if (!CanRead(8)) { - OnFailure(); - return false; - } - - // Read into result. - memcpy(result, data_ + pos_, 8); - - // Iterate. - pos_ += 8; - - return true; -} - -bool QuicDataReader::ReadUInt128(uint128* result) { - uint64 high_hash; - uint64 low_hash; - - if (!ReadUInt64(&low_hash)) { - return false; - } - if (!ReadUInt64(&high_hash)) { - return false; - } - - *result = uint128(high_hash, low_hash); - return true; -} - -bool QuicDataReader::ReadStringPiece16(StringPiece* result) { - // Read resultant length. - uint16 result_len; - if (!ReadUInt16(&result_len)) { - // OnFailure() already called. - return false; - } - - return ReadStringPiece(result, result_len); -} - -bool QuicDataReader::ReadBytes(void* result, size_t size) { - // Make sure that we have enough data to read. - if (!CanRead(size)) { - OnFailure(); - return false; - } - - // Read into result. - memcpy(result, data_ + pos_, size); - - // Iterate. - pos_ += size; - - return true; -} - - -bool QuicDataReader::ReadStringPiece(StringPiece* result, size_t size) { - // Make sure that we have enough data to read. - if (!CanRead(size)) { - OnFailure(); - return false; - } - - // Set result. - result->set(data_ + pos_, size); - - // Iterate. - pos_ += size; - - return true; -} - -StringPiece QuicDataReader::PeekRemainingPayload() { - return StringPiece(data_ + pos_, len_ - pos_); -} - -StringPiece QuicDataReader::ReadRemainingPayload() { - StringPiece payload = PeekRemainingPayload(); - pos_ = len_; - return payload; -} - -bool QuicDataReader::IsDoneReading() const { - return len_ == pos_; -} - -size_t QuicDataReader::BytesRemaining() const { - return len_ - pos_; -} - -bool QuicDataReader::CanRead(size_t bytes) const { - return bytes <= (len_ - pos_); -} - -void QuicDataReader::OnFailure() { - // Set our iterator to the end of the buffer so that further reads fail - // immediately. - pos_ = len_; -} - -} // namespace net diff --git a/net/quic/quic_data_reader.h b/net/quic/quic_data_reader.h deleted file mode 100644 index c03c0a9..0000000 --- a/net/quic/quic_data_reader.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_QUIC_DATA_READER_H_ -#define NET_QUIC_QUIC_DATA_READER_H_ - -#include "base/basictypes.h" -#include "base/string_piece.h" -#include "net/base/net_export.h" -#include "net/quic/uint128.h" - -namespace net { - -// Used for reading QUIC data. Though there isn't really anything terribly -// QUIC-specific here, it's a helper class that's useful when doing QUIC -// framing. -// -// To use, simply construct a QuicDataReader using the underlying buffer that -// you'd like to read fields from, then call one of the Read*() methods to -// actually do some reading. -// -// This class keeps an internal iterator to keep track of what's already been -// read and each successive Read*() call automatically increments said iterator -// on success. On failure, internal state of the QuicDataReader should not be -// trusted and it is up to the caller to throw away the failed instance and -// handle the error as appropriate. None of the Read*() methods should ever be -// called after failure, as they will also fail immediately. -class NET_EXPORT_PRIVATE QuicDataReader { - public: - // Caller must provide an underlying buffer to work on. - QuicDataReader(const char* data, const size_t len); - - // Empty destructor. - ~QuicDataReader() {} - - // Reads a 16-bit unsigned integer into the given output parameter. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadUInt16(uint16* result); - - // Reads a 32-bit unsigned integer into the given output parameter. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadUInt32(uint32* result); - - // Reads a 48-bit unsigned integer into the given output parameter. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadUInt48(uint64* result); - - // Reads a 64-bit unsigned integer into the given output parameter. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadUInt64(uint64* result); - - // Reads a 128-bit unsigned integer into the given output parameter. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadUInt128(uint128* result); - // Reads a string prefixed with 16-bit length into the given output parameter. - // - // NOTE: Does not copy but rather references strings in the underlying buffer. - // This should be kept in mind when handling memory management! - // - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadStringPiece16(base::StringPiece* result); - - // Reads a given number of bytes into the given buffer. The buffer - // must be of adequate size. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadStringPiece(base::StringPiece* result, size_t len); - - // Returns the remaining payload as a StringPiece. - // - // NOTE: Does not copy but rather references strings in the underlying buffer. - // This should be kept in mind when handling memory management! - // - // Forwards the internal iterator. - base::StringPiece ReadRemainingPayload(); - - // Returns the remaining payload as a StringPiece. - // - // NOTE: Does not copy but rather references strings in the underlying buffer. - // This should be kept in mind when handling memory management! - // - // DOES NOT forward the internal iterator. - base::StringPiece PeekRemainingPayload(); - - // Reads a given number of bytes into the given buffer. The buffer - // must be of adequate size. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadBytes(void* result, size_t size); - - // Returns true if the entirety of the underlying buffer has been read via - // Read*() calls. - bool IsDoneReading() const; - - // Returns the number of bytes remaining to be read. - size_t BytesRemaining() const; - - private: - // Returns true if the underlying buffer has enough room to read the given - // amount of bytes. - bool CanRead(size_t bytes) const; - - // To be called when a read fails for any reason. - void OnFailure(); - - // The data buffer that we're reading from. - const char* data_; - - // The length of the data buffer that we're reading from. - const size_t len_; - - // The location of the next read from our data buffer. - size_t pos_; -}; - -} // namespace net - -#endif // NET_QUIC_QUIC_DATA_READER_H_ diff --git a/net/quic/quic_data_writer.cc b/net/quic/quic_data_writer.cc deleted file mode 100644 index f76b253..0000000 --- a/net/quic/quic_data_writer.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/quic_data_writer.h" - -#include -#include - -#include "base/basictypes.h" -#include "base/logging.h" -#include "net/quic/quic_protocol.h" - -using std::numeric_limits; - -namespace net { - -QuicDataWriter::QuicDataWriter(size_t size) - : buffer_(new char[size]), - capacity_(size), - length_(0) { -} - -QuicDataWriter::~QuicDataWriter() { - delete[] buffer_; -} - -char* QuicDataWriter::BeginWrite(size_t length) { - if (capacity_ - length_ < length) { - return NULL; - } - -#ifdef ARCH_CPU_64_BITS - DCHECK_LE(length, numeric_limits::max()); -#endif - - return buffer_ + length_; -} - -bool QuicDataWriter::AdvancePointer(uint32 len) { - if (!BeginWrite(len)) { - return false; - } - length_ += len; - return true; -} - -bool QuicDataWriter::WriteBytes(const void* data, uint32 data_len) { - char* dest = BeginWrite(data_len); - if (!dest) { - return false; - } - - memcpy(dest, data, data_len); - - length_ += data_len; - return true; -} - -void QuicDataWriter::WriteUint64ToBuffer(uint64 value, char* buffer) { - memcpy(buffer, &value, sizeof(value)); -} - -void QuicDataWriter::WriteUint128ToBuffer(uint128 value, char* buffer) { - WriteUint64ToBuffer(value.lo, buffer); - WriteUint64ToBuffer(value.hi, buffer + sizeof(value.lo)); -} - -} // namespace net diff --git a/net/quic/quic_data_writer.h b/net/quic/quic_data_writer.h deleted file mode 100644 index 2db5eca..0000000 --- a/net/quic/quic_data_writer.h +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_QUIC_DATA_WRITER_H_ -#define NET_QUIC_QUIC_DATA_WRITER_H_ - -#include - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/string_piece.h" -#include "net/base/net_export.h" -#include "net/quic/quic_protocol.h" -#include "net/quic/uint128.h" - -namespace net { - -// This class provides facilities for packing QUIC data. -// -// The QuicDataWriter supports appending primitive values (int, string, etc) -// to a frame instance. The QuicDataWriter grows its internal memory buffer -// dynamically to hold the sequence of primitive values. The internal memory -// buffer is exposed as the "data" of the QuicDataWriter. -class NET_EXPORT_PRIVATE QuicDataWriter { - public: - explicit QuicDataWriter(size_t length); - ~QuicDataWriter(); - - // Returns the size of the QuicDataWriter's data. - size_t length() const { return length_; } - - // Takes the buffer from the QuicDataWriter. - // TODO(rch): move non-trivial methods into .cc file. - char* take() { - char* rv = buffer_; - buffer_ = NULL; - capacity_ = 0; - length_ = 0; - return rv; - } - - // Methods for adding to the payload. These values are appended to the end - // of the QuicDataWriter payload. Note - binary integers are written in - // host byte order (little endian) not network byte order (big endian). - bool WriteUInt8(uint8 value) { - return WriteBytes(&value, sizeof(value)); - } - bool WriteUInt16(uint16 value) { - return WriteBytes(&value, sizeof(value)); - } - bool WriteUInt32(uint32 value) { - return WriteBytes(&value, sizeof(value)); - } - bool WriteUInt48(uint64 value) { - uint32 hi = value >> 32; - uint32 lo = value & 0x00000000FFFFFFFF; - return WriteUInt32(lo) && WriteUInt16(hi); - } - bool WriteUInt64(uint64 value) { - return WriteBytes(&value, sizeof(value)); - } - bool WriteUInt128(uint128 value) { - return WriteUInt64(value.lo) && WriteUInt64(value.hi); - } - - bool AdvancePointer(uint32 len); - - bool WriteBytes(const void* data, uint32 data_len); - - static void WriteUint64ToBuffer(uint64 value, char* buffer); - static void WriteUint128ToBuffer(uint128 value, char* buffer); - - size_t capacity() const { - return capacity_; - } - - protected: - const char* end_of_payload() const { return buffer_ + length_; } - - private: - // Returns the location that the data should be written at, or NULL if there - // is not enough room. Call EndWrite with the returned offset and the given - // length to pad out for the next write. - char* BeginWrite(size_t length); - - char* buffer_; - size_t capacity_; // Allocation size of payload (or -1 if buffer is const). - size_t length_; // Current length of the buffer. -}; - -} // namespace net - -#endif // NET_QUIC_QUIC_DATA_WRITER_H_ diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc deleted file mode 100644 index e392306e2..0000000 --- a/net/quic/quic_framer.cc +++ /dev/null @@ -1,784 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/quic_framer.h" - -#include "base/hash_tables.h" -#include "net/quic/crypto/quic_decrypter.h" -#include "net/quic/crypto/quic_encrypter.h" -#include "net/quic/quic_data_reader.h" -#include "net/quic/quic_data_writer.h" -#include "net/quic/quic_utils.h" - -using base::hash_set; -using base::StringPiece; - -namespace net { - -QuicFramer::QuicFramer(QuicDecrypter* decrypter, QuicEncrypter* encrypter) - : visitor_(NULL), - fec_builder_(NULL), - error_(QUIC_NO_ERROR), - decrypter_(decrypter), - encrypter_(encrypter) { -} - -QuicFramer::~QuicFramer() {} - -bool QuicFramer::ConstructFragementDataPacket( - const QuicPacketHeader& header, - const QuicFragments& fragments, - QuicPacket** packet) { - // Compute the length of the packet. We use "magic numbers" here because - // sizeof(member_) is not necessairly the same as sizeof(member_wire_format). - size_t len = kPacketHeaderSize; - len += 1; // fragment count - for (size_t i = 0; i < fragments.size(); ++i) { - len += 1; // space for the 8 bit type - len += ComputeFragmentPayloadLength(fragments[i]); - } - - QuicDataWriter writer(len); - - if (!WritePacketHeader(header, &writer)) { - return false; - } - - // fragment count - DCHECK_GE(256u, fragments.size()); - if (!writer.WriteUInt8(fragments.size())) { - return false; - } - - for (size_t i = 0; i < fragments.size(); ++i) { - const QuicFragment& fragment = fragments[i]; - if (!writer.WriteUInt8(fragment.type)) { - return false; - } - - switch (fragment.type) { - case STREAM_FRAGMENT: - if (!AppendStreamFragmentPayload(*fragment.stream_fragment, - &writer)) { - return false; - } - break; - case PDU_FRAGMENT: - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - case ACK_FRAGMENT: - if (!AppendAckFragmentPayload(*fragment.ack_fragment, &writer)) { - return false; - } - break; - case RST_STREAM_FRAGMENT: - if (!AppendRstStreamFragmentPayload(*fragment.rst_stream_fragment, - &writer)) { - return false; - } - break; - case CONNECTION_CLOSE_FRAGMENT: - if (!AppendConnectionCloseFragmentPayload( - *fragment.connection_close_fragment, &writer)) { - return false; - } - break; - default: - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - } - } - - *packet = new QuicPacket(writer.take(), len, true); - if (fec_builder_) { - fec_builder_->OnBuiltFecProtectedPayload(header, - (*packet)->FecProtectedData()); - } - - return true; -} - -bool QuicFramer::ConstructFecPacket(const QuicPacketHeader& header, - const QuicFecData& fec, - QuicPacket** packet) { - // Compute the length of the packet. We use "magic numbers" here because - // sizeof(member_) is not necessairly the same as sizeof(member_wire_format). - size_t len = kPacketHeaderSize; - len += 6; // first protected packet sequence number - len += fec.redundancy.length(); - - QuicDataWriter writer(len); - - if (!WritePacketHeader(header, &writer)) { - return false; - } - - if (!writer.WriteUInt48(fec.first_protected_packet_sequence_number)) { - return false; - } - - if (!writer.WriteBytes(fec.redundancy.data(), fec.redundancy.length())) { - return false; - } - - *packet = new QuicPacket(writer.take(), len, true); - - return true; -} - -void QuicFramer::IncrementRetransmitCount(QuicPacket* packet) { - CHECK_GT(packet->length(), kPacketHeaderSize); - - ++packet->mutable_data()[kRetransmissionOffset]; -} - -uint8 QuicFramer::GetRetransmitCount(QuicPacket* packet) { - CHECK_GT(packet->length(), kPacketHeaderSize); - - return packet->mutable_data()[kRetransmissionOffset]; -} - -bool QuicFramer::ProcessPacket(const IPEndPoint& peer_address, - const QuicEncryptedPacket& packet) { - DCHECK(!reader_.get()); - reader_.reset(new QuicDataReader(packet.data(), packet.length())); - visitor_->OnPacket(peer_address); - - // First parse the packet header. - QuicPacketHeader header; - if (!ProcessPacketHeader(&header, packet)) { - DLOG(WARNING) << "Unable to process header."; - return RaiseError(QUIC_INVALID_PACKET_HEADER); - } - - if (!visitor_->OnPacketHeader(header)) { - reader_.reset(NULL); - return true; - } - - if (packet.length() > kMaxPacketSize) { - DLOG(WARNING) << "Packet too large: " << packet.length(); - return RaiseError(QUIC_PACKET_TOO_LARGE); - } - - // Handle the payload. - if ((header.flags & PACKET_FLAGS_FEC) == 0) { - if (header.fec_group != 0) { - StringPiece payload = reader_->PeekRemainingPayload(); - visitor_->OnFecProtectedPayload(payload); - } - if (!ProcessFragmentData()) { - DLOG(WARNING) << "Unable to process fragment data."; - return false; - } - } else { - QuicFecData fec_data; - fec_data.fec_group = header.fec_group; - if (!reader_->ReadUInt48( - &fec_data.first_protected_packet_sequence_number)) { - set_detailed_error("Unable to read first protected packet."); - return false; - } - - fec_data.redundancy = reader_->ReadRemainingPayload(); - visitor_->OnFecData(fec_data); - } - - visitor_->OnPacketComplete(); - reader_.reset(NULL); - return true; -} - -bool QuicFramer::ProcessRevivedPacket(const IPEndPoint& peer_address, - const QuicPacketHeader& header, - StringPiece payload) { - DCHECK(!reader_.get()); - - visitor_->OnPacket(peer_address); - - visitor_->OnPacketHeader(header); - - if (payload.length() > kMaxPacketSize) { - set_detailed_error("Revived packet too large."); - return RaiseError(QUIC_PACKET_TOO_LARGE); - } - - reader_.reset(new QuicDataReader(payload.data(), payload.length())); - if (!ProcessFragmentData()) { - DLOG(WARNING) << "Unable to process fragment data."; - return false; - } - - visitor_->OnPacketComplete(); - reader_.reset(NULL); - return true; -} - -bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header, - QuicDataWriter* writer) { - // ConnectionHeader - if (!writer->WriteUInt64(header.guid)) { - return false; - } - - if (!writer->WriteUInt48(header.packet_sequence_number)) { - return false; - } - - if (!writer->WriteBytes(&header.retransmission_count, 1)) { - return false; - } - - // CongestionMonitoredHeader - if (!writer->WriteUInt64(header.transmission_time)) { - return false; - } - - uint8 flags = static_cast(header.flags); - if (!writer->WriteBytes(&flags, 1)) { - return false; - } - - if (!writer->WriteBytes(&header.fec_group, 1)) { - return false; - } - - return true; -} - -bool QuicFramer::ProcessPacketHeader(QuicPacketHeader* header, - const QuicEncryptedPacket& packet) { - // ConnectionHeader - if (!reader_->ReadUInt64(&header->guid)) { - set_detailed_error("Unable to read GUID."); - return false; - } - - if (!reader_->ReadUInt48(&header->packet_sequence_number)) { - set_detailed_error("Unable to read sequence number."); - return false; - } - - if (!reader_->ReadBytes(&header->retransmission_count, 1)) { - set_detailed_error("Unable to read retransmission count."); - return false; - } - - // CongestionMonitoredHeader - if (!reader_->ReadUInt64(&header->transmission_time)) { - set_detailed_error("Unable to read transmission time."); - return false; - } - - unsigned char flags; - if (!reader_->ReadBytes(&flags, 1)) { - set_detailed_error("Unable to read flags."); - return false; - } - - if (flags > PACKET_FLAGS_MAX) { - set_detailed_error("Illegal flags value."); - return false; - } - - header->flags = static_cast(flags); - - if (!DecryptPayload(packet)) { - DLOG(WARNING) << "Unable to decrypt payload."; - return RaiseError(QUIC_DECRYPTION_FAILURE); - } - - if (!reader_->ReadBytes(&header->fec_group, 1)) { - set_detailed_error("Unable to read fec group."); - return false; - } - - return true; -} - -bool QuicFramer::ProcessFragmentData() { - uint8 fragment_count; - if (!reader_->ReadBytes(&fragment_count, 1)) { - set_detailed_error("Unable to read fragment count."); - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - } - - for (uint8 i = 0; i < fragment_count; ++i) { - uint8 fragment_type; - if (!reader_->ReadBytes(&fragment_type, 1)) { - set_detailed_error("Unable to read fragment type."); - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - } - switch (fragment_type) { - case STREAM_FRAGMENT: - if (!ProcessStreamFragment()) { - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - } - break; - case PDU_FRAGMENT: - if (!ProcessPDUFragment()) { - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - } - break; - case ACK_FRAGMENT: { - QuicAckFragment fragment; - if (!ProcessAckFragment(&fragment)) { - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - } - break; - } - case RST_STREAM_FRAGMENT: - if (!ProcessRstStreamFragment()) { - return RaiseError(QUIC_INVALID_RST_STREAM_DATA); - } - break; - case CONNECTION_CLOSE_FRAGMENT: - if (!ProcessConnectionCloseFragment()) { - return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA); - } - break; - default: - set_detailed_error("Illegal fragment type."); - DLOG(WARNING) << "Illegal fragment type: " << (int)fragment_type; - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - } - } - - return true; -} - -bool QuicFramer::ProcessStreamFragment() { - QuicStreamFragment fragment; - if (!reader_->ReadUInt32(&fragment.stream_id)) { - set_detailed_error("Unable to read stream_id."); - return false; - } - - uint8 fin; - if (!reader_->ReadBytes(&fin, 1)) { - set_detailed_error("Unable to read fin."); - return false; - } - if (fin > 1) { - set_detailed_error("Invalid fin value."); - return false; - } - fragment.fin = (fin == 1); - - if (!reader_->ReadUInt64(&fragment.offset)) { - set_detailed_error("Unable to read offset."); - return false; - } - - if (!reader_->ReadStringPiece16(&fragment.data)) { - set_detailed_error("Unable to read fragment data."); - return false; - } - - visitor_->OnStreamFragment(fragment); - return true; -} - -bool QuicFramer::ProcessPDUFragment() { - return false; -} - -bool QuicFramer::ProcessAckFragment(QuicAckFragment* fragment) { - if (!reader_->ReadUInt48(&fragment->received_info.largest_received)) { - set_detailed_error("Unable to read largest received."); - return false; - } - - if (!reader_->ReadUInt64(&fragment->received_info.time_received)) { - set_detailed_error("Unable to read time received."); - return false; - } - - uint8 num_unacked_packets; - if (!reader_->ReadBytes(&num_unacked_packets, 1)) { - set_detailed_error("Unable to read num unacked packets."); - return false; - } - - for (int i = 0; i < num_unacked_packets; ++i) { - QuicPacketSequenceNumber sequence_number; - if (!reader_->ReadUInt48(&sequence_number)) { - set_detailed_error("Unable to read sequence number in unacked packets."); - return false; - } - fragment->received_info.missing_packets.insert(sequence_number); - } - - if (!reader_->ReadUInt48(&fragment->sent_info.least_unacked)) { - set_detailed_error("Unable to read least unacked."); - return false; - } - - uint8 num_non_retransmiting_packets; - if (!reader_->ReadBytes(&num_non_retransmiting_packets, 1)) { - set_detailed_error("Unable to read num non-retransmitting."); - return false; - } - for (uint8 i = 0; i < num_non_retransmiting_packets; ++i) { - QuicPacketSequenceNumber sequence_number; - if (!reader_->ReadUInt48(&sequence_number)) { - set_detailed_error( - "Unable to read sequence number in non-retransmitting."); - return false; - } - fragment->sent_info.non_retransmiting.insert(sequence_number); - } - - uint8 congestion_info_type; - if (!reader_->ReadBytes(&congestion_info_type, 1)) { - set_detailed_error("Unable to read congestion info type."); - return false; - } - fragment->congestion_info.type = - static_cast(congestion_info_type); - - switch (fragment->congestion_info.type) { - case kNone: - break; - case kInterArrival: { - CongestionFeedbackMessageInterArrival* inter_arrival = - &fragment->congestion_info.inter_arrival; - if (!reader_->ReadUInt16( - &inter_arrival->accumulated_number_of_lost_packets)) { - set_detailed_error( - "Unable to read accumulated number of lost packets."); - return false; - } - if (!reader_->ReadBytes(&inter_arrival->offset_time, 2)) { - set_detailed_error("Unable to read offset time."); - return false; - } - if (!reader_->ReadUInt16(&inter_arrival->delta_time)) { - set_detailed_error("Unable to read delta time."); - return false; - } - break; - } - case kFixRate: { - CongestionFeedbackMessageFixRate* fix_rate = - &fragment->congestion_info.fix_rate; - if (!reader_->ReadUInt32(&fix_rate->bitrate_in_bytes_per_second)) { - set_detailed_error("Unable to read bitrate."); - return false; - } - break; - } - case kTCP: { - CongestionFeedbackMessageTCP* tcp = &fragment->congestion_info.tcp; - if (!reader_->ReadUInt16(&tcp->accumulated_number_of_lost_packets)) { - set_detailed_error( - "Unable to read accumulated number of lost packets."); - return false; - } - if (!reader_->ReadUInt16(&tcp->receive_window)) { - set_detailed_error("Unable to read receive window."); - return false; - } - break; - } - default: - set_detailed_error("Illegal congestion info type."); - DLOG(WARNING) << "Illegal congestion info type: " - << fragment->congestion_info.type; - return RaiseError(QUIC_INVALID_FRAGMENT_DATA); - } - - visitor_->OnAckFragment(*fragment); - return true; -} - -bool QuicFramer::ProcessRstStreamFragment() { - QuicRstStreamFragment fragment; - if (!reader_->ReadUInt32(&fragment.stream_id)) { - set_detailed_error("Unable to read stream_id."); - return false; - } - - if (!reader_->ReadUInt64(&fragment.offset)) { - set_detailed_error("Unable to read offset in rst fragment."); - return false; - } - - uint32 details; - if (!reader_->ReadUInt32(&details)) { - set_detailed_error("Unable to read rst stream details."); - return false; - } - fragment.details = static_cast(details); - - visitor_->OnRstStreamFragment(fragment); - return true; -} - -bool QuicFramer::ProcessConnectionCloseFragment() { - QuicConnectionCloseFragment fragment; - - uint32 details; - if (!reader_->ReadUInt32(&details)) { - set_detailed_error("Unable to read connection close details."); - return false; - } - fragment.details = static_cast(details); - - if (!ProcessAckFragment(&fragment.ack_fragment)) { - DLOG(WARNING) << "Unable to process ack fragment."; - return false; - } - - visitor_->OnConnectionCloseFragment(fragment); - return true; -} - -void QuicFramer::WriteTransmissionTime(QuicTransmissionTime time, - QuicPacket* packet) { - QuicDataWriter::WriteUint64ToBuffer( - time, packet->mutable_data() + kTransmissionTimeOffset); -} - -QuicEncryptedPacket* QuicFramer::EncryptPacket(const QuicPacket& packet) { - scoped_ptr out(encrypter_->Encrypt(packet.AssociatedData(), - packet.Plaintext())); - if (out.get() == NULL) { - RaiseError(QUIC_ENCRYPTION_FAILURE); - return NULL; - } - size_t len = kStartOfEncryptedData + out->length(); - char* buffer = new char[len]; - // TODO(rch): eliminate this buffer copy by passing in a buffer to Encrypt(). - memcpy(buffer, packet.data(), kStartOfEncryptedData); - memcpy(buffer + kStartOfEncryptedData, out->data(), out->length()); - return new QuicEncryptedPacket(buffer, len, true); -} - -size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) { - return encrypter_->GetMaxPlaintextSize(ciphertext_size); -} - -bool QuicFramer::DecryptPayload(const QuicEncryptedPacket& packet) { - StringPiece encrypted; - if (!reader_->ReadStringPiece(&encrypted, reader_->BytesRemaining())) { - return false; - } - DCHECK(decrypter_.get() != NULL); - decrypted_.reset(decrypter_->Decrypt(packet.AssociatedData(), encrypted)); - if (decrypted_.get() == NULL) { - return false; - } - - reader_.reset(new QuicDataReader(decrypted_->data(), decrypted_->length())); - return true; -} - -size_t QuicFramer::ComputeFragmentPayloadLength(const QuicFragment& fragment) { - size_t len = 0; - // We use "magic numbers" here because sizeof(member_) is not necessairly the - // same as sizeof(member_wire_format). - switch (fragment.type) { - case STREAM_FRAGMENT: - len += 4; // stream id - len += 1; // fin - len += 8; // offset - len += 2; // space for the 16 bit length - len += fragment.stream_fragment->data.size(); - break; - case PDU_FRAGMENT: - DLOG(INFO) << "PDU_FRAGMENT not yet supported"; - break; // Need to support this eventually :> - case ACK_FRAGMENT: { - const QuicAckFragment& ack = *fragment.ack_fragment; - len += 6; // largest received packet sequence number - len += 8; // time delta - len += 1; // num missing packets - len += 6 * ack.received_info.missing_packets.size(); - len += 6; // least packet sequence number awaiting an ack - len += 1; // num non retransmitting packets - len += 6 * ack.sent_info.non_retransmiting.size(); - len += 1; // congestion control type - switch (ack.congestion_info.type) { - case kNone: - break; - case kInterArrival: - len += 6; - break; - case kFixRate: - len += 4; - break; - case kTCP: - len += 4; - break; - default: - set_detailed_error("Illegal feedback type."); - DLOG(INFO) << "Illegal feedback type: " << ack.congestion_info.type; - break; - } - break; - } - case RST_STREAM_FRAGMENT: - len += 4; // stream id - len += 8; // offset - len += 4; // details - break; - case CONNECTION_CLOSE_FRAGMENT: - len += 4; // details - len += ComputeFragmentPayloadLength( - QuicFragment(&fragment.connection_close_fragment->ack_fragment)); - break; - default: - set_detailed_error("Illegal fragment type."); - DLOG(INFO) << "Illegal fragment type: " << fragment.type; - break; - } - return len; -} - -bool QuicFramer::AppendStreamFragmentPayload( - const QuicStreamFragment& fragment, - QuicDataWriter* writer) { - if (!writer->WriteUInt32(fragment.stream_id)) { - return false; - } - if (!writer->WriteUInt8(fragment.fin)) { - return false; - } - if (!writer->WriteUInt64(fragment.offset)) { - return false; - } - if (!writer->WriteUInt16(fragment.data.size())) { - return false; - } - if (!writer->WriteBytes(fragment.data.data(), - fragment.data.size())) { - return false; - } - return true; -} - -bool QuicFramer::AppendAckFragmentPayload( - const QuicAckFragment& fragment, - QuicDataWriter* writer) { - if (!writer->WriteUInt48(fragment.received_info.largest_received)) { - return false; - } - if (!writer->WriteUInt64(fragment.received_info.time_received)) { - return false; - } - - size_t num_unacked_packets = fragment.received_info.missing_packets.size(); - if (!writer->WriteBytes(&num_unacked_packets, 1)) { - return false; - } - - hash_set::const_iterator it = - fragment.received_info.missing_packets.begin(); - for (; it != fragment.received_info.missing_packets.end(); ++it) { - if (!writer->WriteUInt48(*it)) { - return false; - } - } - - if (!writer->WriteUInt48(fragment.sent_info.least_unacked)) { - return false; - } - - size_t num_non_retransmiting_packets = - fragment.sent_info.non_retransmiting.size(); - if (!writer->WriteBytes(&num_non_retransmiting_packets, 1)) { - return false; - } - - it = fragment.sent_info.non_retransmiting.begin(); - while (it != fragment.sent_info.non_retransmiting.end()) { - if (!writer->WriteUInt48(*it)) { - return false; - } - ++it; - } - - if (!writer->WriteBytes(&fragment.congestion_info.type, 1)) { - return false; - } - - switch (fragment.congestion_info.type) { - case kNone: - break; - case kInterArrival: { - const CongestionFeedbackMessageInterArrival& inter_arrival = - fragment.congestion_info.inter_arrival; - if (!writer->WriteUInt16( - inter_arrival.accumulated_number_of_lost_packets)) { - return false; - } - if (!writer->WriteBytes(&inter_arrival.offset_time, 2)) { - return false; - } - if (!writer->WriteUInt16(inter_arrival.delta_time)) { - return false; - } - break; - } - case kFixRate: { - const CongestionFeedbackMessageFixRate& fix_rate = - fragment.congestion_info.fix_rate; - if (!writer->WriteUInt32(fix_rate.bitrate_in_bytes_per_second)) { - return false; - } - break; - } - case kTCP: { - const CongestionFeedbackMessageTCP& tcp = fragment.congestion_info.tcp; - if (!writer->WriteUInt16(tcp.accumulated_number_of_lost_packets)) { - return false; - } - if (!writer->WriteUInt16(tcp.receive_window)) { - return false; - } - break; - } - default: - return false; - } - - return true; -} - -bool QuicFramer::AppendRstStreamFragmentPayload( - const QuicRstStreamFragment& fragment, - QuicDataWriter* writer) { - if (!writer->WriteUInt32(fragment.stream_id)) { - return false; - } - if (!writer->WriteUInt64(fragment.offset)) { - return false; - } - - uint32 details = static_cast(fragment.details); - if (!writer->WriteUInt32(details)) { - return false; - } - return true; -} - -bool QuicFramer::AppendConnectionCloseFragmentPayload( - const QuicConnectionCloseFragment& fragment, - QuicDataWriter* writer) { - uint32 details = static_cast(fragment.details); - if (!writer->WriteUInt32(details)) { - return false; - } - AppendAckFragmentPayload(fragment.ack_fragment, writer); - return true; -} - -bool QuicFramer::RaiseError(QuicErrorCode error) { - DLOG(INFO) << detailed_error_; - set_error(error); - visitor_->OnError(this); - reader_.reset(NULL); - return false; -} - -} // namespace net diff --git a/net/quic/quic_framer.h b/net/quic/quic_framer.h deleted file mode 100644 index 648ae7d5..0000000 --- a/net/quic/quic_framer.h +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_QUIC_FRAMER_H_ -#define NET_QUIC_QUIC_FRAMER_H_ - -#include - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_piece.h" -#include "net/base/ip_endpoint.h" -#include "net/base/net_export.h" -#include "net/quic/crypto/quic_decrypter.h" -#include "net/quic/crypto/quic_encrypter.h" - -namespace net { - -class QuicEncrypter; -class QuicDecrypter; -class QuicFramer; -class QuicDataReader; -class QuicDataWriter; - -// Class that receives callbacks from the framer when packets -// are processed. -class NET_EXPORT_PRIVATE QuicFramerVisitorInterface { - public: - virtual ~QuicFramerVisitorInterface() {} - - // Called if an error is detected in the QUIC protocol. - virtual void OnError(QuicFramer* framer) = 0; - - // Called when a new packet has been recieved, before it - // has been validated or processed. - virtual void OnPacket(const IPEndPoint& peer_address) = 0; - - // Called when the header of a packet had been parsed. - // If OnPacketHeader returns false, framing for this packet will cease. - virtual bool OnPacketHeader(const QuicPacketHeader& header) = 0; - - // Called when a data packet is parsed that is part of an FEC group. - // |payload| is the non-encrypted FEC protected payload of the packet. - virtual void OnFecProtectedPayload(base::StringPiece payload) = 0; - - // Called when a StreamFragment has been parsed. - virtual void OnStreamFragment(const QuicStreamFragment& fragment) = 0; - - // Called when a AckFragment has been parsed. - virtual void OnAckFragment(const QuicAckFragment& fragment) = 0; - - // Called when a RstStreamFragment has been parsed. - virtual void OnRstStreamFragment( - const QuicRstStreamFragment& fragment) = 0; - - // Called when a ConnectionCloseFragment has been parsed. - virtual void OnConnectionCloseFragment( - const QuicConnectionCloseFragment& fragment) = 0; - - // Called when FEC data has been parsed. - virtual void OnFecData(const QuicFecData& fec) = 0; - - // Called when a packet has been completely processed. - virtual void OnPacketComplete() = 0; -}; - -class NET_EXPORT_PRIVATE QuicFecBuilderInterface { - public: - virtual ~QuicFecBuilderInterface() {} - - // Called when a data packet is constructed that is part of an FEC group. - // |payload| is the non-encrypted FEC protected payload of the packet. - virtual void OnBuiltFecProtectedPayload(const QuicPacketHeader& header, - base::StringPiece payload) = 0; -}; - -// Class for parsing and constructing QUIC packets. Has a -// QuicFramerVisitorInterface that is called when packets are parsed. -// Also has a QuicFecBuilder that is called when packets are constructed -// in order to generate FEC data for subsequently building FEC packets. -class NET_EXPORT_PRIVATE QuicFramer { - public: - // Constructs a new framer that will own |decrypter| and |encrypter|. - QuicFramer(QuicDecrypter* decrypter, QuicEncrypter* encrypter); - - virtual ~QuicFramer(); - - // Set callbacks to be called from the framer. A visitor must be set, or - // else the framer will likely crash. It is acceptable for the visitor - // to do nothing. If this is called multiple times, only the last visitor - // will be used. - void set_visitor(QuicFramerVisitorInterface* visitor) { - visitor_ = visitor; - } - - // Set a builder to be called from the framer when building FEC protected - // packets. If this is called multiple times, only the last builder - // will be used. The builder need not be set. - void set_fec_builder(QuicFecBuilderInterface* builder) { - fec_builder_ = builder; - } - - QuicErrorCode error() const { - return error_; - } - - // Pass a UDP packet into the framer for parsing. - // Return true if the packet was processed succesfully. |packet| must be a - // single, complete UDP packet (not a fragment of a packet). This packet - // might be null padded past the end of the payload, which will be correctly - // ignored. - bool ProcessPacket(const IPEndPoint& client_address, - const QuicEncryptedPacket& packet); - - // Pass a data packet that was revived from FEC data into the framer - // for parsing. - // Return true if the packet was processed succesfully. |payload| must be - // the complete DECRYPTED payload of the revived packet. - bool ProcessRevivedPacket(const IPEndPoint& client_address, - const QuicPacketHeader& header, - base::StringPiece payload); - - // Creates a new QuicPacket populated with the fields in |header| and - // |fragments|. Assigns |*packet| to the address of the new object. - // Returns true upon success. - bool ConstructFragementDataPacket(const QuicPacketHeader& header, - const QuicFragments& fragments, - QuicPacket** packet); - - // Creates a new QuicPacket populated with the fields in |header| and - // |fec|. Assigns |*packet| to the address of the new object. - // Returns true upon success. - bool ConstructFecPacket(const QuicPacketHeader& header, - const QuicFecData& fec, - QuicPacket** packet); - - // Increments the retransmission count by one, and updates the authentication - // hash accordingly. - void IncrementRetransmitCount(QuicPacket* packet); - - uint8 GetRetransmitCount(QuicPacket* packet); - - void WriteTransmissionTime(QuicTransmissionTime time, QuicPacket* packet); - - // Returns a new encrypted packet, owned by the caller. - QuicEncryptedPacket* EncryptPacket(const QuicPacket& packet); - - // Returns the maximum length of plaintext that can be encrypted - // to ciphertext no larger than |ciphertext_size|. - size_t GetMaxPlaintextSize(size_t ciphertext_size); - - const std::string& detailed_error() { return detailed_error_; } - - private: - bool WritePacketHeader(const QuicPacketHeader& header, - QuicDataWriter* builder); - - bool ProcessPacketHeader(QuicPacketHeader* header, - const QuicEncryptedPacket& packet); - - bool ProcessFragmentData(); - bool ProcessStreamFragment(); - bool ProcessPDUFragment(); - bool ProcessAckFragment(QuicAckFragment* fragment); - bool ProcessRstStreamFragment(); - bool ProcessConnectionCloseFragment(); - - bool DecryptPayload(const QuicEncryptedPacket& packet); - - // Computes the wire size in bytes of the payload of |fragment|. - size_t ComputeFragmentPayloadLength(const QuicFragment& fragment); - - bool AppendStreamFragmentPayload( - const QuicStreamFragment& fragment, - QuicDataWriter* builder); - bool AppendAckFragmentPayload( - const QuicAckFragment& fragment, - QuicDataWriter* builder); - bool AppendRstStreamFragmentPayload( - const QuicRstStreamFragment& fragment, - QuicDataWriter* builder); - bool AppendConnectionCloseFragmentPayload( - const QuicConnectionCloseFragment& fragment, - QuicDataWriter* builder); - bool RaiseError(QuicErrorCode error); - - void set_error(QuicErrorCode error) { - error_ = error; - } - - void set_detailed_error(const char* error) { - detailed_error_ = error; - } - - std::string detailed_error_; - scoped_ptr reader_; - QuicFramerVisitorInterface* visitor_; - QuicFecBuilderInterface* fec_builder_; - QuicErrorCode error_; - // Buffer containing decrypted payload data during parsing. - scoped_ptr decrypted_; - // Decrypter used to decrypt packets during parsing. - scoped_ptr decrypter_; - // Encrypter used to encrypt packets via EncryptPacket(). - scoped_ptr encrypter_; - - DISALLOW_COPY_AND_ASSIGN(QuicFramer); -}; - -} // namespace net - -#endif // NET_QUIC_QUIC_FRAMER_H_ diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc deleted file mode 100644 index 884f708..0000000 --- a/net/quic/quic_framer_test.cc +++ /dev/null @@ -1,2157 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include "base/hash_tables.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/stl_util.h" -#include "net/quic/quic_framer.h" -#include "net/quic/quic_protocol.h" -#include "net/quic/quic_utils.h" -#include "net/quic/test_tools/quic_test_utils.h" - -using base::hash_set; -using base::StringPiece; -using std::string; -using std::vector; - -namespace net { - -namespace test { - -class TestEncrypter : public QuicEncrypter { - public: - virtual ~TestEncrypter() {} - virtual QuicData* Encrypt(StringPiece associated_data, - StringPiece plaintext) { - associated_data_ = associated_data.as_string(); - plaintext_ = plaintext.as_string(); - return new QuicData(plaintext.data(), plaintext.length()); - } - virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) { - return ciphertext_size; - } - virtual size_t GetCiphertextSize(size_t plaintext_size) { - return plaintext_size; - } - string associated_data_; - string plaintext_; -}; - -class TestDecrypter : public QuicDecrypter { - public: - virtual ~TestDecrypter() {} - virtual QuicData* Decrypt(StringPiece associated_data, - StringPiece ciphertext) { - associated_data_ = associated_data.as_string(); - ciphertext_ = ciphertext.as_string(); - return new QuicData(ciphertext.data(), ciphertext.length()); - } - string associated_data_; - string ciphertext_; -}; - -// The offset of congestion info in our tests, given the size of our usual ack -// fragment. This does NOT work for all packets. -const int kCongestionInfoOffset = kPacketHeaderSize + 54; - -class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { - public: - TestQuicVisitor() - : error_count_(0), - packet_count_(0), - fragment_count_(0), - fec_count_(0), - complete_packets_(0), - accept_packet_(true) { - } - - ~TestQuicVisitor() { - STLDeleteElements(&stream_fragments_); - STLDeleteElements(&ack_fragments_); - STLDeleteElements(&fec_data_); - } - - virtual void OnError(QuicFramer* f) { - DLOG(INFO) << "QuicFramer Error: " << QuicUtils::ErrorToString(f->error()) - << " (" << f->error() << ")"; - error_count_++; - } - - virtual void OnPacket(const IPEndPoint& client_address) { - address_ = client_address; - } - - virtual bool OnPacketHeader(const QuicPacketHeader& header) { - packet_count_++; - header_.reset(new QuicPacketHeader(header)); - return accept_packet_; - } - - virtual void OnStreamFragment(const QuicStreamFragment& fragment) { - fragment_count_++; - stream_fragments_.push_back(new QuicStreamFragment(fragment)); - } - - virtual void OnFecProtectedPayload(StringPiece payload) { - fec_protected_payload_ = payload.as_string(); - } - - virtual void OnAckFragment(const QuicAckFragment& fragment) { - fragment_count_++; - ack_fragments_.push_back(new QuicAckFragment(fragment)); - } - - virtual void OnFecData(const QuicFecData& fec) { - fec_count_++; - fec_data_.push_back(new QuicFecData(fec)); - } - - virtual void OnPacketComplete() { - complete_packets_++; - } - - virtual void OnRstStreamFragment(const QuicRstStreamFragment& fragment) { - rst_stream_fragment_ = fragment; - } - - virtual void OnConnectionCloseFragment( - const QuicConnectionCloseFragment& fragment) { - connection_close_fragment_ = fragment; - } - - // Counters from the visitor_ callbacks. - int error_count_; - int packet_count_; - int fragment_count_; - int fec_count_; - int complete_packets_; - bool accept_packet_; - - IPEndPoint address_; - scoped_ptr header_; - vector stream_fragments_; - vector ack_fragments_; - vector fec_data_; - string fec_protected_payload_; - QuicRstStreamFragment rst_stream_fragment_; - QuicConnectionCloseFragment connection_close_fragment_; -}; - -class QuicFramerTest : public ::testing::Test { - public: - QuicFramerTest() - : encrypter_(new test::TestEncrypter()), - decrypter_(new test::TestDecrypter()), - framer_(decrypter_, encrypter_) { - framer_.set_visitor(&visitor_); - } - - bool CheckEncryption(StringPiece packet) { - StringPiece associated_data( - packet.substr(kStartOfHashData, - kStartOfEncryptedData - kStartOfHashData)); - if (associated_data != encrypter_->associated_data_) { - LOG(ERROR) << "Encrypted incorrect associated data. expected " - << associated_data << " actual: " - << encrypter_->associated_data_; - return false; - } - StringPiece plaintext(packet.substr(kStartOfEncryptedData)); - if (plaintext != encrypter_->plaintext_) { - LOG(ERROR) << "Encrypted incorrect plaintext data. expected " - << plaintext << " actual: " - << encrypter_->plaintext_; - return false; - } - return true; - } - - bool CheckDecryption(StringPiece packet) { - StringPiece associated_data( - packet.substr(kStartOfHashData, - kStartOfEncryptedData - kStartOfHashData)); - if (associated_data != decrypter_->associated_data_) { - LOG(ERROR) << "Decrypted incorrect associated data. expected " - << associated_data << " actual: " - << decrypter_->associated_data_; - return false; - } - StringPiece plaintext(packet.substr(kStartOfEncryptedData)); - if (plaintext != decrypter_->ciphertext_) { - LOG(ERROR) << "Decrypted incorrect chipertext data. expected " - << plaintext << " actual: " - << decrypter_->ciphertext_; - return false; - } - return true; - } - - char* AsChars(unsigned char* data) { - return reinterpret_cast(data); - } - - test::TestEncrypter* encrypter_; - test::TestDecrypter* decrypter_; - QuicFramer framer_; - test::TestQuicVisitor visitor_; - IPEndPoint address_; -}; - -TEST_F(QuicFramerTest, EmptyPacket) { - char packet[] = { 0x00 }; - EXPECT_FALSE(framer_.ProcessPacket(address_, - QuicEncryptedPacket(packet, 0, false))); - EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); -} - -TEST_F(QuicFramerTest, LargePacket) { - unsigned char packet[kMaxPacketSize + 1] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - // fragment count - 0x01, - }; - - memset(packet + kPacketHeaderSize, 0, kMaxPacketSize - kPacketHeaderSize + 1); - - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - ASSERT_TRUE(visitor_.header_.get()); - // Make sure we've parsed the packet header, so we can send an error. - EXPECT_EQ(0xFEDCBA9876543210, visitor_.header_->guid); - // Make sure the correct error is propogated. - EXPECT_EQ(QUIC_PACKET_TOO_LARGE, framer_.error()); -} - -TEST_F(QuicFramerTest, PacketHeader) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - }; - - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_EQ(QUIC_INVALID_FRAGMENT_DATA, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - EXPECT_EQ(0xFEDCBA9876543210, visitor_.header_->guid); - EXPECT_EQ(0x1, visitor_.header_->retransmission_count); - EXPECT_EQ(static_cast(0x123456789ABC), - visitor_.header_->packet_sequence_number); - EXPECT_EQ(static_cast(0xF0E1D2C3B4A59687), - visitor_.header_->transmission_time); - EXPECT_EQ(0x00, visitor_.header_->flags); - EXPECT_EQ(0x00, visitor_.header_->fec_group); - - // Now test framing boundaries - for (int i = 0; i < 25; ++i) { - string expected_error; - if (i < 8) { - expected_error = "Unable to read GUID."; - } else if (i < 14) { - expected_error = "Unable to read sequence number."; - } else if (i < 15) { - expected_error = "Unable to read retransmission count."; - } else if (i < 23) { - expected_error = "Unable to read transmission time."; - } else if (i < 24) { - expected_error = "Unable to read flags."; - } else if (i < 25) { - expected_error = "Unable to read fec group."; - } - - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), i, false))); - EXPECT_EQ(expected_error, framer_.detailed_error()); - EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); - } -} - -TEST_F(QuicFramerTest, StreamFragment) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (stream fragment) - 0x00, - // stream id - 0x04, 0x03, 0x02, 0x01, - // fin - 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // data length - 0x0c, 0x00, - // data - 'h', 'e', 'l', 'l', - 'o', ' ', 'w', 'o', - 'r', 'l', 'd', '!', - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - ASSERT_EQ(address_, visitor_.address_); - - ASSERT_EQ(1u, visitor_.stream_fragments_.size()); - EXPECT_EQ(0u, visitor_.ack_fragments_.size()); - EXPECT_EQ(static_cast(0x01020304), - visitor_.stream_fragments_[0]->stream_id); - EXPECT_TRUE(visitor_.stream_fragments_[0]->fin); - EXPECT_EQ(0xBA98FEDC32107654, visitor_.stream_fragments_[0]->offset); - EXPECT_EQ("hello world!", visitor_.stream_fragments_[0]->data); - - // Now test framing boundaries - for (size_t i = kPacketHeaderSize; i < kPacketHeaderSize + 29; ++i) { - string expected_error; - if (i < kPacketHeaderSize + 1) { - expected_error = "Unable to read fragment count."; - } else if (i < kPacketHeaderSize + 2) { - expected_error = "Unable to read fragment type."; - } else if (i < kPacketHeaderSize + 6) { - expected_error = "Unable to read stream_id."; - } else if (i < kPacketHeaderSize + 7) { - expected_error = "Unable to read fin."; - } else if (i < kPacketHeaderSize + 15) { - expected_error = "Unable to read offset."; - } else if (i < kPacketHeaderSize + 29) { - expected_error = "Unable to read fragment data."; - } - - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), i, false))); - EXPECT_EQ(expected_error, framer_.detailed_error()); - EXPECT_EQ(QUIC_INVALID_FRAGMENT_DATA, framer_.error()); - } -} - -TEST_F(QuicFramerTest, RejectPacket) { - visitor_.accept_packet_ = false; - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (stream fragment) - 0x00, - // stream id - 0x04, 0x03, 0x02, 0x01, - // fin - 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // data length - 0x0c, 0x00, - // data - 'h', 'e', 'l', 'l', - 'o', ' ', 'w', 'o', - 'r', 'l', 'd', '!', - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - ASSERT_EQ(address_, visitor_.address_); - - ASSERT_EQ(0u, visitor_.stream_fragments_.size()); - EXPECT_EQ(0u, visitor_.ack_fragments_.size()); -} - -TEST_F(QuicFramerTest, RevivedStreamFragment) { - unsigned char payload[] = { - // fragment count - 0x01, - // fragment type (stream fragment) - 0x00, - // stream id - 0x04, 0x03, 0x02, 0x01, - // fin - 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // data length - 0x0c, 0x00, - // data - 'h', 'e', 'l', 'l', - 'o', ' ', 'w', 'o', - 'r', 'l', 'd', '!', - }; - - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - // Do not encrypt the payload because the revived payload is post-encryption. - EXPECT_TRUE(framer_.ProcessRevivedPacket(address_, - header, - StringPiece(AsChars(payload), - arraysize(payload)))); - - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_EQ(address_, visitor_.address_); - ASSERT_TRUE(visitor_.header_.get()); - EXPECT_EQ(0xFEDCBA9876543210, visitor_.header_->guid); - EXPECT_EQ(0x1, visitor_.header_->retransmission_count); - EXPECT_EQ(static_cast(0x123456789ABC), - visitor_.header_->packet_sequence_number); - EXPECT_EQ(static_cast(0xF0E1D2C3B4A59687), - visitor_.header_->transmission_time); - EXPECT_EQ(0x00, visitor_.header_->flags); - EXPECT_EQ(0x00, visitor_.header_->fec_group); - - - ASSERT_EQ(1u, visitor_.stream_fragments_.size()); - EXPECT_EQ(0u, visitor_.ack_fragments_.size()); - EXPECT_EQ(static_cast(0x01020304), - visitor_.stream_fragments_[0]->stream_id); - EXPECT_TRUE(visitor_.stream_fragments_[0]->fin); - EXPECT_EQ(0xBA98FEDC32107654, visitor_.stream_fragments_[0]->offset); - EXPECT_EQ("hello world!", visitor_.stream_fragments_[0]->data); -} - -TEST_F(QuicFramerTest, StreamFragmentInFecGroup) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x12, 0x34, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x02, - - // fragment count - 0x01, - // fragment type (stream fragment) - 0x00, - // stream id - 0x04, 0x03, 0x02, 0x01, - // fin - 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // data length - 0x0c, 0x00, - // data - 'h', 'e', 'l', 'l', - 'o', ' ', 'w', 'o', - 'r', 'l', 'd', '!', - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - EXPECT_EQ(2, visitor_.header_->fec_group); - EXPECT_EQ(string(AsChars(packet) + kStartOfFecProtectedData, - arraysize(packet) - kStartOfFecProtectedData), - visitor_.fec_protected_payload_); - ASSERT_EQ(address_, visitor_.address_); - - ASSERT_EQ(1u, visitor_.stream_fragments_.size()); - EXPECT_EQ(0u, visitor_.ack_fragments_.size()); - EXPECT_EQ(static_cast(0x01020304), - visitor_.stream_fragments_[0]->stream_id); - EXPECT_TRUE(visitor_.stream_fragments_[0]->fin); - EXPECT_EQ(0xBA98FEDC32107654, visitor_.stream_fragments_[0]->offset); - EXPECT_EQ("hello world!", visitor_.stream_fragments_[0]->data); -} - -TEST_F(QuicFramerTest, AckFragment) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // congestion feedback type (none) - 0x00, - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - - EXPECT_EQ(0u, visitor_.stream_fragments_.size()); - ASSERT_EQ(1u, visitor_.ack_fragments_.size()); - const QuicAckFragment& fragment = *visitor_.ack_fragments_[0]; - EXPECT_EQ(static_cast(0x0123456789ABC), - fragment.received_info.largest_received); - EXPECT_EQ(0xF0E1D2C3B4A59687, fragment.received_info.time_received); - - const hash_set* sequence_nums = - &fragment.received_info.missing_packets; - ASSERT_EQ(2u, sequence_nums->size()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABB) != sequence_nums->end()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABA) != sequence_nums->end()); - EXPECT_EQ(static_cast(0x0123456789AA0), - fragment.sent_info.least_unacked); - ASSERT_EQ(3u, fragment.sent_info.non_retransmiting.size()); - const hash_set* non_retrans = - &fragment.sent_info.non_retransmiting; - EXPECT_TRUE(non_retrans->find(0x0123456789AB0) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAF) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAE) != non_retrans->end()); - ASSERT_EQ(kNone, fragment.congestion_info.type); - - // Now test framing boundaries - for (size_t i = kPacketHeaderSize; i < kPacketHeaderSize + 55; ++i) { - string expected_error; - if (i < kPacketHeaderSize + 1) { - expected_error = "Unable to read fragment count."; - } else if (i < kPacketHeaderSize + 2) { - expected_error = "Unable to read fragment type."; - } else if (i < kPacketHeaderSize + 8) { - expected_error = "Unable to read largest received."; - } else if (i < kPacketHeaderSize + 16) { - expected_error = "Unable to read time received."; - } else if (i < kPacketHeaderSize + 17) { - expected_error = "Unable to read num unacked packets."; - } else if (i < kPacketHeaderSize + 29) { - expected_error = "Unable to read sequence number in unacked packets."; - } else if (i < kPacketHeaderSize + 35) { - expected_error = "Unable to read least unacked."; - } else if (i < kPacketHeaderSize + 36) { - expected_error = "Unable to read num non-retransmitting."; - } else if (i < kPacketHeaderSize + 54) { - expected_error = "Unable to read sequence number in non-retransmitting."; - } else if (i < kPacketHeaderSize + 55) { - expected_error = "Unable to read congestion info type."; - } - - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), i, false))); - EXPECT_EQ(expected_error, framer_.detailed_error()); - EXPECT_EQ(QUIC_INVALID_FRAGMENT_DATA, framer_.error()); - } -} - -TEST_F(QuicFramerTest, AckFragmentTCP) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // congestion feedback type (tcp) - 0x01, - // ack_fragment.congestion_info.tcp.accumulated_number_of_lost_packets - 0x01, 0x02, - // ack_fragment.congestion_info.tcp.receive_window - 0x03, 0x04, - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - - EXPECT_EQ(0u, visitor_.stream_fragments_.size()); - ASSERT_EQ(1u, visitor_.ack_fragments_.size()); - const QuicAckFragment& fragment = *visitor_.ack_fragments_[0]; - EXPECT_EQ(static_cast(0x0123456789ABC), - fragment.received_info.largest_received); - EXPECT_EQ(0xF0E1D2C3B4A59687, fragment.received_info.time_received); - - const hash_set* sequence_nums = - &fragment.received_info.missing_packets; - ASSERT_EQ(2u, sequence_nums->size()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABB) != sequence_nums->end()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABA) != sequence_nums->end()); - EXPECT_EQ(static_cast(0x0123456789AA0), - fragment.sent_info.least_unacked); - ASSERT_EQ(3u, fragment.sent_info.non_retransmiting.size()); - const hash_set* non_retrans = - &fragment.sent_info.non_retransmiting; - EXPECT_TRUE(non_retrans->find(0x0123456789AB0) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAF) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAE) != non_retrans->end()); - ASSERT_EQ(kTCP, fragment.congestion_info.type); - EXPECT_EQ(0x0201, - fragment.congestion_info.tcp.accumulated_number_of_lost_packets); - EXPECT_EQ(0x0403, fragment.congestion_info.tcp.receive_window); - - // Now test framing boundaries - for (size_t i = kCongestionInfoOffset; i < kCongestionInfoOffset + 5; ++i) { - string expected_error; - if (i < kCongestionInfoOffset + 1) { - expected_error = "Unable to read congestion info type."; - } else if (i < kCongestionInfoOffset + 3) { - expected_error = "Unable to read accumulated number of lost packets."; - } else if (i < kCongestionInfoOffset + 5) { - expected_error = "Unable to read receive window."; - } - - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), i, false))); - EXPECT_EQ(expected_error, framer_.detailed_error()); - EXPECT_EQ(QUIC_INVALID_FRAGMENT_DATA, framer_.error()); - } -} - -TEST_F(QuicFramerTest, AckFragmentInterArrival) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // congestion feedback type (inter arrival) - 0x02, - // accumulated_number_of_lost_packets - 0x02, 0x03, - // offset_time - 0x04, 0x05, - // delta_time - 0x06, 0x07, - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - - EXPECT_EQ(0u, visitor_.stream_fragments_.size()); - ASSERT_EQ(1u, visitor_.ack_fragments_.size()); - const QuicAckFragment& fragment = *visitor_.ack_fragments_[0]; - EXPECT_EQ(static_cast(0x0123456789ABC), - fragment.received_info.largest_received); - EXPECT_EQ(0xF0E1D2C3B4A59687, fragment.received_info.time_received); - - const hash_set* sequence_nums = - &fragment.received_info.missing_packets; - ASSERT_EQ(2u, sequence_nums->size()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABB) != sequence_nums->end()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABA) != sequence_nums->end()); - EXPECT_EQ(static_cast(0x0123456789AA0), - fragment.sent_info.least_unacked); - ASSERT_EQ(3u, fragment.sent_info.non_retransmiting.size()); - const hash_set* non_retrans = - &fragment.sent_info.non_retransmiting; - EXPECT_TRUE(non_retrans->find(0x0123456789AB0) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAF) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAE) != non_retrans->end()); - ASSERT_EQ(kInterArrival, fragment.congestion_info.type); - EXPECT_EQ(0x0302, fragment.congestion_info.inter_arrival. - accumulated_number_of_lost_packets); - EXPECT_EQ(0x0504, - fragment.congestion_info.inter_arrival.offset_time); - EXPECT_EQ(0x0706, - fragment.congestion_info.inter_arrival.delta_time); - - // Now test framing boundaries - for (size_t i = kCongestionInfoOffset; i < kCongestionInfoOffset + 5; ++i) { - string expected_error; - if (i < kCongestionInfoOffset + 1) { - expected_error = "Unable to read congestion info type."; - } else if (i < kCongestionInfoOffset + 3) { - expected_error = "Unable to read accumulated number of lost packets."; - } else if (i < kCongestionInfoOffset + 5) { - expected_error = "Unable to read offset time."; - } else if (i < kCongestionInfoOffset + 7) { - expected_error = "Unable to read delta time."; - } - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), i, false))); - EXPECT_EQ(expected_error, framer_.detailed_error()); - EXPECT_EQ(QUIC_INVALID_FRAGMENT_DATA, framer_.error()); - } -} - -TEST_F(QuicFramerTest, AckFragmentFixRate) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // congestion feedback type (fix rate) - 0x03, - // bitrate_in_bytes_per_second; - 0x01, 0x02, 0x03, 0x04, - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - - EXPECT_EQ(0u, visitor_.stream_fragments_.size()); - ASSERT_EQ(1u, visitor_.ack_fragments_.size()); - const QuicAckFragment& fragment = *visitor_.ack_fragments_[0]; - EXPECT_EQ(static_cast(0x0123456789ABC), - fragment.received_info.largest_received); - EXPECT_EQ(0xF0E1D2C3B4A59687, fragment.received_info.time_received); - - const hash_set* sequence_nums = - &fragment.received_info.missing_packets; - ASSERT_EQ(2u, sequence_nums->size()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABB) != sequence_nums->end()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABA) != sequence_nums->end()); - EXPECT_EQ(static_cast(0x0123456789AA0), - fragment.sent_info.least_unacked); - ASSERT_EQ(3u, fragment.sent_info.non_retransmiting.size()); - const hash_set* non_retrans = - &fragment.sent_info.non_retransmiting; - EXPECT_TRUE(non_retrans->find(0x0123456789AB0) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAF) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAE) != non_retrans->end()); - ASSERT_EQ(kFixRate, fragment.congestion_info.type); - EXPECT_EQ(static_cast(0x04030201), - fragment.congestion_info.fix_rate.bitrate_in_bytes_per_second); - - // Now test framing boundaries - for (size_t i = kCongestionInfoOffset; i < kCongestionInfoOffset + 5; ++i) { - string expected_error; - if (i < kCongestionInfoOffset + 1) { - expected_error = "Unable to read congestion info type."; - } else if (i < kCongestionInfoOffset + 5) { - expected_error = "Unable to read bitrate."; - } - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), i, false))); - EXPECT_EQ(expected_error, framer_.detailed_error()); - EXPECT_EQ(QUIC_INVALID_FRAGMENT_DATA, framer_.error()); - } -} - - -TEST_F(QuicFramerTest, AckFragmentInvalidFeedback) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // congestion feedback type (invalid) - 0x04, - }; - - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_INVALID_FRAGMENT_DATA, framer_.error()); -} - -TEST_F(QuicFramerTest, RstStreamFragment) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (rst stream fragment) - 0x03, - // stream id - 0x04, 0x03, 0x02, 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // details - 0x08, 0x07, 0x06, 0x05, - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - ASSERT_EQ(address_, visitor_.address_); - - EXPECT_EQ(static_cast(0x01020304), - visitor_.rst_stream_fragment_.stream_id); - EXPECT_EQ(0x05060708, visitor_.rst_stream_fragment_.details); - EXPECT_EQ(0xBA98FEDC32107654, visitor_.rst_stream_fragment_.offset); - - // Now test framing boundaries - for (size_t i = kPacketHeaderSize + 3; i < kPacketHeaderSize + 18; ++i) { - string expected_error; - if (i < kPacketHeaderSize + 6) { - expected_error = "Unable to read stream_id."; - } else if (i < kPacketHeaderSize + 14) { - expected_error = "Unable to read offset in rst fragment."; - } else if (i < kPacketHeaderSize + 18) { - expected_error = "Unable to read rst stream details."; - } - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), i, false))); - EXPECT_EQ(expected_error, framer_.detailed_error()); - EXPECT_EQ(QUIC_INVALID_RST_STREAM_DATA, framer_.error()); - } -} - -TEST_F(QuicFramerTest, ConnectionCloseFragment) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - - // fragment count - 0x01, - // fragment type (connection close fragment) - 0x04, - // details - 0x08, 0x07, 0x06, 0x05, - - // Ack fragment. - - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // congestion feedback type (inter arrival) - 0x02, - // accumulated_number_of_lost_packets - 0x02, 0x03, - // offset_time - 0x04, 0x05, - // delta_time - 0x06, 0x07, - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - - EXPECT_EQ(0u, visitor_.stream_fragments_.size()); - - EXPECT_EQ(0x05060708, visitor_.connection_close_fragment_.details); - - ASSERT_EQ(1u, visitor_.ack_fragments_.size()); - const QuicAckFragment& fragment = *visitor_.ack_fragments_[0]; - EXPECT_EQ(static_cast(0x0123456789ABC), - fragment.received_info.largest_received); - EXPECT_EQ(0xF0E1D2C3B4A59687, fragment.received_info.time_received); - - const hash_set* sequence_nums = - &fragment.received_info.missing_packets; - ASSERT_EQ(2u, sequence_nums->size()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABB) != sequence_nums->end()); - EXPECT_TRUE(sequence_nums->find(0x0123456789ABA) != sequence_nums->end()); - EXPECT_EQ(static_cast(0x0123456789AA0), - fragment.sent_info.least_unacked); - ASSERT_EQ(3u, fragment.sent_info.non_retransmiting.size()); - const hash_set* non_retrans = - &fragment.sent_info.non_retransmiting; - EXPECT_TRUE(non_retrans->find(0x0123456789AB0) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAF) != non_retrans->end()); - EXPECT_TRUE(non_retrans->find(0x0123456789AAE) != non_retrans->end()); - ASSERT_EQ(kInterArrival, fragment.congestion_info.type); - EXPECT_EQ(0x0302, fragment.congestion_info.inter_arrival. - accumulated_number_of_lost_packets); - EXPECT_EQ(0x0504, - fragment.congestion_info.inter_arrival.offset_time); - EXPECT_EQ(0x0706, - fragment.congestion_info.inter_arrival.delta_time); - - // Now test framing boundaries - for (size_t i = kPacketHeaderSize + 3; i < kPacketHeaderSize + 6; ++i) { - string expected_error; - if (i < kPacketHeaderSize + 6) { - expected_error = "Unable to read connection close details."; - } - EXPECT_FALSE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), i, false))); - EXPECT_EQ(expected_error, framer_.detailed_error()); - EXPECT_EQ(QUIC_INVALID_CONNECTION_CLOSE_DATA, framer_.error()); - } -} - -TEST_F(QuicFramerTest, FecPacket) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags (FEC) - 0x01, - // fec group - 0x01, - - // first protected packet - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // redundancy - 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', - }; - - EXPECT_TRUE(framer_.ProcessPacket( - address_, QuicEncryptedPacket(AsChars(packet), - arraysize(packet), false))); - - EXPECT_TRUE(CheckDecryption(StringPiece(AsChars(packet), arraysize(packet)))); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - - EXPECT_EQ(0u, visitor_.stream_fragments_.size()); - EXPECT_EQ(0u, visitor_.ack_fragments_.size()); - ASSERT_EQ(1, visitor_.fec_count_); - const QuicFecData& fec_data = *visitor_.fec_data_[0]; - EXPECT_EQ(static_cast(0x0123456789ABB), - fec_data.first_protected_packet_sequence_number); - EXPECT_EQ("abcdefghijklmnop", fec_data.redundancy); -} - -TEST_F(QuicFramerTest, ConstructStreamFragmentPacket) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicStreamFragment stream_fragment; - stream_fragment.stream_id = 0x01020304; - stream_fragment.fin = true; - stream_fragment.offset = 0xBA98FEDC32107654; - stream_fragment.data = "hello world!"; - - QuicFragment fragment; - fragment.type = STREAM_FRAGMENT; - fragment.stream_fragment = &stream_fragment; - - QuicFragments fragments; - fragments.push_back(fragment); - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (stream fragment) - 0x00, - // stream id - 0x04, 0x03, 0x02, 0x01, - // fin - 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // data length - 0x0c, 0x00, - // data - 'h', 'e', 'l', 'l', - 'o', ' ', 'w', 'o', - 'r', 'l', 'd', '!', - }; - - QuicPacket* data; - ASSERT_TRUE(framer_.ConstructFragementDataPacket(header, fragments, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST_F(QuicFramerTest, ConstructAckFragmentPacket) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicAckFragment ack_fragment; - ack_fragment.received_info.largest_received = 0x0123456789ABC; - ack_fragment.received_info.time_received = 0xF0E1D2C3B4A59687; - ack_fragment.received_info.missing_packets.insert(0x0123456789ABB); - ack_fragment.received_info.missing_packets.insert(0x0123456789ABA); - ack_fragment.sent_info.least_unacked = 0x0123456789AA0; - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AB0); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAF); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAE); - ack_fragment.congestion_info.type = kNone; - - QuicFragment fragment; - fragment.type = ACK_FRAGMENT; - fragment.ack_fragment = &ack_fragment; - - QuicFragments fragments; - fragments.push_back(fragment); - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, -#if defined(OS_WIN) - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, -#if defined(OS_WIN) - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // congestion feedback type (none) - 0x00, - }; - - QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, fragments, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST_F(QuicFramerTest, ConstructAckFragmentPacketTCP) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicAckFragment ack_fragment; - ack_fragment.received_info.largest_received = 0x0123456789ABC; - ack_fragment.received_info.time_received = 0xF0E1D2C3B4A59687; - ack_fragment.received_info.missing_packets.insert(0x0123456789ABB); - ack_fragment.received_info.missing_packets.insert(0x0123456789ABA); - ack_fragment.sent_info.least_unacked = 0x0123456789AA0; - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AB0); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAF); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAE); - ack_fragment.congestion_info.type = kTCP; - ack_fragment.congestion_info.tcp.accumulated_number_of_lost_packets = 0x0201; - ack_fragment.congestion_info.tcp.receive_window = 0x0403; - - QuicFragment fragment; - fragment.type = ACK_FRAGMENT; - fragment.ack_fragment = &ack_fragment; - - QuicFragments fragments; - fragments.push_back(fragment); - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, -#if defined(OS_WIN) - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, -#if defined(OS_WIN) - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // congestion feedback type (tcp) - 0x01, - // ack_fragment.congestion_info.tcp.accumulated_number_of_lost_packets - 0x01, 0x02, - // ack_fragment.congestion_info.tcp.receive_window - 0x03, 0x04, - }; - - QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, fragments, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST_F(QuicFramerTest, ConstructAckFragmentPacketInterArrival) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicAckFragment ack_fragment; - ack_fragment.received_info.largest_received = 0x0123456789ABC; - ack_fragment.received_info.time_received = 0xF0E1D2C3B4A59687; - ack_fragment.received_info.missing_packets.insert(0x0123456789ABB); - ack_fragment.received_info.missing_packets.insert(0x0123456789ABA); - ack_fragment.sent_info.least_unacked = 0x0123456789AA0; - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AB0); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAF); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAE); - ack_fragment.congestion_info.type = kInterArrival; - ack_fragment.congestion_info.inter_arrival.accumulated_number_of_lost_packets - = 0x0302; - ack_fragment.congestion_info.inter_arrival.offset_time = 0x0504; - ack_fragment.congestion_info.inter_arrival.delta_time = 0x0706; - - QuicFragment fragment; - fragment.type = ACK_FRAGMENT; - fragment.ack_fragment = &ack_fragment; - - QuicFragments fragments; - fragments.push_back(fragment); - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, -#if defined(OS_WIN) - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, -#if defined(OS_WIN) - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // congestion feedback type (inter arrival) - 0x02, - // accumulated_number_of_lost_packets - 0x02, 0x03, - // offset_time - 0x04, 0x05, - // delta_time - 0x06, 0x07, - }; - - QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, fragments, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST_F(QuicFramerTest, ConstructAckFragmentPacketFixRate) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicAckFragment ack_fragment; - ack_fragment.received_info.largest_received = 0x0123456789ABC; - ack_fragment.received_info.time_received = 0xF0E1D2C3B4A59687; - ack_fragment.received_info.missing_packets.insert(0x0123456789ABB); - ack_fragment.received_info.missing_packets.insert(0x0123456789ABA); - ack_fragment.sent_info.least_unacked = 0x0123456789AA0; - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AB0); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAF); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAE); - ack_fragment.congestion_info.type = kFixRate; - ack_fragment.congestion_info.fix_rate.bitrate_in_bytes_per_second - = 0x04030201; - - QuicFragment fragment; - fragment.type = ACK_FRAGMENT; - fragment.ack_fragment = &ack_fragment; - - QuicFragments fragments; - fragments.push_back(fragment); - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (ack fragment) - 0x02, - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, -#if defined(OS_WIN) - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, -#if defined(OS_WIN) - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // congestion feedback type (fix rate) - 0x03, - // bitrate_in_bytes_per_second; - 0x01, 0x02, 0x03, 0x04, - }; - - QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, fragments, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST_F(QuicFramerTest, ConstructAckFragmentPacketInvalidFeedback) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicAckFragment ack_fragment; - ack_fragment.received_info.largest_received = 0x0123456789ABC; - ack_fragment.received_info.time_received = 0xF0E1D2C3B4A59687; - ack_fragment.received_info.missing_packets.insert(0x0123456789ABB); - ack_fragment.received_info.missing_packets.insert(0x0123456789ABA); - ack_fragment.sent_info.least_unacked = 0x0123456789AA0; - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AB0); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAF); - ack_fragment.sent_info.non_retransmiting.insert(0x0123456789AAE); - ack_fragment.congestion_info.type = - static_cast(kFixRate + 1); - - QuicFragment fragment; - fragment.type = ACK_FRAGMENT; - fragment.ack_fragment = &ack_fragment; - - QuicFragments fragments; - fragments.push_back(fragment); - - QuicPacket* data; - EXPECT_FALSE(framer_.ConstructFragementDataPacket(header, fragments, &data)); -} - -TEST_F(QuicFramerTest, ConstructRstFragmentPacket) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicRstStreamFragment rst_fragment; - rst_fragment.stream_id = 0x01020304; - rst_fragment.details = static_cast(0x05060708); - rst_fragment.offset = 0xBA98FEDC32107654; - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (rst stream fragment) - 0x03, - // stream id - 0x04, 0x03, 0x02, 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // details - 0x08, 0x07, 0x06, 0x05, - }; - - QuicFragment fragment(&rst_fragment); - - QuicFragments fragments; - fragments.push_back(fragment); - - QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, fragments, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST_F(QuicFramerTest, ConstructCloseFragmentPacket) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicConnectionCloseFragment close_fragment; - close_fragment.details = static_cast(0x05060708); - - QuicAckFragment* ack_fragment = &close_fragment.ack_fragment; - ack_fragment->received_info.largest_received = 0x0123456789ABC; - ack_fragment->received_info.time_received = 0xF0E1D2C3B4A59687; - ack_fragment->received_info.missing_packets.insert(0x0123456789ABB); - ack_fragment->received_info.missing_packets.insert(0x0123456789ABA); - ack_fragment->sent_info.least_unacked = 0x0123456789AA0; - ack_fragment->sent_info.non_retransmiting.insert(0x0123456789AB0); - ack_fragment->sent_info.non_retransmiting.insert(0x0123456789AAF); - ack_fragment->sent_info.non_retransmiting.insert(0x0123456789AAE); - ack_fragment->congestion_info.type = kInterArrival; - ack_fragment->congestion_info.inter_arrival.accumulated_number_of_lost_packets - = 0x0302; - ack_fragment->congestion_info.inter_arrival.offset_time = 0x0504; - ack_fragment->congestion_info.inter_arrival.delta_time = 0x0706; - - QuicFragment fragment(&close_fragment); - - QuicFragments fragments; - fragments.push_back(fragment); - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x00, - // fec group - 0x00, - - // fragment count - 0x01, - // fragment type (connection close fragment) - 0x04, - // details - 0x08, 0x07, 0x06, 0x05, - - // Ack fragment. - - // largest received packet sequence number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // time delta - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // num_unacked_packets - 0x02, -#if defined(OS_WIN) - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // unacked packet sequence number - 0xBA, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // unacked packet sequence number - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // least packet sequence number awaiting an ack - 0xA0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // num non retransmitting packets - 0x03, -#if defined(OS_WIN) - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#else - // non retransmitting packet sequence number - 0xAE, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xAF, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // non retransmitting packet sequence number - 0xB0, 0x9A, 0x78, 0x56, - 0x34, 0x12, -#endif - // congestion feedback type (inter arrival) - 0x02, - // accumulated_number_of_lost_packets - 0x02, 0x03, - // offset_time - 0x04, 0x05, - // delta_time - 0x06, 0x07, - }; - - QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, fragments, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST_F(QuicFramerTest, ConstructFecPacket) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 0x01; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_FEC; - header.fec_group = 1; - - QuicFecData fec_data; - fec_data.fec_group = 1; - fec_data.first_protected_packet_sequence_number = 0x123456789ABB; - fec_data.redundancy = "abcdefghijklmnop"; - - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x01, - // fec group - 0x01, - // first protected packet - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // redundancy - 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', - }; - - QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFecPacket(header, fec_data, &data)); - - test::CompareCharArraysWithHexError("constructed packet", - data->data(), data->length(), - AsChars(packet), arraysize(packet)); - - delete data; -} - -TEST_F(QuicFramerTest, IncrementRetransmitCount) { - QuicPacketHeader header; - header.guid = 0xFEDCBA9876543210; - header.retransmission_count = 1; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicStreamFragment stream_fragment; - stream_fragment.stream_id = 0x01020304; - stream_fragment.fin = true; - stream_fragment.offset = 0xBA98FEDC32107654; - stream_fragment.data = "hello world!"; - - QuicFragment fragment; - fragment.type = STREAM_FRAGMENT; - fragment.stream_fragment = &stream_fragment; - - QuicFragments fragments; - fragments.push_back(fragment); - - QuicPacket *original; - ASSERT_TRUE(framer_.ConstructFragementDataPacket( - header, fragments, &original)); - EXPECT_EQ(header.retransmission_count, framer_.GetRetransmitCount(original)); - - header.retransmission_count = 2; - QuicPacket *retransmitted; - ASSERT_TRUE(framer_.ConstructFragementDataPacket( - header, fragments, &retransmitted)); - - framer_.IncrementRetransmitCount(original); - EXPECT_EQ(header.retransmission_count, framer_.GetRetransmitCount(original)); - - test::CompareCharArraysWithHexError( - "constructed packet", original->data(), original->length(), - retransmitted->data(), retransmitted->length()); - delete original; - delete retransmitted; -} - -TEST_F(QuicFramerTest, EncryptPacket) { - unsigned char packet[] = { - // guid - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // packet id - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // retransmission count - 0x01, - // transmission time - 0x87, 0x96, 0xA5, 0xB4, - 0xC3, 0xD2, 0xE1, 0xF0, - // flags - 0x01, - // fec group - 0x01, - // first protected packet - 0xBB, 0x9A, 0x78, 0x56, - 0x34, 0x12, - // redundancy - 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', - }; - - scoped_ptr encrypted(framer_.EncryptPacket( - QuicPacket(AsChars(packet), arraysize(packet), false))); - ASSERT_TRUE(encrypted.get() != NULL); - EXPECT_TRUE(CheckEncryption(StringPiece(AsChars(packet), arraysize(packet)))); -} - -} // namespace test - -} // namespace net diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc deleted file mode 100644 index 78c0241d..0000000 --- a/net/quic/quic_protocol.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/quic_protocol.h" - -using base::StringPiece; - -namespace net { - -QuicStreamFragment::QuicStreamFragment() {} - -QuicStreamFragment::QuicStreamFragment(QuicStreamId stream_id, - bool fin, - uint64 offset, - StringPiece data) - : stream_id(stream_id), - fin(fin), - offset(offset), - data(data) { -} - -ReceivedPacketInfo::ReceivedPacketInfo() {} - -ReceivedPacketInfo::~ReceivedPacketInfo() {} - -SentPacketInfo::SentPacketInfo() {} - -SentPacketInfo::~SentPacketInfo() {} - -QuicFecData::QuicFecData() {} - -QuicData::~QuicData() { - if (owns_buffer_) { - delete [] const_cast(buffer_); - } -} - -} // namespace net diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h deleted file mode 100644 index d096fff..0000000 --- a/net/quic/quic_protocol.h +++ /dev/null @@ -1,422 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_QUIC_PROTOCOL_H_ -#define NET_QUIC_QUIC_PROTOCOL_H_ - -#include -#include -#include - -#include "base/basictypes.h" -#include "base/hash_tables.h" -#include "base/logging.h" -#include "base/string_piece.h" -#include "net/base/net_export.h" -#include "net/quic/uint128.h" - -namespace net { - -class QuicPacket; - -typedef uint64 QuicGuid; -typedef uint32 QuicStreamId; -typedef uint64 QuicStreamOffset; -typedef uint64 QuicPacketSequenceNumber; -typedef uint64 QuicTransmissionTime; -typedef uint8 QuicFecGroupNumber; - -// TODO(rch): Consider Quic specific names for these constants. -const size_t kMaxPacketSize = 1200; // Maximum size in bytes of a QUIC packet. - -// Maximum number of open streams per connection. -const size_t kDefaultMaxStreamsPerConnection = 100; - -// Size in bytes of the packet header common across all packets. -const size_t kPacketHeaderSize = 25; -// Index of the first byte in a QUIC packet of FEC protected data. -const size_t kStartOfFecProtectedData = kPacketHeaderSize; -// Index of the first byte in a QUIC packet of encrypted data. -const size_t kStartOfEncryptedData = kPacketHeaderSize - 1; -// Index of the first byte in a QUIC packet which is hashed. -const size_t kStartOfHashData = 0; -// Index into the retransmission offset in the header. -// (After GUID and sequence number.) -const int kRetransmissionOffset = 14; -// Index into the transmission time offset in the header. -const int kTransmissionTimeOffset = 15; - -// Size in bytes of all stream fragment fields. -const size_t kMinStreamFragmentLength = 15; - -// Limit on the delta between stream IDs. -const QuicStreamId kMaxStreamIdDelta = 100; - -// Reserved ID for the crypto stream. -// TODO(rch): ensure that this is not usable by any other streams. -const QuicStreamId kCryptoStreamId = 1; - -typedef std::pair PacketPair; - -const int64 kDefaultTimeout = 600000000; // 10 minutes - -enum QuicFragmentType { - STREAM_FRAGMENT = 0, - PDU_FRAGMENT, - ACK_FRAGMENT, - RST_STREAM_FRAGMENT, - CONNECTION_CLOSE_FRAGMENT, - NUM_FRAGMENT_TYPES -}; - -enum QuicPacketFlags { - PACKET_FLAGS_NONE = 0, - PACKET_FLAGS_FEC = 1, // Payload is FEC as opposed to fragments. - - PACKET_FLAGS_MAX = PACKET_FLAGS_FEC -}; - -enum QuicErrorCode { - // Stream errors. - QUIC_NO_ERROR = 0, - - // There were data fragments after the a fin or reset. - QUIC_STREAM_DATA_AFTER_TERMINATION, - // There was some server error which halted stream processing. - QUIC_SERVER_ERROR_PROCESSING_STREAM, - // We got two fin or reset offsets which did not match. - QUIC_MULTIPLE_TERMINATION_OFFSETS, - // We got bad payload and can not respond to it at the protocol level. - QUIC_BAD_APPLICATION_PAYLOAD, - - // Connection errors. - - // Control frame is malformed. - QUIC_INVALID_PACKET_HEADER, - // Fragment data is malformed. - QUIC_INVALID_FRAGMENT_DATA, - // FEC data is malformed. - QUIC_INVALID_FEC_DATA, - // Stream rst data is malformed - QUIC_INVALID_RST_STREAM_DATA, - // Connection close data is malformed. - QUIC_INVALID_CONNECTION_CLOSE_DATA, - // Ack data is malformed. - QUIC_INVALID_ACK_DATA, - // There was an error decrypting. - QUIC_DECRYPTION_FAILURE, - // There was an error encrypting. - QUIC_ENCRYPTION_FAILURE, - // The packet exceeded kMaxPacketSize. - QUIC_PACKET_TOO_LARGE, - // Data was sent for a stream which did not exist. - QUIC_PACKET_FOR_NONEXISTENT_STREAM, - // The client is going away (browser close, etc.) - QUIC_CLIENT_GOING_AWAY, - // The server is going away (restart etc.) - QUIC_SERVER_GOING_AWAY, - // A stream ID was invalid. - QUIC_INVALID_STREAM_ID, - // Too many streams already open. - QUIC_TOO_MANY_OPEN_STREAMS, - - // We hit our prenegotiated (or default) timeout - QUIC_CONNECTION_TIMED_OUT, - - // Crypto errors. - - // Handshake message contained out of order tags. - QUIC_CRYPTO_TAGS_OUT_OF_ORDER, - // Handshake message contained too many entires. - QUIC_CRYPTO_TOO_MANY_ENTRIES, - // Handshake message contained an invalid value length. - QUIC_CRYPTO_INVALID_VALUE_LENGTH, - // A crypto message was received after the handshake was complete. - QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, - // A crypto message was receieved with an illegal message tag. - QUIC_INVALID_CRYPTO_MESSAGE_TYPE, - -}; - -struct NET_EXPORT_PRIVATE QuicPacketHeader { - // Includes the ConnectionHeader and CongestionMonitoredHeader - // from the design docs, as well as some elements of DecryptedData. - QuicGuid guid; - QuicPacketSequenceNumber packet_sequence_number; - uint8 retransmission_count; - QuicTransmissionTime transmission_time; - QuicPacketFlags flags; - QuicFecGroupNumber fec_group; -}; - -struct NET_EXPORT_PRIVATE QuicStreamFragment { - QuicStreamFragment(); - QuicStreamFragment(QuicStreamId stream_id, - bool fin, - uint64 offset, - base::StringPiece data); - - QuicStreamId stream_id; - bool fin; - uint64 offset; - base::StringPiece data; -}; - -struct NET_EXPORT_PRIVATE ReceivedPacketInfo { - ReceivedPacketInfo(); - ~ReceivedPacketInfo(); - // The highest packet sequence number we've received from the peer. - QuicPacketSequenceNumber largest_received; - // The time at which we received the above packet. - QuicTransmissionTime time_received; - // The set of packets which we're expecting and have not received. - // This includes any packets between the lowest and largest_received - // which we have neither seen nor been informed are non-retransmitting. - base::hash_set missing_packets; -}; - -struct NET_EXPORT_PRIVATE SentPacketInfo { - SentPacketInfo(); - ~SentPacketInfo(); - // The lowest packet we've sent which is unacked, and we expect an ack for. - QuicPacketSequenceNumber least_unacked; - // The set of packets between least_unacked and the last packet we have sent - // which we will not resend. - base::hash_set non_retransmiting; -}; - -// Defines for all types of congestion feedback that will be negotiated in QUIC, -// kTCP MUST be supported by all QUIC implementations to guarentee 100% -// compatibility. -enum CongestionFeedbackType { - kNone = 0, // No feedback provided - kTCP, // Used to mimic TCP. - kInterArrival, // Use additional inter arrival information. - kFixRate, // Provided for testing. -}; - -struct NET_EXPORT_PRIVATE CongestionFeedbackMessageTCP { - uint16 accumulated_number_of_lost_packets; - uint16 receive_window; // Number of bytes >> 4. -}; - -struct NET_EXPORT_PRIVATE CongestionFeedbackMessageInterArrival { - uint16 accumulated_number_of_lost_packets; - int16 offset_time; - uint16 delta_time; // delta time is described below. -}; - -/* - * Description of delta time. - * - * 0 1 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |D|S| offset_time | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * Where: - * D is the time domain. If set time domain is in milliseconds, else in - * microseconds. - * S is the sign bit. - * offset_time is the time offset where the relative packet size is equal to - * 0. - */ - -struct NET_EXPORT_PRIVATE CongestionFeedbackMessageFixRate { - uint32 bitrate_in_bytes_per_second; -}; - -struct NET_EXPORT_PRIVATE CongestionInfo { - CongestionFeedbackType type; - union { - CongestionFeedbackMessageTCP tcp; - CongestionFeedbackMessageInterArrival inter_arrival; - CongestionFeedbackMessageFixRate fix_rate; - }; -}; - -struct NET_EXPORT_PRIVATE QuicAckFragment { - QuicAckFragment() {} - QuicAckFragment(QuicPacketSequenceNumber largest_received, - QuicTransmissionTime time_received, - QuicPacketSequenceNumber least_unacked) { - received_info.largest_received = largest_received; - received_info.time_received = time_received; - sent_info.least_unacked = least_unacked; - congestion_info.type = kNone; - } - - SentPacketInfo sent_info; - ReceivedPacketInfo received_info; - CongestionInfo congestion_info; - - friend std::ostream& operator<<(std::ostream& os, const QuicAckFragment& s) { - os << "largest_received: " << s.received_info.largest_received - << " time: " << s.received_info.time_received - << " missing: "; - for (base::hash_set::const_iterator it = - s.received_info.missing_packets.begin(); - it != s.received_info.missing_packets.end(); ++it) { - os << *it << " "; - } - - os << " least_waiting: " << s.sent_info.least_unacked - << " no_retransmit: "; - for (base::hash_set::const_iterator it = - s.sent_info.non_retransmiting.begin(); - it != s.sent_info.non_retransmiting.end(); ++it) { - os << *it << " "; - } - os << "\n"; - return os; - } -}; - -struct NET_EXPORT_PRIVATE QuicRstStreamFragment { - QuicRstStreamFragment() {} - QuicRstStreamFragment(QuicStreamId stream_id, uint64 offset, - QuicErrorCode details) - : stream_id(stream_id), offset(offset), details(details) { - DCHECK_LE(details, std::numeric_limits::max()); - } - - QuicStreamId stream_id; - uint64 offset; - QuicErrorCode details; -}; - -struct NET_EXPORT_PRIVATE QuicConnectionCloseFragment { - QuicErrorCode details; - QuicAckFragment ack_fragment; -}; - -struct NET_EXPORT_PRIVATE QuicFragment { - QuicFragment() {} - explicit QuicFragment(QuicStreamFragment* stream_fragment) - : type(STREAM_FRAGMENT), stream_fragment(stream_fragment) { - } - explicit QuicFragment(QuicAckFragment* fragment) - : type(ACK_FRAGMENT), ack_fragment(fragment) { - } - explicit QuicFragment(QuicRstStreamFragment* fragment) - : type(RST_STREAM_FRAGMENT), - rst_stream_fragment(fragment) { - } - explicit QuicFragment(QuicConnectionCloseFragment* fragment) - : type(CONNECTION_CLOSE_FRAGMENT), - connection_close_fragment(fragment) { - } - - QuicFragmentType type; - union { - QuicStreamFragment* stream_fragment; - QuicAckFragment* ack_fragment; - QuicRstStreamFragment* rst_stream_fragment; - QuicConnectionCloseFragment* connection_close_fragment; - }; -}; - -typedef std::vector QuicFragments; - -struct NET_EXPORT_PRIVATE QuicFecData { - QuicFecData(); - QuicFecGroupNumber fec_group; - QuicPacketSequenceNumber first_protected_packet_sequence_number; - // The last protected packet's sequence number will be one - // less than the sequence number of the FEC packet. - base::StringPiece redundancy; - bool operator==(const QuicFecData& other) const { - if (fec_group != other.fec_group) { - return false; - } - if (first_protected_packet_sequence_number != - other.first_protected_packet_sequence_number) { - return false; - } - if (redundancy != other.redundancy) { - return false; - } - return true; - } -}; - -struct NET_EXPORT_PRIVATE QuicPacketData { - std::string data; -}; - -class NET_EXPORT_PRIVATE QuicData { - public: - QuicData(const char* buffer, size_t length) - : buffer_(buffer), - length_(length), - owns_buffer_(false) { } - - QuicData(char* buffer, size_t length, bool owns_buffer) - : buffer_(buffer), - length_(length), - owns_buffer_(owns_buffer) { } - - virtual ~QuicData(); - - base::StringPiece AsStringPiece() const { - return base::StringPiece(data(), length()); - } - - const char* data() const { return buffer_; } - size_t length() const { return length_; } - - private: - const char* buffer_; - size_t length_; - bool owns_buffer_; - - DISALLOW_COPY_AND_ASSIGN(QuicData); -}; - -class NET_EXPORT_PRIVATE QuicPacket : public QuicData { - public: - QuicPacket(char* buffer, size_t length, bool owns_buffer) - : QuicData(buffer, length, owns_buffer), - buffer_(buffer) { } - - base::StringPiece FecProtectedData() const { - return base::StringPiece(data() + kStartOfFecProtectedData, - length() - kStartOfFecProtectedData); - } - - base::StringPiece AssociatedData() const { - return base::StringPiece(data() + kStartOfHashData, kStartOfEncryptedData); - } - - base::StringPiece Plaintext() const { - return base::StringPiece(data() + kStartOfEncryptedData, - length() - kStartOfEncryptedData); - } - char* mutable_data() { return buffer_; } - - private: - char* buffer_; - - // TODO(rch): DISALLOW_COPY_AND_ASSIGN -}; - -class NET_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData { - public: - QuicEncryptedPacket(const char* buffer, size_t length) - : QuicData(buffer, length) { } - - QuicEncryptedPacket(char* buffer, size_t length, bool owns_buffer) - : QuicData(buffer, length, owns_buffer) { } - - base::StringPiece AssociatedData() const { - return base::StringPiece(data() + kStartOfHashData, kStartOfEncryptedData); - } - - // TODO(rch): DISALLOW_COPY_AND_ASSIGN -}; - -} // namespace net - -#endif // NET_QUIC_QUIC_PROTOCOL_H_ diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc deleted file mode 100644 index b29a46c..0000000 --- a/net/quic/quic_utils.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/quic_utils.h" - -#include "base/logging.h" - -namespace net { - -// static -int QuicUtils::StreamFragmentPacketOverhead(int num_fragments) { - // TODO(jar): Use sizeof(some name). - return kPacketHeaderSize + - 1 + // fragment count - (1 + // 8 bit type - 2 + // 16 bit length - kMinStreamFragmentLength) * num_fragments; -} - -// TODO(jar): put into an anonymous namespage. -// The following two constants are defined as part of the hash algorithm. -// 309485009821345068724781371 -static uint128 kPrime(16777216u, 315u); -// 14406626329776981559649562966706236762 -static uint128 kOffset(780984778246553632u, 4400696054689967450u); - -uint128 QuicUtils::FNV1a_128_Hash(const char* data, int len) { - const uint8* octets = reinterpret_cast(data); - - uint128 hash = kOffset; - - for (int i = 0; i < len; ++i) { - hash = hash ^ uint128(0, octets[i]); - hash = hash * kPrime; - } - - return hash; -} - -#define RETURN_STRING_LITERAL(x) \ -case x: \ -return #x; - -const char* QuicUtils::ErrorToString(QuicErrorCode error) { - switch (error) { - RETURN_STRING_LITERAL(QUIC_NO_ERROR); - RETURN_STRING_LITERAL(QUIC_STREAM_DATA_AFTER_TERMINATION); - RETURN_STRING_LITERAL(QUIC_SERVER_ERROR_PROCESSING_STREAM); - RETURN_STRING_LITERAL(QUIC_MULTIPLE_TERMINATION_OFFSETS); - RETURN_STRING_LITERAL(QUIC_BAD_APPLICATION_PAYLOAD); - RETURN_STRING_LITERAL(QUIC_INVALID_PACKET_HEADER); - RETURN_STRING_LITERAL(QUIC_INVALID_FRAGMENT_DATA); - RETURN_STRING_LITERAL(QUIC_INVALID_FEC_DATA); - RETURN_STRING_LITERAL(QUIC_INVALID_RST_STREAM_DATA); - RETURN_STRING_LITERAL(QUIC_INVALID_CONNECTION_CLOSE_DATA); - RETURN_STRING_LITERAL(QUIC_INVALID_ACK_DATA); - RETURN_STRING_LITERAL(QUIC_DECRYPTION_FAILURE); - RETURN_STRING_LITERAL(QUIC_ENCRYPTION_FAILURE); - RETURN_STRING_LITERAL(QUIC_PACKET_TOO_LARGE); - RETURN_STRING_LITERAL(QUIC_PACKET_FOR_NONEXISTENT_STREAM); - RETURN_STRING_LITERAL(QUIC_CLIENT_GOING_AWAY); - RETURN_STRING_LITERAL(QUIC_SERVER_GOING_AWAY); - RETURN_STRING_LITERAL(QUIC_CRYPTO_TAGS_OUT_OF_ORDER); - RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_ENTRIES); - RETURN_STRING_LITERAL(QUIC_CRYPTO_INVALID_VALUE_LENGTH) - RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE); - RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); - RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_ID); - RETURN_STRING_LITERAL(QUIC_TOO_MANY_OPEN_STREAMS); - RETURN_STRING_LITERAL(QUIC_CONNECTION_TIMED_OUT); - // Intentionally have no default case, so we'll break the build - // if we add errors and don't put them here. - } - return ""; -} - -} // namespace net diff --git a/net/quic/quic_utils.h b/net/quic/quic_utils.h deleted file mode 100644 index 9a851ad..0000000 --- a/net/quic/quic_utils.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Some helpers for quic - -#ifndef NET_QUIC_QUIC_UTILS_H_ -#define NET_QUIC_QUIC_UTILS_H_ - -#include - -#include "net/base/net_export.h" -#include "net/quic/quic_protocol.h" -#include "net/quic/uint128.h" - -class SocketAddress; - -namespace gfe2 { - class BalsaHeaders; -} - -namespace net { - -class NET_EXPORT_PRIVATE QuicUtils { - public: - // The overhead the quic framing will add for a packet with num_fragments - // fragments. - static int StreamFragmentPacketOverhead(int num_fragments); - - // returns the 128 bit FNV1a hash of the data. See - // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param - static uint128 FNV1a_128_Hash(const char* data, int len); - - // Returns the name of the quic error code as a char* - static const char* ErrorToString(QuicErrorCode error); -}; - -} // namespace net - -#endif // NET_QUIC_QUIC_UTILS_H_ diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc deleted file mode 100644 index a4c71bd..0000000 --- a/net/quic/test_tools/quic_test_utils.cc +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/test_tools/quic_test_utils.h" -#include "net/quic/crypto/crypto_framer.h" - -using std::max; -using std::min; -using std::string; - -namespace net { -namespace test { - -MockFramerVisitor::MockFramerVisitor() { - // By default, we want to accept packets. - ON_CALL(*this, OnPacketHeader(testing::_)) - .WillByDefault(testing::Return(true)); -} - -MockFramerVisitor::~MockFramerVisitor() {} - -bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) { - return true; -} - -namespace { - -string HexDumpWithMarks(const char* data, int length, - const bool* marks, int mark_length) { - static const char kHexChars[] = "0123456789abcdef"; - static const int kColumns = 4; - - const int kSizeLimit = 1024; - if (length > kSizeLimit || mark_length > kSizeLimit) { - LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes."; - length = min(length, kSizeLimit); - mark_length = min(mark_length, kSizeLimit); - } - - string hex; - for (const char* row = data; length > 0; - row += kColumns, length -= kColumns) { - for (const char *p = row; p < row + 4; ++p) { - if (p < row + length) { - const bool mark = - (marks && (p - data) < mark_length && marks[p - data]); - hex += mark ? '*' : ' '; - hex += kHexChars[(*p & 0xf0) >> 4]; - hex += kHexChars[*p & 0x0f]; - hex += mark ? '*' : ' '; - } else { - hex += " "; - } - } - hex = hex + " "; - - for (const char *p = row; p < row + 4 && p < row + length; ++p) - hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.'; - - hex = hex + '\n'; - } - return hex; -} - -} // namespace - -void CompareCharArraysWithHexError( - const string& description, - const char* actual, - const int actual_len, - const char* expected, - const int expected_len) { - const int min_len = min(actual_len, expected_len); - const int max_len = max(actual_len, expected_len); - scoped_array marks(new bool[max_len]); - bool identical = (actual_len == expected_len); - for (int i = 0; i < min_len; ++i) { - if (actual[i] != expected[i]) { - marks[i] = true; - identical = false; - } else { - marks[i] = false; - } - } - for (int i = min_len; i < max_len; ++i) { - marks[i] = true; - } - if (identical) return; - ADD_FAILURE() - << "Description:\n" - << description - << "\n\nExpected:\n" - << HexDumpWithMarks(expected, expected_len, marks.get(), max_len) - << "\nActual:\n" - << HexDumpWithMarks(actual, actual_len, marks.get(), max_len); -} - -void CompareQuicDataWithHexError( - const string& description, - QuicData* actual, - QuicData* expected) { - CompareCharArraysWithHexError( - description, - actual->data(), actual->length(), - expected->data(), expected->length()); -} - -QuicPacket* ConstructHandshakePacket(QuicGuid guid, CryptoTag tag) { - CryptoHandshakeMessage message; - message.tag = tag; - CryptoFramer crypto_framer; - QuicData* data; - crypto_framer.ConstructHandshakeMessage(message, &data); - QuicFramer quic_framer(QuicDecrypter::Create(kNULL), - QuicEncrypter::Create(kNULL)); - - QuicPacketHeader header; - header.guid = guid; - header.retransmission_count = 0; - header.packet_sequence_number = 1; - header.transmission_time = 0; - header.flags = PACKET_FLAGS_NONE; - header.fec_group = 0; - - QuicStreamFragment stream_fragment(kCryptoStreamId, false, 0, - data->AsStringPiece()); - - QuicFragment fragment(&stream_fragment); - QuicFragments fragments; - fragments.push_back(fragment); - QuicPacket* packet; - quic_framer.ConstructFragementDataPacket(header, fragments, &packet); - delete data; - return packet; -} - -} // namespace test - -} // namespace net diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h deleted file mode 100644 index 14e3fd2..0000000 --- a/net/quic/test_tools/quic_test_utils.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Common utilities for Quic tests - -#ifndef NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_ -#define NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_ - -#include "net/quic/quic_framer.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace net { - -namespace test { - -void CompareCharArraysWithHexError(const std::string& description, - const char* actual, - const int actual_len, - const char* expected, - const int expected_len); - -void CompareQuicDataWithHexError(const std::string& description, - QuicData* actual, - QuicData* expected); - -// Constructs a basic crypto handshake message -QuicPacket* ConstructHandshakePacket(QuicGuid guid, CryptoTag tag); - -class MockFramerVisitor : public QuicFramerVisitorInterface { - public: - MockFramerVisitor(); - ~MockFramerVisitor(); - - MOCK_METHOD1(OnError, void(QuicFramer* framer)); - MOCK_METHOD1(OnPacket, void(const IPEndPoint& client_address)); - MOCK_METHOD1(OnPacketHeader, bool(const QuicPacketHeader& header)); - MOCK_METHOD1(OnFecProtectedPayload, void(base::StringPiece payload)); - MOCK_METHOD1(OnStreamFragment, void(const QuicStreamFragment& fragment)); - MOCK_METHOD1(OnAckFragment, void(const QuicAckFragment& fragment)); - MOCK_METHOD1(OnFecData, void(const QuicFecData& fec)); - MOCK_METHOD1(OnRstStreamFragment, - void(const QuicRstStreamFragment& fragment)); - MOCK_METHOD1(OnConnectionCloseFragment, - void(const QuicConnectionCloseFragment& fragment)); - MOCK_METHOD0(OnPacketComplete, void()); -}; - -class NoOpFramerVisitor : public QuicFramerVisitorInterface { - public: - virtual void OnError(QuicFramer* framer) OVERRIDE {} - virtual void OnPacket(const IPEndPoint& client_address) OVERRIDE {} - virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE; - virtual void OnFecProtectedPayload(base::StringPiece payload) OVERRIDE {} - virtual void OnStreamFragment(const QuicStreamFragment& fragment) OVERRIDE {} - virtual void OnAckFragment(const QuicAckFragment& fragment) OVERRIDE {} - virtual void OnFecData(const QuicFecData& fec) OVERRIDE {} - virtual void OnRstStreamFragment( - const QuicRstStreamFragment& fragment) OVERRIDE {} - virtual void OnConnectionCloseFragment( - const QuicConnectionCloseFragment& fragment) OVERRIDE {} - virtual void OnPacketComplete() OVERRIDE {} -}; - -} // namespace test - -} // namespace net - -#endif // NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_ diff --git a/net/quic/uint128.h b/net/quic/uint128.h deleted file mode 100644 index c368242..0000000 --- a/net/quic/uint128.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_QUIC_UINT128_H_ -#define NET_QUIC_UINT128_H_ - -#include "base/basictypes.h" -#include "base/logging.h" - -namespace net { - -struct uint128 { - uint128() {} - uint128(uint64 hi, uint64 lo) : hi(hi), lo(lo) {} - uint64 hi; - uint64 lo; -}; - -inline uint128 operator ^(const uint128& lhs, const uint128& rhs) { - return uint128(lhs.hi ^ rhs.hi, lhs.lo ^ rhs.lo); -} - -inline uint128 operator *(const uint128& lhs, const uint128& rhs) { - // TODO(rch): correctly implement uint128 multiplication. - return lhs ^ rhs; -} - -inline bool operator ==(const uint128& lhs, const uint128& rhs) { - return lhs.hi == rhs.hi && lhs.lo == rhs.lo; -} - -inline bool operator !=(const uint128& lhs, const uint128& rhs) { - return !(lhs == rhs); -} - -} // namespace net - -#endif // NET_QUIC_UINT128_H_ -- cgit v1.1