Index: net/quic/crypto/crypto_framer.cc |
diff --git a/net/quic/crypto/crypto_framer.cc b/net/quic/crypto/crypto_framer.cc |
deleted file mode 100644 |
index 9b2fc2d80af9fb52e0a86121da532a31d9f548c1..0000000000000000000000000000000000000000 |
--- a/net/quic/crypto/crypto_framer.cc |
+++ /dev/null |
@@ -1,294 +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 <memory> |
- |
-#include "base/strings/stringprintf.h" |
-#include "net/quic/crypto/crypto_protocol.h" |
-#include "net/quic/quic_data_reader.h" |
-#include "net/quic/quic_data_writer.h" |
- |
-using base::StringPiece; |
-using std::pair; |
-using std::vector; |
- |
-namespace net { |
- |
-namespace { |
- |
-const size_t kQuicTagSize = sizeof(uint32_t); |
-const size_t kCryptoEndOffsetSize = sizeof(uint32_t); |
-const size_t kNumEntriesSize = sizeof(uint16_t); |
- |
-// OneShotVisitor is a framer visitor that records a single handshake message. |
-class OneShotVisitor : public CryptoFramerVisitorInterface { |
- public: |
- OneShotVisitor() : error_(false) {} |
- |
- void OnError(CryptoFramer* framer) override { error_ = true; } |
- |
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override { |
- out_.reset(new CryptoHandshakeMessage(message)); |
- } |
- |
- bool error() const { return error_; } |
- |
- CryptoHandshakeMessage* release() { return out_.release(); } |
- |
- private: |
- std::unique_ptr<CryptoHandshakeMessage> out_; |
- bool error_; |
-}; |
- |
-} // namespace |
- |
-CryptoFramer::CryptoFramer() |
- : visitor_(nullptr), error_detail_(""), num_entries_(0), values_len_(0) { |
- Clear(); |
-} |
- |
-CryptoFramer::~CryptoFramer() {} |
- |
-// static |
-CryptoHandshakeMessage* CryptoFramer::ParseMessage(StringPiece in) { |
- OneShotVisitor visitor; |
- CryptoFramer framer; |
- |
- framer.set_visitor(&visitor); |
- if (!framer.ProcessInput(in) || visitor.error() || |
- framer.InputBytesRemaining()) { |
- return nullptr; |
- } |
- |
- return visitor.release(); |
-} |
- |
-bool CryptoFramer::ProcessInput(StringPiece input) { |
- DCHECK_EQ(QUIC_NO_ERROR, error_); |
- if (error_ != QUIC_NO_ERROR) { |
- return false; |
- } |
- error_ = Process(input); |
- if (error_ != QUIC_NO_ERROR) { |
- DCHECK(!error_detail_.empty()); |
- visitor_->OnError(this); |
- return false; |
- } |
- |
- return true; |
-} |
- |
-// static |
-QuicData* CryptoFramer::ConstructHandshakeMessage( |
- const CryptoHandshakeMessage& message) { |
- size_t num_entries = message.tag_value_map().size(); |
- size_t pad_length = 0; |
- bool need_pad_tag = false; |
- bool need_pad_value = false; |
- |
- size_t len = message.size(); |
- if (len < message.minimum_size()) { |
- need_pad_tag = true; |
- need_pad_value = true; |
- num_entries++; |
- |
- size_t delta = message.minimum_size() - len; |
- const size_t overhead = kQuicTagSize + kCryptoEndOffsetSize; |
- if (delta > overhead) { |
- pad_length = delta - overhead; |
- } |
- len += overhead + pad_length; |
- } |
- |
- if (num_entries > kMaxEntries) { |
- return nullptr; |
- } |
- |
- std::unique_ptr<char[]> buffer(new char[len]); |
- QuicDataWriter writer(len, buffer.get()); |
- if (!writer.WriteUInt32(message.tag())) { |
- DCHECK(false) << "Failed to write message tag."; |
- return nullptr; |
- } |
- if (!writer.WriteUInt16(static_cast<uint16_t>(num_entries))) { |
- DCHECK(false) << "Failed to write size."; |
- return nullptr; |
- } |
- if (!writer.WriteUInt16(0)) { |
- DCHECK(false) << "Failed to write padding."; |
- return nullptr; |
- } |
- |
- uint32_t end_offset = 0; |
- // Tags and offsets |
- for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin(); |
- it != message.tag_value_map().end(); ++it) { |
- if (it->first == kPAD && need_pad_tag) { |
- // Existing PAD tags are only checked when padding needs to be added |
- // because parts of the code may need to reserialize received messages |
- // and those messages may, legitimately include padding. |
- DCHECK(false) << "Message needed padding but already contained a PAD tag"; |
- return nullptr; |
- } |
- |
- if (it->first > kPAD && need_pad_tag) { |
- need_pad_tag = false; |
- if (!WritePadTag(&writer, pad_length, &end_offset)) { |
- return nullptr; |
- } |
- } |
- |
- if (!writer.WriteUInt32(it->first)) { |
- DCHECK(false) << "Failed to write tag."; |
- return nullptr; |
- } |
- end_offset += it->second.length(); |
- if (!writer.WriteUInt32(end_offset)) { |
- DCHECK(false) << "Failed to write end offset."; |
- return nullptr; |
- } |
- } |
- |
- if (need_pad_tag) { |
- if (!WritePadTag(&writer, pad_length, &end_offset)) { |
- return nullptr; |
- } |
- } |
- |
- // Values |
- for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin(); |
- it != message.tag_value_map().end(); ++it) { |
- if (it->first > kPAD && need_pad_value) { |
- need_pad_value = false; |
- if (!writer.WriteRepeatedByte('-', pad_length)) { |
- DCHECK(false) << "Failed to write padding."; |
- return nullptr; |
- } |
- } |
- |
- if (!writer.WriteBytes(it->second.data(), it->second.length())) { |
- DCHECK(false) << "Failed to write value."; |
- return nullptr; |
- } |
- } |
- |
- if (need_pad_value) { |
- if (!writer.WriteRepeatedByte('-', pad_length)) { |
- DCHECK(false) << "Failed to write padding."; |
- return nullptr; |
- } |
- } |
- |
- return new QuicData(buffer.release(), len, true); |
-} |
- |
-void CryptoFramer::Clear() { |
- message_.Clear(); |
- tags_and_lengths_.clear(); |
- error_ = QUIC_NO_ERROR; |
- error_detail_ = ""; |
- state_ = STATE_READING_TAG; |
-} |
- |
-QuicErrorCode CryptoFramer::Process(StringPiece input) { |
- // 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() < kQuicTagSize) { |
- break; |
- } |
- QuicTag message_tag; |
- reader.ReadUInt32(&message_tag); |
- message_.set_tag(message_tag); |
- state_ = STATE_READING_NUM_ENTRIES; |
- case STATE_READING_NUM_ENTRIES: |
- if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) { |
- break; |
- } |
- reader.ReadUInt16(&num_entries_); |
- if (num_entries_ > kMaxEntries) { |
- error_detail_ = base::StringPrintf("%u entries", num_entries_); |
- return QUIC_CRYPTO_TOO_MANY_ENTRIES; |
- } |
- uint16_t padding; |
- reader.ReadUInt16(&padding); |
- |
- tags_and_lengths_.reserve(num_entries_); |
- state_ = STATE_READING_TAGS_AND_LENGTHS; |
- values_len_ = 0; |
- case STATE_READING_TAGS_AND_LENGTHS: { |
- if (reader.BytesRemaining() < |
- num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) { |
- break; |
- } |
- |
- uint32_t last_end_offset = 0; |
- for (unsigned i = 0; i < num_entries_; ++i) { |
- QuicTag tag; |
- reader.ReadUInt32(&tag); |
- if (i > 0 && tag <= tags_and_lengths_[i - 1].first) { |
- if (tag == tags_and_lengths_[i - 1].first) { |
- error_detail_ = base::StringPrintf("Duplicate tag:%u", tag); |
- return QUIC_CRYPTO_DUPLICATE_TAG; |
- } |
- error_detail_ = base::StringPrintf("Tag %u out of order", tag); |
- return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; |
- } |
- |
- uint32_t end_offset; |
- reader.ReadUInt32(&end_offset); |
- |
- if (end_offset < last_end_offset) { |
- error_detail_ = base::StringPrintf("End offset: %u vs %u", end_offset, |
- last_end_offset); |
- return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; |
- } |
- tags_and_lengths_.push_back(std::make_pair( |
- tag, static_cast<size_t>(end_offset - last_end_offset))); |
- last_end_offset = end_offset; |
- } |
- values_len_ = last_end_offset; |
- state_ = STATE_READING_VALUES; |
- } |
- case STATE_READING_VALUES: |
- if (reader.BytesRemaining() < values_len_) { |
- break; |
- } |
- for (const pair<QuicTag, size_t>& item : tags_and_lengths_) { |
- StringPiece value; |
- reader.ReadStringPiece(&value, item.second); |
- message_.SetStringPiece(item.first, value); |
- } |
- visitor_->OnHandshakeMessage(message_); |
- Clear(); |
- state_ = STATE_READING_TAG; |
- break; |
- } |
- // Save any remaining data. |
- buffer_ = reader.PeekRemainingPayload().as_string(); |
- return QUIC_NO_ERROR; |
-} |
- |
-// static |
-bool CryptoFramer::WritePadTag(QuicDataWriter* writer, |
- size_t pad_length, |
- uint32_t* end_offset) { |
- if (!writer->WriteUInt32(kPAD)) { |
- DCHECK(false) << "Failed to write tag."; |
- return false; |
- } |
- *end_offset += pad_length; |
- if (!writer->WriteUInt32(*end_offset)) { |
- DCHECK(false) << "Failed to write end offset."; |
- return false; |
- } |
- return true; |
-} |
- |
-} // namespace net |