blob: 92363ec8eea61cdca8f4bfdf6aa963968bb6a40c [file] [log] [blame]
// 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 "quic/test_tools/simple_quic_framer.h"
#include <memory>
#include <utility>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "quic/core/crypto/quic_decrypter.h"
#include "quic/core/crypto/quic_encrypter.h"
#include "quic/core/quic_types.h"
namespace quic {
namespace test {
class SimpleFramerVisitor : public QuicFramerVisitorInterface {
public:
SimpleFramerVisitor() : error_(QUIC_NO_ERROR) {}
SimpleFramerVisitor(const SimpleFramerVisitor&) = delete;
SimpleFramerVisitor& operator=(const SimpleFramerVisitor&) = delete;
~SimpleFramerVisitor() override {}
void OnError(QuicFramer* framer) override { error_ = framer->error(); }
bool OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) override {
return false;
}
void OnPacket() override {}
void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet));
}
void OnVersionNegotiationPacket(
const QuicVersionNegotiationPacket& packet) override {
version_negotiation_packet_ =
std::make_unique<QuicVersionNegotiationPacket>((packet));
}
void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
QuicConnectionId /*new_connection_id*/,
absl::string_view /*retry_token*/,
absl::string_view /*retry_integrity_tag*/,
absl::string_view /*retry_without_tag*/) override {}
bool OnUnauthenticatedPublicHeader(
const QuicPacketHeader& /*header*/) override {
return true;
}
bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
return true;
}
void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override {
last_decrypted_level_ = level;
}
bool OnPacketHeader(const QuicPacketHeader& header) override {
has_header_ = true;
header_ = header;
return true;
}
void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
coalesced_packet_ = packet.Clone();
}
void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
EncryptionLevel /*decryption_level*/,
bool /*has_decryption_key*/) override {}
bool OnStreamFrame(const QuicStreamFrame& frame) override {
// Save a copy of the data so it is valid after the packet is processed.
std::string* string_data =
new std::string(frame.data_buffer, frame.data_length);
stream_data_.push_back(absl::WrapUnique(string_data));
// TODO(ianswett): A pointer isn't necessary with emplace_back.
stream_frames_.push_back(std::make_unique<QuicStreamFrame>(
frame.stream_id, frame.fin, frame.offset,
absl::string_view(*string_data)));
return true;
}
bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
// Save a copy of the data so it is valid after the packet is processed.
std::string* string_data =
new std::string(frame.data_buffer, frame.data_length);
crypto_data_.push_back(absl::WrapUnique(string_data));
crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>(
frame.level, frame.offset, absl::string_view(*string_data)));
return true;
}
bool OnAckFrameStart(QuicPacketNumber largest_acked,
QuicTime::Delta ack_delay_time) override {
QuicAckFrame ack_frame;
ack_frame.largest_acked = largest_acked;
ack_frame.ack_delay_time = ack_delay_time;
ack_frames_.push_back(ack_frame);
return true;
}
bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
QUICHE_DCHECK(!ack_frames_.empty());
ack_frames_[ack_frames_.size() - 1].packets.AddRange(start, end);
return true;
}
bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
QuicTime /*timestamp*/) override {
return true;
}
bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
stop_waiting_frames_.push_back(frame);
return true;
}
bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
padding_frames_.push_back(frame);
return true;
}
bool OnPingFrame(const QuicPingFrame& frame) override {
ping_frames_.push_back(frame);
return true;
}
bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
rst_stream_frames_.push_back(frame);
return true;
}
bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
connection_close_frames_.push_back(frame);
return true;
}
bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
new_connection_id_frames_.push_back(frame);
return true;
}
bool OnRetireConnectionIdFrame(
const QuicRetireConnectionIdFrame& frame) override {
retire_connection_id_frames_.push_back(frame);
return true;
}
bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
new_token_frames_.push_back(frame);
return true;
}
bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
stop_sending_frames_.push_back(frame);
return true;
}
bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
path_challenge_frames_.push_back(frame);
return true;
}
bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
path_response_frames_.push_back(frame);
return true;
}
bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
goaway_frames_.push_back(frame);
return true;
}
bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
max_streams_frames_.push_back(frame);
return true;
}
bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
streams_blocked_frames_.push_back(frame);
return true;
}
bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
window_update_frames_.push_back(frame);
return true;
}
bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
blocked_frames_.push_back(frame);
return true;
}
bool OnMessageFrame(const QuicMessageFrame& frame) override {
message_frames_.emplace_back(frame.data, frame.message_length);
return true;
}
bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
handshake_done_frames_.push_back(frame);
return true;
}
bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
ack_frequency_frames_.push_back(frame);
return true;
}
void OnPacketComplete() override {}
bool IsValidStatelessResetToken(
const StatelessResetToken& /*token*/) const override {
return false;
}
void OnAuthenticatedIetfStatelessResetPacket(
const QuicIetfStatelessResetPacket& packet) override {
stateless_reset_packet_ =
std::make_unique<QuicIetfStatelessResetPacket>(packet);
}
void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
void OnDecryptedFirstPacketInKeyPhase() override {}
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override {
return nullptr;
}
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
return nullptr;
}
const QuicPacketHeader& header() const { return header_; }
const std::vector<QuicAckFrame>& ack_frames() const { return ack_frames_; }
const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
return connection_close_frames_;
}
const std::vector<QuicGoAwayFrame>& goaway_frames() const {
return goaway_frames_;
}
const std::vector<QuicMaxStreamsFrame>& max_streams_frames() const {
return max_streams_frames_;
}
const std::vector<QuicStreamsBlockedFrame>& streams_blocked_frames() const {
return streams_blocked_frames_;
}
const std::vector<QuicRstStreamFrame>& rst_stream_frames() const {
return rst_stream_frames_;
}
const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const {
return stream_frames_;
}
const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const {
return crypto_frames_;
}
const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
return stop_waiting_frames_;
}
const std::vector<QuicPingFrame>& ping_frames() const { return ping_frames_; }
const std::vector<QuicMessageFrame>& message_frames() const {
return message_frames_;
}
const std::vector<QuicWindowUpdateFrame>& window_update_frames() const {
return window_update_frames_;
}
const std::vector<QuicPaddingFrame>& padding_frames() const {
return padding_frames_;
}
const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const {
return path_challenge_frames_;
}
const std::vector<QuicPathResponseFrame>& path_response_frames() const {
return path_response_frames_;
}
const QuicVersionNegotiationPacket* version_negotiation_packet() const {
return version_negotiation_packet_.get();
}
EncryptionLevel last_decrypted_level() const { return last_decrypted_level_; }
const QuicEncryptedPacket* coalesced_packet() const {
return coalesced_packet_.get();
}
private:
QuicErrorCode error_;
bool has_header_;
QuicPacketHeader header_;
std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
std::vector<QuicAckFrame> ack_frames_;
std::vector<QuicStopWaitingFrame> stop_waiting_frames_;
std::vector<QuicPaddingFrame> padding_frames_;
std::vector<QuicPingFrame> ping_frames_;
std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_;
std::vector<QuicRstStreamFrame> rst_stream_frames_;
std::vector<QuicGoAwayFrame> goaway_frames_;
std::vector<QuicStreamsBlockedFrame> streams_blocked_frames_;
std::vector<QuicMaxStreamsFrame> max_streams_frames_;
std::vector<QuicConnectionCloseFrame> connection_close_frames_;
std::vector<QuicStopSendingFrame> stop_sending_frames_;
std::vector<QuicPathChallengeFrame> path_challenge_frames_;
std::vector<QuicPathResponseFrame> path_response_frames_;
std::vector<QuicWindowUpdateFrame> window_update_frames_;
std::vector<QuicBlockedFrame> blocked_frames_;
std::vector<QuicNewConnectionIdFrame> new_connection_id_frames_;
std::vector<QuicRetireConnectionIdFrame> retire_connection_id_frames_;
std::vector<QuicNewTokenFrame> new_token_frames_;
std::vector<QuicMessageFrame> message_frames_;
std::vector<QuicHandshakeDoneFrame> handshake_done_frames_;
std::vector<QuicAckFrequencyFrame> ack_frequency_frames_;
std::vector<std::unique_ptr<std::string>> stream_data_;
std::vector<std::unique_ptr<std::string>> crypto_data_;
EncryptionLevel last_decrypted_level_;
std::unique_ptr<QuicEncryptedPacket> coalesced_packet_;
};
SimpleQuicFramer::SimpleQuicFramer()
: framer_(AllSupportedVersions(),
QuicTime::Zero(),
Perspective::IS_SERVER,
kQuicDefaultConnectionIdLength) {}
SimpleQuicFramer::SimpleQuicFramer(
const ParsedQuicVersionVector& supported_versions)
: framer_(supported_versions,
QuicTime::Zero(),
Perspective::IS_SERVER,
kQuicDefaultConnectionIdLength) {}
SimpleQuicFramer::SimpleQuicFramer(
const ParsedQuicVersionVector& supported_versions,
Perspective perspective)
: framer_(supported_versions,
QuicTime::Zero(),
perspective,
kQuicDefaultConnectionIdLength) {}
SimpleQuicFramer::~SimpleQuicFramer() {}
bool SimpleQuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
visitor_ = std::make_unique<SimpleFramerVisitor>();
framer_.set_visitor(visitor_.get());
return framer_.ProcessPacket(packet);
}
void SimpleQuicFramer::Reset() {
visitor_ = std::make_unique<SimpleFramerVisitor>();
}
const QuicPacketHeader& SimpleQuicFramer::header() const {
return visitor_->header();
}
const QuicVersionNegotiationPacket*
SimpleQuicFramer::version_negotiation_packet() const {
return visitor_->version_negotiation_packet();
}
EncryptionLevel SimpleQuicFramer::last_decrypted_level() const {
return visitor_->last_decrypted_level();
}
QuicFramer* SimpleQuicFramer::framer() {
return &framer_;
}
size_t SimpleQuicFramer::num_frames() const {
return ack_frames().size() + goaway_frames().size() +
rst_stream_frames().size() + stop_waiting_frames().size() +
path_challenge_frames().size() + path_response_frames().size() +
stream_frames().size() + ping_frames().size() +
connection_close_frames().size() + padding_frames().size() +
crypto_frames().size();
}
const std::vector<QuicAckFrame>& SimpleQuicFramer::ack_frames() const {
return visitor_->ack_frames();
}
const std::vector<QuicStopWaitingFrame>& SimpleQuicFramer::stop_waiting_frames()
const {
return visitor_->stop_waiting_frames();
}
const std::vector<QuicPathChallengeFrame>&
SimpleQuicFramer::path_challenge_frames() const {
return visitor_->path_challenge_frames();
}
const std::vector<QuicPathResponseFrame>&
SimpleQuicFramer::path_response_frames() const {
return visitor_->path_response_frames();
}
const std::vector<QuicPingFrame>& SimpleQuicFramer::ping_frames() const {
return visitor_->ping_frames();
}
const std::vector<QuicMessageFrame>& SimpleQuicFramer::message_frames() const {
return visitor_->message_frames();
}
const std::vector<QuicWindowUpdateFrame>&
SimpleQuicFramer::window_update_frames() const {
return visitor_->window_update_frames();
}
const std::vector<std::unique_ptr<QuicStreamFrame>>&
SimpleQuicFramer::stream_frames() const {
return visitor_->stream_frames();
}
const std::vector<std::unique_ptr<QuicCryptoFrame>>&
SimpleQuicFramer::crypto_frames() const {
return visitor_->crypto_frames();
}
const std::vector<QuicRstStreamFrame>& SimpleQuicFramer::rst_stream_frames()
const {
return visitor_->rst_stream_frames();
}
const std::vector<QuicGoAwayFrame>& SimpleQuicFramer::goaway_frames() const {
return visitor_->goaway_frames();
}
const std::vector<QuicConnectionCloseFrame>&
SimpleQuicFramer::connection_close_frames() const {
return visitor_->connection_close_frames();
}
const std::vector<QuicPaddingFrame>& SimpleQuicFramer::padding_frames() const {
return visitor_->padding_frames();
}
const QuicEncryptedPacket* SimpleQuicFramer::coalesced_packet() const {
return visitor_->coalesced_packet();
}
} // namespace test
} // namespace quic