summaryrefslogtreecommitdiff
path: root/chromium/net/tools/quic
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-24 12:15:48 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 13:30:04 +0000
commitb014812705fc80bff0a5c120dfcef88f349816dc (patch)
tree25a2e2d9fa285f1add86aa333389a839f81a39ae /chromium/net/tools/quic
parent9f4560b1027ae06fdb497023cdcaf91b8511fa74 (diff)
downloadqtwebengine-chromium-b014812705fc80bff0a5c120dfcef88f349816dc.tar.gz
BASELINE: Update Chromium to 68.0.3440.125
Change-Id: I23f19369e01f688e496f5bf179abb521ad73874f Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/tools/quic')
-rw-r--r--chromium/net/tools/quic/chlo_extractor.cc215
-rw-r--r--chromium/net/tools/quic/chlo_extractor.h44
-rw-r--r--chromium/net/tools/quic/chlo_extractor_test.cc137
-rw-r--r--chromium/net/tools/quic/crypto_message_printer_bin.cc4
-rw-r--r--chromium/net/tools/quic/end_to_end_test.cc3116
-rw-r--r--chromium/net/tools/quic/platform/impl/quic_epoll_clock.cc37
-rw-r--r--chromium/net/tools/quic/platform/impl/quic_epoll_clock.h49
-rw-r--r--chromium/net/tools/quic/platform/impl/quic_epoll_clock_test.cc48
-rw-r--r--chromium/net/tools/quic/platform/impl/quic_socket_utils.cc319
-rw-r--r--chromium/net/tools/quic/platform/impl/quic_socket_utils.h134
-rw-r--r--chromium/net/tools/quic/platform/impl/quic_socket_utils_test.cc175
-rw-r--r--chromium/net/tools/quic/quic_client.cc96
-rw-r--r--chromium/net/tools/quic/quic_client.h76
-rw-r--r--chromium/net/tools/quic/quic_client_base.cc307
-rw-r--r--chromium/net/tools/quic/quic_client_base.h357
-rw-r--r--chromium/net/tools/quic/quic_client_bin.cc384
-rw-r--r--chromium/net/tools/quic/quic_client_epoll_network_helper.cc204
-rw-r--r--chromium/net/tools/quic/quic_client_epoll_network_helper.h136
-rw-r--r--chromium/net/tools/quic/quic_client_message_loop_network_helper.cc18
-rw-r--r--chromium/net/tools/quic/quic_client_message_loop_network_helper.h8
-rw-r--r--chromium/net/tools/quic/quic_client_test.cc119
-rw-r--r--chromium/net/tools/quic/quic_default_packet_writer.cc54
-rw-r--r--chromium/net/tools/quic/quic_default_packet_writer.h53
-rw-r--r--chromium/net/tools/quic/quic_dispatcher.cc1107
-rw-r--r--chromium/net/tools/quic/quic_dispatcher.h438
-rw-r--r--chromium/net/tools/quic/quic_dispatcher_test.cc2421
-rw-r--r--chromium/net/tools/quic/quic_epoll_alarm_factory.cc76
-rw-r--r--chromium/net/tools/quic/quic_epoll_alarm_factory.h35
-rw-r--r--chromium/net/tools/quic/quic_epoll_alarm_factory_test.cc140
-rw-r--r--chromium/net/tools/quic/quic_epoll_connection_helper.cc41
-rw-r--r--chromium/net/tools/quic/quic_epoll_connection_helper.h58
-rw-r--r--chromium/net/tools/quic/quic_epoll_connection_helper_test.cc41
-rw-r--r--chromium/net/tools/quic/quic_http_response_cache.cc396
-rw-r--r--chromium/net/tools/quic/quic_http_response_cache.h223
-rw-r--r--chromium/net/tools/quic/quic_http_response_cache_test.cc246
-rw-r--r--chromium/net/tools/quic/quic_packet_printer_bin.cc215
-rw-r--r--chromium/net/tools/quic/quic_packet_reader.cc193
-rw-r--r--chromium/net/tools/quic/quic_packet_reader.h95
-rw-r--r--chromium/net/tools/quic/quic_packet_writer_wrapper.cc46
-rw-r--r--chromium/net/tools/quic/quic_packet_writer_wrapper.h53
-rw-r--r--chromium/net/tools/quic/quic_per_connection_packet_writer.cc42
-rw-r--r--chromium/net/tools/quic/quic_per_connection_packet_writer.h44
-rw-r--r--chromium/net/tools/quic/quic_process_packet_interface.h25
-rw-r--r--chromium/net/tools/quic/quic_reject_reason_decoder_bin.cc44
-rw-r--r--chromium/net/tools/quic/quic_server.cc213
-rw-r--r--chromium/net/tools/quic/quic_server.h144
-rw-r--r--chromium/net/tools/quic/quic_server_bin.cc101
-rw-r--r--chromium/net/tools/quic/quic_server_test.cc211
-rw-r--r--chromium/net/tools/quic/quic_simple_client.cc18
-rw-r--r--chromium/net/tools/quic/quic_simple_client.h8
-rw-r--r--chromium/net/tools/quic/quic_simple_client_bin.cc27
-rw-r--r--chromium/net/tools/quic/quic_simple_client_test.cc6
-rw-r--r--chromium/net/tools/quic/quic_simple_crypto_server_stream_helper.cc29
-rw-r--r--chromium/net/tools/quic/quic_simple_crypto_server_stream_helper.h35
-rw-r--r--chromium/net/tools/quic/quic_simple_dispatcher.cc66
-rw-r--r--chromium/net/tools/quic/quic_simple_dispatcher.h48
-rw-r--r--chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h4
-rw-r--r--chromium/net/tools/quic/quic_simple_server.cc21
-rw-r--r--chromium/net/tools/quic/quic_simple_server.h14
-rw-r--r--chromium/net/tools/quic/quic_simple_server_bin.cc43
-rw-r--r--chromium/net/tools/quic/quic_simple_server_packet_writer.cc2
-rw-r--r--chromium/net/tools/quic/quic_simple_server_packet_writer.h6
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session.cc210
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session.h155
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session_helper.cc2
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session_helper.h6
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session_helper_test.cc4
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session_test.cc658
-rw-r--r--chromium/net/tools/quic/quic_simple_server_stream.cc266
-rw-r--r--chromium/net/tools/quic/quic_simple_server_stream.h92
-rw-r--r--chromium/net/tools/quic/quic_simple_server_stream_test.cc618
-rw-r--r--chromium/net/tools/quic/quic_simple_server_test.cc21
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_base.cc269
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_base.h215
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_session.cc140
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_session.h98
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_session_test.cc611
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_stream.cc148
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_stream.h93
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_stream_test.cc191
-rw-r--r--chromium/net/tools/quic/quic_spdy_server_stream_base.cc41
-rw-r--r--chromium/net/tools/quic/quic_spdy_server_stream_base.h27
-rw-r--r--chromium/net/tools/quic/quic_spdy_server_stream_base_test.cc68
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager.cc329
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager.h215
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager_test.cc501
-rw-r--r--chromium/net/tools/quic/stateless_rejector.cc160
-rw-r--r--chromium/net/tools/quic/stateless_rejector.h119
-rw-r--r--chromium/net/tools/quic/stateless_rejector_test.cc291
-rw-r--r--chromium/net/tools/quic/synchronous_host_resolver.cc2
-rw-r--r--chromium/net/tools/quic/test_tools/bad_packet_writer.cc36
-rw-r--r--chromium/net/tools/quic/test_tools/bad_packet_writer.h36
-rw-r--r--chromium/net/tools/quic/test_tools/limited_mtu_test_writer.cc30
-rw-r--r--chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h38
-rw-r--r--chromium/net/tools/quic/test_tools/mock_epoll_server.cc60
-rw-r--r--chromium/net/tools/quic/test_tools/mock_epoll_server.h115
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_session_visitor.cc19
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_session_visitor.h52
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc32
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h57
-rw-r--r--chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc245
-rw-r--r--chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h181
-rw-r--r--chromium/net/tools/quic/test_tools/packet_reordering_writer.cc53
-rw-r--r--chromium/net/tools/quic/test_tools/packet_reordering_writer.h45
-rw-r--r--chromium/net/tools/quic/test_tools/quic_client_peer.cc35
-rw-r--r--chromium/net/tools/quic/test_tools/quic_client_peer.h31
-rw-r--r--chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc95
-rw-r--r--chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h64
-rw-r--r--chromium/net/tools/quic/test_tools/quic_server_peer.cc32
-rw-r--r--chromium/net/tools/quic/test_tools/quic_server_peer.h31
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.cc876
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.h396
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_server.cc210
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_server.h107
-rw-r--r--chromium/net/tools/quic/test_tools/run_all_unittests.cc11
-rw-r--r--chromium/net/tools/quic/test_tools/server_thread.cc129
-rw-r--r--chromium/net/tools/quic/test_tools/server_thread.h90
117 files changed, 123 insertions, 21598 deletions
diff --git a/chromium/net/tools/quic/chlo_extractor.cc b/chromium/net/tools/quic/chlo_extractor.cc
deleted file mode 100644
index 7ef853a939c..00000000000
--- a/chromium/net/tools/quic/chlo_extractor.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) 2016 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/tools/quic/chlo_extractor.h"
-
-#include "net/quic/core/crypto/crypto_framer.h"
-#include "net/quic/core/crypto/crypto_handshake_message.h"
-#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/crypto/quic_decrypter.h"
-#include "net/quic/core/crypto/quic_encrypter.h"
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-
-namespace net {
-
-namespace {
-
-class ChloFramerVisitor : public QuicFramerVisitorInterface,
- public CryptoFramerVisitorInterface {
- public:
- ChloFramerVisitor(QuicFramer* framer,
- const QuicTagVector& create_session_tag_indicators,
- ChloExtractor::Delegate* delegate);
-
- ~ChloFramerVisitor() override = default;
-
- // QuicFramerVisitorInterface implementation
- void OnError(QuicFramer* framer) override {}
- bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
- void OnPacket() override {}
- void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {}
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& packet) override {}
- bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
- bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
- void OnDecryptedPacket(EncryptionLevel level) override {}
- bool OnPacketHeader(const QuicPacketHeader& header) override;
- bool OnStreamFrame(const QuicStreamFrame& frame) override;
- bool OnAckFrame(const QuicAckFrame& frame) override;
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) override;
- bool OnAckRange(QuicPacketNumber start,
- QuicPacketNumber end,
- bool last_range) override;
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
- bool OnPingFrame(const QuicPingFrame& frame) override;
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
- void OnPacketComplete() override {}
- bool IsValidStatelessResetToken(uint128 token) const override;
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) override {}
-
- // CryptoFramerVisitorInterface implementation.
- void OnError(CryptoFramer* framer) override;
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
- bool found_chlo() { return found_chlo_; }
- bool chlo_contains_tags() { return chlo_contains_tags_; }
-
- private:
- QuicFramer* framer_;
- const QuicTagVector& create_session_tag_indicators_;
- ChloExtractor::Delegate* delegate_;
- bool found_chlo_;
- bool chlo_contains_tags_;
- QuicConnectionId connection_id_;
-};
-
-ChloFramerVisitor::ChloFramerVisitor(
- QuicFramer* framer,
- const QuicTagVector& create_session_tag_indicators,
- ChloExtractor::Delegate* delegate)
- : framer_(framer),
- create_session_tag_indicators_(create_session_tag_indicators),
- delegate_(delegate),
- found_chlo_(false),
- chlo_contains_tags_(false),
- connection_id_(0) {}
-
-bool ChloFramerVisitor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
- if (!framer_->IsSupportedVersion(version)) {
- return false;
- }
- framer_->set_version(version);
- return true;
-}
-
-bool ChloFramerVisitor::OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& header) {
- connection_id_ = header.connection_id;
- return true;
-}
-bool ChloFramerVisitor::OnUnauthenticatedHeader(
- const QuicPacketHeader& header) {
- return true;
-}
-bool ChloFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) {
- return true;
-}
-bool ChloFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
- QuicStringPiece data(frame.data_buffer, frame.data_length);
- if (frame.stream_id == kCryptoStreamId && frame.offset == 0 &&
- QuicTextUtils::StartsWith(data, "CHLO")) {
- CryptoFramer crypto_framer;
- crypto_framer.set_visitor(this);
- if (!crypto_framer.ProcessInput(data, Perspective::IS_SERVER)) {
- return false;
- }
- // Interrogate the crypto framer and see if there are any
- // intersecting tags between what we saw in the maybe-CHLO and the
- // indicator set.
- for (const QuicTag tag : create_session_tag_indicators_) {
- if (crypto_framer.HasTag(tag)) {
- chlo_contains_tags_ = true;
- }
- }
- if (chlo_contains_tags_ && delegate_) {
- // Unfortunately, because this is a partial CHLO,
- // OnHandshakeMessage was never called, so the ALPN was never
- // extracted. Fake it up a bit and send it to the delegate so that
- // the correct dispatch can happen.
- crypto_framer.ForceHandshake();
- }
- }
-
- return true;
-}
-
-bool ChloFramerVisitor::OnAckFrame(const QuicAckFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
- QuicTime::Delta /*ack_delay_time*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnAckRange(QuicPacketNumber /*start*/,
- QuicPacketNumber /*end*/,
- bool /*last_range*/) {
- return true;
-}
-
-bool ChloFramerVisitor::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::OnPingFrame(const QuicPingFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::OnConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::OnWindowUpdateFrame(
- const QuicWindowUpdateFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& frame) {
- return true;
-}
-
-bool ChloFramerVisitor::IsValidStatelessResetToken(uint128 token) const {
- return false;
-}
-
-void ChloFramerVisitor::OnError(CryptoFramer* framer) {}
-
-void ChloFramerVisitor::OnHandshakeMessage(
- const CryptoHandshakeMessage& message) {
- if (delegate_ != nullptr) {
- delegate_->OnChlo(framer_->transport_version(), connection_id_, message);
- }
- found_chlo_ = true;
-}
-
-} // namespace
-
-// static
-bool ChloExtractor::Extract(const QuicEncryptedPacket& packet,
- const ParsedQuicVersionVector& versions,
- const QuicTagVector& create_session_tag_indicators,
- Delegate* delegate) {
- QuicFramer framer(versions, QuicTime::Zero(), Perspective::IS_SERVER);
- ChloFramerVisitor visitor(&framer, create_session_tag_indicators, delegate);
- framer.set_visitor(&visitor);
- if (!framer.ProcessPacket(packet)) {
- return false;
- }
- return visitor.found_chlo() || visitor.chlo_contains_tags();
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/chlo_extractor.h b/chromium/net/tools/quic/chlo_extractor.h
deleted file mode 100644
index dd0fe907dac..00000000000
--- a/chromium/net/tools/quic/chlo_extractor.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2016 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_TOOLS_QUIC_CHLO_EXTRACTOR_H_
-#define NET_TOOLS_QUIC_CHLO_EXTRACTOR_H_
-
-#include "net/quic/core/crypto/crypto_handshake_message.h"
-#include "net/quic/core/quic_packets.h"
-
-namespace net {
-
-// A utility for extracting QUIC Client Hello messages from packets,
-// without needs to spin up a full QuicSession.
-class ChloExtractor {
- public:
- class Delegate {
- public:
- virtual ~Delegate() {}
-
- // Called when a CHLO message is found in the packets.
- virtual void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
- const CryptoHandshakeMessage& chlo) = 0;
- };
-
- // Extracts a CHLO message from |packet| and invokes the OnChlo
- // method of |delegate|. Return true if a CHLO message was found,
- // and false otherwise. If non-empty,
- // |create_session_tag_indicators| contains a list of QUIC tags that
- // if found will result in the session being created early, to
- // enable support for multi-packet CHLOs.
- static bool Extract(const QuicEncryptedPacket& packet,
- const ParsedQuicVersionVector& versions,
- const QuicTagVector& create_session_tag_indicators,
- Delegate* delegate);
-
- ChloExtractor(const ChloExtractor&) = delete;
- ChloExtractor operator=(const ChloExtractor&) = delete;
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_CHLO_EXTRACTOR_H_
diff --git a/chromium/net/tools/quic/chlo_extractor_test.cc b/chromium/net/tools/quic/chlo_extractor_test.cc
deleted file mode 100644
index f02b5d1bb30..00000000000
--- a/chromium/net/tools/quic/chlo_extractor_test.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2016 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/tools/quic/chlo_extractor.h"
-
-#include <memory>
-
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/platform/api/quic_arraysize.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-
-using std::string;
-
-namespace net {
-namespace test {
-namespace {
-
-class TestDelegate : public ChloExtractor::Delegate {
- public:
- TestDelegate() = default;
- ~TestDelegate() override = default;
-
- // ChloExtractor::Delegate implementation
- void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
- const CryptoHandshakeMessage& chlo) override {
- version_ = version;
- connection_id_ = connection_id;
- chlo_ = chlo.DebugString(Perspective::IS_SERVER);
- }
-
- QuicConnectionId connection_id() const { return connection_id_; }
- QuicTransportVersion transport_version() const { return version_; }
- const QuicString& chlo() const { return chlo_; }
-
- private:
- QuicConnectionId connection_id_;
- QuicTransportVersion version_;
- QuicString chlo_;
-};
-
-class ChloExtractorTest : public QuicTest {
- public:
- ChloExtractorTest() {
- header_.connection_id = 42;
- header_.connection_id_length = PACKET_8BYTE_CONNECTION_ID;
- header_.version_flag = true;
- header_.version = AllSupportedVersions().front();
- header_.reset_flag = false;
- header_.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
- header_.packet_number = 1;
- }
-
- void MakePacket(QuicStreamFrame* stream_frame) {
- QuicFrame frame(stream_frame);
- QuicFrames frames;
- frames.push_back(frame);
- QuicFramer framer(SupportedVersions(header_.version), QuicTime::Zero(),
- Perspective::IS_CLIENT);
- std::unique_ptr<QuicPacket> packet(
- BuildUnsizedDataPacket(&framer, header_, frames));
- EXPECT_TRUE(packet != nullptr);
- size_t encrypted_length =
- framer.EncryptPayload(ENCRYPTION_NONE, header_.packet_number, *packet,
- buffer_, QUIC_ARRAYSIZE(buffer_));
- ASSERT_NE(0u, encrypted_length);
- packet_ = QuicMakeUnique<QuicEncryptedPacket>(buffer_, encrypted_length);
- EXPECT_TRUE(packet_ != nullptr);
- delete stream_frame;
- }
-
- protected:
- TestDelegate delegate_;
- QuicPacketHeader header_;
- std::unique_ptr<QuicEncryptedPacket> packet_;
- char buffer_[kMaxPacketSize];
-};
-
-TEST_F(ChloExtractorTest, FindsValidChlo) {
- CryptoHandshakeMessage client_hello;
- client_hello.set_tag(kCHLO);
-
- string client_hello_str((string(
- client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece())));
- // Construct a CHLO with each supported version
- for (ParsedQuicVersion version : AllSupportedVersions()) {
- ParsedQuicVersionVector versions(SupportedVersions(version));
- header_.version = version;
- MakePacket(
- new QuicStreamFrame(kCryptoStreamId, false, 0, client_hello_str));
- EXPECT_TRUE(ChloExtractor::Extract(*packet_, versions, {}, &delegate_))
- << ParsedQuicVersionToString(version);
- EXPECT_EQ(version.transport_version, delegate_.transport_version());
- EXPECT_EQ(header_.connection_id, delegate_.connection_id());
- EXPECT_EQ(client_hello.DebugString(Perspective::IS_SERVER),
- delegate_.chlo())
- << ParsedQuicVersionToString(version);
- }
-}
-
-TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
- CryptoHandshakeMessage client_hello;
- client_hello.set_tag(kCHLO);
-
- string client_hello_str((string(
- client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece())));
- MakePacket(
- new QuicStreamFrame(kCryptoStreamId + 1, false, 0, client_hello_str));
- EXPECT_FALSE(
- ChloExtractor::Extract(*packet_, AllSupportedVersions(), {}, &delegate_));
-}
-
-TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
- CryptoHandshakeMessage client_hello;
- client_hello.set_tag(kCHLO);
-
- string client_hello_str((string(
- client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece())));
- MakePacket(new QuicStreamFrame(kCryptoStreamId, false, 1, client_hello_str));
- EXPECT_FALSE(
- ChloExtractor::Extract(*packet_, AllSupportedVersions(), {}, &delegate_));
-}
-
-TEST_F(ChloExtractorTest, DoesNotFindInvalidChlo) {
- MakePacket(new QuicStreamFrame(kCryptoStreamId, false, 0, "foo"));
- EXPECT_FALSE(
- ChloExtractor::Extract(*packet_, AllSupportedVersions(), {}, &delegate_));
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/crypto_message_printer_bin.cc b/chromium/net/tools/quic/crypto_message_printer_bin.cc
index 260175441ef..dfb5db2e83f 100644
--- a/chromium/net/tools/quic/crypto_message_printer_bin.cc
+++ b/chromium/net/tools/quic/crypto_message_printer_bin.cc
@@ -10,8 +10,8 @@
#include <iostream>
#include "base/command_line.h"
-#include "net/quic/core/crypto/crypto_framer.h"
-#include "net/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/quic/core/crypto/crypto_framer.h"
+#include "net/third_party/quic/platform/api/quic_text_utils.h"
using net::Perspective;
using std::cerr;
diff --git a/chromium/net/tools/quic/end_to_end_test.cc b/chromium/net/tools/quic/end_to_end_test.cc
deleted file mode 100644
index d43f8c3ef02..00000000000
--- a/chromium/net/tools/quic/end_to_end_test.cc
+++ /dev/null
@@ -1,3116 +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 <stddef.h>
-#include <sys/epoll.h>
-
-#include <cstdint>
-#include <list>
-#include <memory>
-#include <ostream>
-#include <utility>
-#include <vector>
-
-#include "base/memory/singleton.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/platform_thread.h"
-#include "base/time/time.h"
-#include "net/base/ip_address.h"
-#include "net/base/ip_endpoint.h"
-#include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "net/quic/core/crypto/null_encrypter.h"
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/core/quic_packet_creator.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/quic_session.h"
-#include "net/quic/core/quic_spdy_client_session_base.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_str_cat.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/platform/api/quic_test_loopback.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_config_peer.h"
-#include "net/quic/test_tools/quic_connection_peer.h"
-#include "net/quic/test_tools/quic_flow_controller_peer.h"
-#include "net/quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "net/quic/test_tools/quic_session_peer.h"
-#include "net/quic/test_tools/quic_spdy_session_peer.h"
-#include "net/quic/test_tools/quic_stream_peer.h"
-#include "net/quic/test_tools/quic_stream_sequencer_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/test/gtest_util.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-#include "net/tools/quic/quic_packet_writer_wrapper.h"
-#include "net/tools/quic/quic_server.h"
-#include "net/tools/quic/quic_simple_server_stream.h"
-#include "net/tools/quic/quic_spdy_client_stream.h"
-#include "net/tools/quic/test_tools/bad_packet_writer.h"
-#include "net/tools/quic/test_tools/packet_dropping_test_writer.h"
-#include "net/tools/quic/test_tools/packet_reordering_writer.h"
-#include "net/tools/quic/test_tools/quic_client_peer.h"
-#include "net/tools/quic/test_tools/quic_dispatcher_peer.h"
-#include "net/tools/quic/test_tools/quic_server_peer.h"
-#include "net/tools/quic/test_tools/quic_test_client.h"
-#include "net/tools/quic/test_tools/quic_test_server.h"
-#include "net/tools/quic/test_tools/server_thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::IntToString;
-using base::WaitableEvent;
-
-namespace net {
-namespace test {
-namespace {
-
-const char kFooResponseBody[] = "Artichoke hearts make me happy.";
-const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
-const float kSessionToStreamRatio = 1.5;
-
-// Run all tests with the cross products of all versions.
-struct TestParams {
- TestParams(const ParsedQuicVersionVector& client_supported_versions,
- const ParsedQuicVersionVector& server_supported_versions,
- ParsedQuicVersion negotiated_version,
- bool client_supports_stateless_rejects,
- bool server_uses_stateless_rejects_if_peer_supported,
- QuicTag congestion_control_tag,
- bool disable_hpack_dynamic_table,
- bool use_cheap_stateless_reject)
- : client_supported_versions(client_supported_versions),
- server_supported_versions(server_supported_versions),
- negotiated_version(negotiated_version),
- client_supports_stateless_rejects(client_supports_stateless_rejects),
- server_uses_stateless_rejects_if_peer_supported(
- server_uses_stateless_rejects_if_peer_supported),
- congestion_control_tag(congestion_control_tag),
- disable_hpack_dynamic_table(disable_hpack_dynamic_table),
- use_cheap_stateless_reject(use_cheap_stateless_reject) {}
-
- friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << "{ server_supported_versions: "
- << ParsedQuicVersionVectorToString(p.server_supported_versions);
- os << " client_supported_versions: "
- << ParsedQuicVersionVectorToString(p.client_supported_versions);
- os << " negotiated_version: "
- << ParsedQuicVersionToString(p.negotiated_version);
- os << " client_supports_stateless_rejects: "
- << p.client_supports_stateless_rejects;
- os << " server_uses_stateless_rejects_if_peer_supported: "
- << p.server_uses_stateless_rejects_if_peer_supported;
- os << " congestion_control_tag: "
- << QuicTagToString(p.congestion_control_tag);
- os << " disable_hpack_dynamic_table: " << p.disable_hpack_dynamic_table;
- os << " use_cheap_stateless_reject: " << p.use_cheap_stateless_reject
- << " }";
- return os;
- }
-
- ParsedQuicVersionVector client_supported_versions;
- ParsedQuicVersionVector server_supported_versions;
- ParsedQuicVersion negotiated_version;
- bool client_supports_stateless_rejects;
- bool server_uses_stateless_rejects_if_peer_supported;
- QuicTag congestion_control_tag;
- bool disable_hpack_dynamic_table;
- bool use_cheap_stateless_reject;
-};
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams(bool use_tls_handshake) {
- // Divide the versions into buckets in which the intra-frame format
- // is compatible. When clients encounter QUIC version negotiation
- // they simply retransmit all packets using the new version's
- // QUIC framing. However, they are unable to change the intra-frame
- // layout (for example to change HTTP/2 headers to SPDY/3, or a change in the
- // handshake protocol). So these tests need to ensure that clients are never
- // attempting to do 0-RTT across incompatible versions. Chromium only
- // supports a single version at a time anyway. :)
- FLAGS_quic_supports_tls_handshake = use_tls_handshake;
- ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
- // Buckets are separated by the handshake protocol (QUIC crypto or TLS) in
- // use, since if the handshake protocol changes, the ClientHello/CHLO must be
- // reconstructed for the correct protocol.
- ParsedQuicVersionVector version_buckets[2];
-
- for (const ParsedQuicVersion& version : all_supported_versions) {
- // Versions: 35+
- // QUIC_VERSION_35 allows endpoints to independently set stream limit.
- if (version.handshake_protocol == PROTOCOL_TLS1_3) {
- version_buckets[1].push_back(version);
- } else {
- version_buckets[0].push_back(version);
- }
- }
-
- // This must be kept in sync with the number of nested for-loops below as it
- // is used to prune the number of tests that are run.
- const int kMaxEnabledOptions = 4;
- int max_enabled_options = 0;
- std::vector<TestParams> params;
- for (bool server_uses_stateless_rejects_if_peer_supported : {true, false}) {
- for (bool client_supports_stateless_rejects : {true, false}) {
- for (const QuicTag congestion_control_tag :
- {kRENO, kTBBR, kQBIC, kTPCC}) {
- for (bool disable_hpack_dynamic_table : {false}) {
- for (bool use_cheap_stateless_reject : {true, false}) {
- int enabled_options = 0;
- if (congestion_control_tag != kQBIC) {
- ++enabled_options;
- }
- if (disable_hpack_dynamic_table) {
- ++enabled_options;
- }
- if (client_supports_stateless_rejects) {
- ++enabled_options;
- }
- if (server_uses_stateless_rejects_if_peer_supported) {
- ++enabled_options;
- }
- if (use_cheap_stateless_reject) {
- ++enabled_options;
- }
- CHECK_GE(kMaxEnabledOptions, enabled_options);
- if (enabled_options > max_enabled_options) {
- max_enabled_options = enabled_options;
- }
-
- // Run tests with no options, a single option, or all the
- // options enabled to avoid a combinatorial explosion.
- if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) {
- continue;
- }
-
- for (const ParsedQuicVersionVector& client_versions :
- version_buckets) {
- if (FilterSupportedVersions(client_versions).empty()) {
- continue;
- }
- // Add an entry for server and client supporting all
- // versions.
- params.push_back(TestParams(
- client_versions, all_supported_versions,
- client_versions.front(), client_supports_stateless_rejects,
- server_uses_stateless_rejects_if_peer_supported,
- congestion_control_tag, disable_hpack_dynamic_table,
- use_cheap_stateless_reject));
-
- // Run version negotiation tests tests with no options, or
- // all the options enabled to avoid a combinatorial
- // explosion.
- if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) {
- continue;
- }
-
- // Test client supporting all versions and server supporting
- // 1 version. Simulate an old server and exercise version
- // downgrade in the client. Protocol negotiation should
- // occur. Skip the i = 0 case because it is essentially the
- // same as the default case.
- for (size_t i = 1; i < client_versions.size(); ++i) {
- ParsedQuicVersionVector server_supported_versions;
- server_supported_versions.push_back(client_versions[i]);
- if (FilterSupportedVersions(server_supported_versions)
- .empty()) {
- continue;
- }
- params.push_back(TestParams(
- client_versions, server_supported_versions,
- server_supported_versions.front(),
- client_supports_stateless_rejects,
- server_uses_stateless_rejects_if_peer_supported,
- congestion_control_tag, disable_hpack_dynamic_table,
- use_cheap_stateless_reject));
- } // End of version for loop.
- } // End of 2nd version for loop.
- } // End of use_cheap_stateless_reject for loop.
- } // End of disable_hpack_dynamic_table for loop.
- } // End of congestion_control_tag for loop.
- } // End of client_supports_stateless_rejects for loop.
- CHECK_EQ(kMaxEnabledOptions, max_enabled_options);
- } // End of server_uses_stateless_rejects_if_peer_supported for loop.
- return params;
-}
-
-class ServerDelegate : public PacketDroppingTestWriter::Delegate {
- public:
- explicit ServerDelegate(QuicDispatcher* dispatcher)
- : dispatcher_(dispatcher) {}
- ~ServerDelegate() override = default;
- void OnCanWrite() override { dispatcher_->OnCanWrite(); }
-
- private:
- QuicDispatcher* dispatcher_;
-};
-
-class ClientDelegate : public PacketDroppingTestWriter::Delegate {
- public:
- explicit ClientDelegate(QuicClient* client) : client_(client) {}
- ~ClientDelegate() override = default;
- void OnCanWrite() override {
- EpollEvent event(EPOLLOUT);
- client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event);
- }
-
- private:
- QuicClient* client_;
-};
-
-class EndToEndTest : public QuicTestWithParam<TestParams> {
- protected:
- EndToEndTest()
- : initialized_(false),
- server_address_(QuicSocketAddress(TestLoopback(), 0)),
- server_hostname_("test.example.com"),
- client_writer_(nullptr),
- server_writer_(nullptr),
- server_started_(false),
- negotiated_version_(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED),
- chlo_multiplier_(0),
- stream_factory_(nullptr),
- support_server_push_(false) {
- FLAGS_quic_supports_tls_handshake = true;
- FLAGS_quic_reloadable_flag_quic_store_version_before_signalling = true;
- client_supported_versions_ = GetParam().client_supported_versions;
- server_supported_versions_ = GetParam().server_supported_versions;
- negotiated_version_ = GetParam().negotiated_version;
-
- QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
-
- // Use different flow control windows for client/server.
- client_config_.SetInitialStreamFlowControlWindowToSend(
- 2 * kInitialStreamFlowControlWindowForTest);
- client_config_.SetInitialSessionFlowControlWindowToSend(
- 2 * kInitialSessionFlowControlWindowForTest);
- server_config_.SetInitialStreamFlowControlWindowToSend(
- 3 * kInitialStreamFlowControlWindowForTest);
- server_config_.SetInitialSessionFlowControlWindowToSend(
- 3 * kInitialSessionFlowControlWindowForTest);
-
- // The default idle timeouts can be too strict when running on a busy
- // machine.
- const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
- client_config_.set_max_time_before_crypto_handshake(timeout);
- client_config_.set_max_idle_time_before_crypto_handshake(timeout);
- server_config_.set_max_time_before_crypto_handshake(timeout);
- server_config_.set_max_idle_time_before_crypto_handshake(timeout);
-
- AddToCache("/foo", 200, kFooResponseBody);
- AddToCache("/bar", 200, kBarResponseBody);
- }
-
- ~EndToEndTest() override {
- // TODO(rtenneti): port RecycleUnusedPort if needed.
- // RecycleUnusedPort(server_address_.port());
- }
-
- virtual void CreateClientWithWriter() {
- client_.reset(CreateQuicClient(client_writer_));
- }
-
- QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
- QuicTestClient* client =
- new QuicTestClient(server_address_, server_hostname_, client_config_,
- client_supported_versions_,
- crypto_test_utils::ProofVerifierForTesting());
- client->UseWriter(writer);
- client->Connect();
- return client;
- }
-
- void set_smaller_flow_control_receive_window() {
- const uint32_t kClientIFCW = 64 * 1024;
- const uint32_t kServerIFCW = 1024 * 1024;
- set_client_initial_stream_flow_control_receive_window(kClientIFCW);
- set_client_initial_session_flow_control_receive_window(
- kSessionToStreamRatio * kClientIFCW);
- set_server_initial_stream_flow_control_receive_window(kServerIFCW);
- set_server_initial_session_flow_control_receive_window(
- kSessionToStreamRatio * kServerIFCW);
- }
-
- void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
- CHECK(client_ == nullptr);
- QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
- << window;
- client_config_.SetInitialStreamFlowControlWindowToSend(window);
- }
-
- void set_client_initial_session_flow_control_receive_window(uint32_t window) {
- CHECK(client_ == nullptr);
- QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
- << window;
- client_config_.SetInitialSessionFlowControlWindowToSend(window);
- }
-
- void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
- CHECK(server_thread_ == nullptr);
- QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
- << window;
- server_config_.SetInitialStreamFlowControlWindowToSend(window);
- }
-
- void set_server_initial_session_flow_control_receive_window(uint32_t window) {
- CHECK(server_thread_ == nullptr);
- QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
- << window;
- server_config_.SetInitialSessionFlowControlWindowToSend(window);
- }
-
- const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession()
- const {
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- return &session->connection()->sent_packet_manager();
- }
-
- bool Initialize() {
- QuicTagVector copt;
- server_config_.SetConnectionOptionsToSend(copt);
- copt = client_extra_copts_;
-
- // TODO(nimia): Consider setting the congestion control algorithm for the
- // client as well according to the test parameter.
- copt.push_back(GetParam().congestion_control_tag);
- if (GetParam().congestion_control_tag == kTPCC &&
- GetQuicReloadableFlag(quic_enable_pcc)) {
- copt.push_back(kTPCC);
- }
-
- if (support_server_push_) {
- copt.push_back(kSPSH);
- }
- if (GetParam().client_supports_stateless_rejects) {
- copt.push_back(kSREJ);
- }
- if (GetParam().disable_hpack_dynamic_table) {
- copt.push_back(kDHDT);
- }
- client_config_.SetConnectionOptionsToSend(copt);
-
- // Start the server first, because CreateQuicClient() attempts
- // to connect to the server.
- StartServer();
-
- CreateClientWithWriter();
- static EpollEvent event(EPOLLOUT);
- if (client_writer_ != nullptr) {
- client_writer_->Initialize(
- QuicConnectionPeer::GetHelper(
- client_->client()->client_session()->connection()),
- QuicConnectionPeer::GetAlarmFactory(
- client_->client()->client_session()->connection()),
- new ClientDelegate(client_->client()));
- }
- initialized_ = true;
- return client_->client()->connected();
- }
-
- void SetUp() override {
- // The ownership of these gets transferred to the QuicPacketWriterWrapper
- // when Initialize() is executed.
- client_writer_ = new PacketDroppingTestWriter();
- server_writer_ = new PacketDroppingTestWriter();
- }
-
- void TearDown() override {
- ASSERT_TRUE(initialized_) << "You must call Initialize() in every test "
- << "case. Otherwise, your test will leak memory.";
- StopServer();
- }
-
- void StartServer() {
- SetQuicReloadableFlag(quic_use_cheap_stateless_rejects,
- GetParam().use_cheap_stateless_reject);
-
- auto* test_server = new QuicTestServer(
- crypto_test_utils::ProofSourceForTesting(), server_config_,
- server_supported_versions_, &response_cache_);
- server_thread_ = QuicMakeUnique<ServerThread>(test_server, server_address_);
- if (chlo_multiplier_ != 0) {
- server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
- }
- server_thread_->Initialize();
- server_address_ =
- QuicSocketAddress(server_address_.host(), server_thread_->GetPort());
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
-
- SetQuicReloadableFlag(
- enable_quic_stateless_reject_support,
- GetParam().server_uses_stateless_rejects_if_peer_supported);
-
- server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
- QuicDispatcherPeer::GetAlarmFactory(dispatcher),
- new ServerDelegate(dispatcher));
- if (stream_factory_ != nullptr) {
- static_cast<QuicTestServer*>(server_thread_->server())
- ->SetSpdyStreamFactory(stream_factory_);
- }
-
- server_thread_->Start();
- server_started_ = true;
- }
-
- void StopServer() {
- if (!server_started_)
- return;
- if (server_thread_) {
- server_thread_->Quit();
- server_thread_->Join();
- }
- }
-
- void AddToCache(QuicStringPiece path,
- int response_code,
- QuicStringPiece body) {
- response_cache_.AddSimpleResponse(server_hostname_, path, response_code,
- body);
- }
-
- void SetPacketLossPercentage(int32_t loss) {
- // TODO(rtenneti): enable when we can do random packet loss tests in
- // chrome's tree.
- if (loss != 0 && loss != 100)
- return;
- client_writer_->set_fake_packet_loss_percentage(loss);
- server_writer_->set_fake_packet_loss_percentage(loss);
- }
-
- void SetPacketSendDelay(QuicTime::Delta delay) {
- // TODO(rtenneti): enable when we can do random packet send delay tests in
- // chrome's tree.
- // client_writer_->set_fake_packet_delay(delay);
- // server_writer_->set_fake_packet_delay(delay);
- }
-
- void SetReorderPercentage(int32_t reorder) {
- // TODO(rtenneti): enable when we can do random packet reorder tests in
- // chrome's tree.
- // client_writer_->set_fake_reorder_percentage(reorder);
- // server_writer_->set_fake_reorder_percentage(reorder);
- }
-
- // Verifies that the client and server connections were both free of packets
- // being discarded, based on connection stats.
- // Calls server_thread_ Pause() and Resume(), which may only be called once
- // per test.
- void VerifyCleanConnection(bool had_packet_loss) {
- QuicConnectionStats client_stats =
- client_->client()->client_session()->connection()->GetStats();
- // TODO(ianswett): Determine why this becomes even more flaky with BBR
- // enabled. b/62141144
- if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
- EXPECT_EQ(0u, client_stats.packets_lost);
- }
- EXPECT_EQ(0u, client_stats.packets_discarded);
- // When doing 0-RTT with stateless rejects, the encrypted requests cause
- // a retranmission of the SREJ packets which are dropped by the client.
- if (!BothSidesSupportStatelessRejects()) {
- EXPECT_EQ(0u, client_stats.packets_dropped);
- }
- EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
-
- const int num_expected_stateless_rejects =
- (BothSidesSupportStatelessRejects() &&
- client_->client()->client_session()->GetNumSentClientHellos() > 0)
- ? 1
- : 0;
- EXPECT_EQ(num_expected_stateless_rejects,
- client_->client()->num_stateless_rejects_received());
-
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- ASSERT_EQ(1u, dispatcher->session_map().size());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- QuicConnectionStats server_stats = session->connection()->GetStats();
- if (!had_packet_loss) {
- EXPECT_EQ(0u, server_stats.packets_lost);
- }
- EXPECT_EQ(0u, server_stats.packets_discarded);
- // TODO(ianswett): Restore the check for packets_dropped equals 0.
- // The expect for packets received is equal to packets processed fails
- // due to version negotiation packets.
- server_thread_->Resume();
- }
-
- bool BothSidesSupportStatelessRejects() {
- return (GetParam().server_uses_stateless_rejects_if_peer_supported &&
- GetParam().client_supports_stateless_rejects);
- }
-
- void ExpectFlowControlsSynced(QuicFlowController* client,
- QuicFlowController* server) {
- EXPECT_EQ(QuicFlowControllerPeer::SendWindowSize(client),
- QuicFlowControllerPeer::ReceiveWindowSize(server));
- EXPECT_EQ(QuicFlowControllerPeer::ReceiveWindowSize(client),
- QuicFlowControllerPeer::SendWindowSize(server));
- }
-
- // Must be called before Initialize to have effect.
- void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
- stream_factory_ = factory;
- }
-
- QuicStreamId GetNthClientInitiatedId(int n) {
- return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(
- *client_->client()->client_session(), n);
- }
-
- QuicStreamId GetNthServerInitiatedId(int n) {
- return QuicSpdySessionPeer::GetNthServerInitiatedStreamId(
- *client_->client()->client_session(), n);
- }
-
- bool initialized_;
- QuicSocketAddress server_address_;
- QuicString server_hostname_;
- QuicHttpResponseCache response_cache_;
- std::unique_ptr<ServerThread> server_thread_;
- std::unique_ptr<QuicTestClient> client_;
- PacketDroppingTestWriter* client_writer_;
- PacketDroppingTestWriter* server_writer_;
- bool server_started_;
- QuicConfig client_config_;
- QuicConfig server_config_;
- ParsedQuicVersionVector client_supported_versions_;
- ParsedQuicVersionVector server_supported_versions_;
- QuicTagVector client_extra_copts_;
- ParsedQuicVersion negotiated_version_;
- size_t chlo_multiplier_;
- QuicTestServer::StreamFactory* stream_factory_;
- bool support_server_push_;
-};
-
-class EndToEndTestWithTls : public EndToEndTest {
- protected:
- EndToEndTestWithTls() : EndToEndTest() {
- FLAGS_quic_reloadable_flag_delay_quic_server_handshaker_construction = true;
- SetQuicReloadableFlag(quic_server_early_version_negotiation, true);
- }
-};
-
-// Run all end to end tests with all supported versions.
-INSTANTIATE_TEST_CASE_P(EndToEndTests,
- EndToEndTest,
- ::testing::ValuesIn(GetTestParams(false)));
-
-INSTANTIATE_TEST_CASE_P(EndToEndTestsWithTls,
- EndToEndTestWithTls,
- ::testing::ValuesIn(GetTestParams(true)));
-
-TEST_P(EndToEndTestWithTls, HandshakeSuccessful) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
- QuicCryptoStream* crypto_stream = QuicSessionPeer::GetMutableCryptoStream(
- client_->client()->client_session());
- QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(crypto_stream);
- EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicSession* server_session = dispatcher->session_map().begin()->second.get();
- crypto_stream = QuicSessionPeer::GetMutableCryptoStream(server_session);
- sequencer = QuicStreamPeer::sequencer(crypto_stream);
- EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponse) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
- chlo_multiplier_ = 1;
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
- EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
-}
-
-TEST_P(EndToEndTestWithTls, SimpleRequestResponsev6) {
- server_address_ =
- QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTestWithTls, SeparateFinPacket) {
- ASSERT_TRUE(Initialize());
-
- // Send a request in two parts: the request and then an empty packet with FIN.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->SendData("", true);
- client_->WaitForResponse();
- EXPECT_EQ(kFooResponseBody, client_->response_body());
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Now do the same thing but with a content length.
- headers["content-length"] = "3";
- client_->SendMessage(headers, "", /*fin=*/false);
- client_->SendData("foo", true);
- client_->WaitForResponse();
- EXPECT_EQ(kFooResponseBody, client_->response_body());
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTestWithTls, MultipleRequestResponse) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTestWithTls, MultipleStreams) {
- // Verifies quic_test_client can track responses of all active streams.
- ASSERT_TRUE(Initialize());
-
- const int kNumRequests = 10;
-
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
-
- for (int i = 0; i < kNumRequests; ++i) {
- client_->SendMessage(headers, "bar", /*fin=*/true);
- }
-
- while (kNumRequests > client_->num_responses()) {
- client_->ClearPerRequestState();
- client_->WaitForResponse();
- EXPECT_EQ(kFooResponseBody, client_->response_body());
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
- }
-}
-
-TEST_P(EndToEndTestWithTls, MultipleClients) {
- ASSERT_TRUE(Initialize());
- std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
-
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
-
- client_->SendMessage(headers, "", /*fin=*/false);
- client2->SendMessage(headers, "", /*fin=*/false);
-
- client_->SendData("bar", true);
- client_->WaitForResponse();
- EXPECT_EQ(kFooResponseBody, client_->response_body());
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- client2->SendData("eep", true);
- client2->WaitForResponse();
- EXPECT_EQ(kFooResponseBody, client2->response_body());
- EXPECT_EQ("200", client2->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTestWithTls, RequestOverMultiplePackets) {
- // Send a large enough request to guarantee fragmentation.
- QuicString huge_request =
- "/some/path?query=" + QuicString(kMaxPacketSize, '.');
- AddToCache(huge_request, 200, kBarResponseBody);
-
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTestWithTls, MultiplePacketsRandomOrder) {
- // Send a large enough request to guarantee fragmentation.
- QuicString huge_request =
- "/some/path?query=" + QuicString(kMaxPacketSize, '.');
- AddToCache(huge_request, 200, kBarResponseBody);
-
- ASSERT_TRUE(Initialize());
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(50);
-
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTestWithTls, PostMissingBytes) {
- ASSERT_TRUE(Initialize());
-
- // Add a content length header with no body.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
-
- // This should be detected as stream fin without complete request,
- // triggering an error response.
- client_->SendCustomSynchronousRequest(headers, "");
- EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
- client_->response_body());
- EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLoss) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // 1 MB body.
- QuicString body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- // TODO(ianswett): There should not be packet loss in this test, but on some
- // platforms the receive buffer overflows.
- VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
- ASSERT_TRUE(Initialize());
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // 100 KB body.
- QuicString body(100 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- VerifyCleanConnection(false);
-}
-
-TEST_P(EndToEndTest, LargePostWithPacketLoss) {
- if (!BothSidesSupportStatelessRejects()) {
- // Connect with lower fake packet loss than we'd like to test.
- // Until b/10126687 is fixed, losing handshake packets is pretty
- // brutal.
- // TODO(jokulik): Until we support redundant SREJ packets, don't
- // drop handshake packets for stateless rejects.
- SetPacketLossPercentage(5);
- }
- ASSERT_TRUE(Initialize());
-
- // Wait for the server SHLO before upping the packet loss.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- SetPacketLossPercentage(30);
-
- // 10 KB body.
- QuicString body(1024 * 10, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
- if (!BothSidesSupportStatelessRejects()) {
- // Connect with lower fake packet loss than we'd like to test. Until
- // b/10126687 is fixed, losing handshake packets is pretty brutal.
- // TODO(jokulik): Until we support redundant SREJ packets, don't
- // drop handshake packets for stateless rejects.
- SetPacketLossPercentage(5);
- }
- ASSERT_TRUE(Initialize());
-
- // Wait for the server SHLO before upping the packet loss.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- SetPacketLossPercentage(10);
- client_writer_->set_fake_blocked_socket_percentage(10);
-
- // 10 KB body.
- QuicString body(1024 * 10, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- // Both of these must be called when the writer is not actively used.
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(30);
-
- // 1 MB body.
- QuicString body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-}
-
-TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
- // Send a request and then disconnect. This prepares the client to attempt
- // a 0-RTT handshake for the next request.
- ASSERT_TRUE(Initialize());
-
- QuicString body(20480, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- // In the non-stateless case, the same session is used for both
- // hellos, so the number of hellos sent on that session is 2. In
- // the stateless case, the first client session will be completely
- // torn down after the reject. The number of hellos on the latest
- // session is 1.
- const int expected_num_hellos_latest_session =
- BothSidesSupportStatelessRejects() ? 1 : 2;
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- client_->WaitForInitialResponse();
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-
- EXPECT_EQ(1, client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
-
- client_->Disconnect();
-
- // Restart the server so that the 0-RTT handshake will take 1 RTT.
- StopServer();
- server_writer_ = new PacketDroppingTestWriter();
- StartServer();
-
- client_->Connect();
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- // In the non-stateless case, the same session is used for both
- // hellos, so the number of hellos sent on that session is 2. In
- // the stateless case, the first client session will be completely
- // torn down after the reject. The number of hellos sent on the
- // latest session is 1.
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
-
- VerifyCleanConnection(false);
-}
-
-TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
- // Send a request and then disconnect. This prepares the client to attempt
- // a 0-RTT handshake for the next request.
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- // In the non-stateless case, the same session is used for both
- // hellos, so the number of hellos sent on that session is 2. In
- // the stateless case, the first client session will be completely
- // torn down after the reject. The number of hellos on that second
- // latest session is 1.
- const int expected_num_hellos_latest_session =
- BothSidesSupportStatelessRejects() ? 1 : 2;
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- client_->WaitForInitialResponse();
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- EXPECT_EQ(1, client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
-
- client_->Disconnect();
-
- // Restart the server so that the 0-RTT handshake will take 1 RTT.
- StopServer();
- server_writer_ = new PacketDroppingTestWriter();
- StartServer();
-
- client_->Connect();
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- // In the non-stateless case, the same session is used for both
- // hellos, so the number of hellos sent on that session is 2. In
- // the stateless case, the first client session will be completely
- // torn down after the reject. The number of hellos sent on the
- // latest session is 1.
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
-
- VerifyCleanConnection(false);
-}
-
-TEST_P(EndToEndTest, LargePostSynchronousRequest) {
- // Send a request and then disconnect. This prepares the client to attempt
- // a 0-RTT handshake for the next request.
- ASSERT_TRUE(Initialize());
-
- QuicString body(20480, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- // In the non-stateless case, the same session is used for both
- // hellos, so the number of hellos sent on that session is 2. In
- // the stateless case, the first client session will be completely
- // torn down after the reject. The number of hellos on the latest
- // session is 1.
- const int expected_num_hellos_latest_session =
- BothSidesSupportStatelessRejects() ? 1 : 2;
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
-
- client_->Disconnect();
-
- // The 0-RTT handshake should succeed.
- client_->Connect();
- client_->WaitForInitialResponse();
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
-
- EXPECT_EQ(1, client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
-
- client_->Disconnect();
-
- // Restart the server so that the 0-RTT handshake will take 1 RTT.
- StopServer();
- server_writer_ = new PacketDroppingTestWriter();
- StartServer();
-
- client_->Connect();
- ASSERT_TRUE(client_->client()->connected());
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- // In the non-stateless case, the same session is used for both
- // hellos, so the number of hellos sent on that session is 2. In
- // the stateless case, the first client session will be completely
- // torn down after the reject. The number of hellos sent on the
- // latest session is 1.
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->client_session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
-
- VerifyCleanConnection(false);
-}
-
-TEST_P(EndToEndTest, StatelessRejectWithPacketLoss) {
- // In this test, we intentionally drop the first packet from the
- // server, which corresponds with the initial REJ/SREJ response from
- // the server.
- server_writer_->set_fake_drop_first_n_packets(1);
- ASSERT_TRUE(Initialize());
-}
-
-TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
- QuicTagVector initial_received_options;
- initial_received_options.push_back(kTBBR);
- initial_received_options.push_back(kIW10);
- initial_received_options.push_back(kPRST);
- EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
- initial_received_options));
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
- initial_received_options));
-
- // Verify that server's configuration is correct.
- server_thread_->Pause();
- EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
- EXPECT_TRUE(
- ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
- EXPECT_TRUE(
- ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
- EXPECT_TRUE(
- ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
-}
-
-TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
- ASSERT_TRUE(Initialize());
- SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
- // 256KB per second with a 256KB buffer from server to client. Wireless
- // clients commonly have larger buffers, but our max CWND is 200.
- server_writer_->set_max_bandwidth_and_buffer_size(
- QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // 1 MB body.
- QuicString body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- // This connection may drop packets, because the buffer is smaller than the
- // max CWND.
- VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTestWithTls,
- DoNotSetResumeWriteAlarmIfConnectionFlowControlBlocked) {
- // Regression test for b/14677858.
- // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
- // if currently connection level flow control blocked. If set, this results in
- // an infinite loop in the EpollServer, as the alarm fires and is immediately
- // rescheduled.
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Ensure both stream and connection level are flow control blocked by setting
- // the send window offset to 0.
- const uint64_t flow_control_window =
- server_config_.GetInitialStreamFlowControlWindowToSend();
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- QuicSession* session = client_->client()->client_session();
- QuicFlowControllerPeer::SetSendWindowOffset(stream->flow_controller(), 0);
- QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
- EXPECT_TRUE(stream->flow_controller()->IsBlocked());
- EXPECT_TRUE(session->flow_controller()->IsBlocked());
-
- // Make sure that the stream has data pending so that it will be marked as
- // write blocked when it receives a stream level WINDOW_UPDATE.
- stream->WriteOrBufferBody("hello", false, nullptr);
-
- // The stream now attempts to write, fails because it is still connection
- // level flow control blocked, and is added to the write blocked list.
- QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
- 2 * flow_control_window);
- stream->OnWindowUpdateFrame(window_update);
-
- // Prior to fixing b/14677858 this call would result in an infinite loop in
- // Chromium. As a proxy for detecting this, we now check whether the
- // resume_writes_alarm is set after OnCanWrite. It should not be, as the
- // connection is still flow control blocked.
- session->connection()->OnCanWrite();
-
- QuicAlarm* resume_writes_alarm =
- QuicConnectionPeer::GetResumeWritesAlarm(session->connection());
- EXPECT_FALSE(resume_writes_alarm->IsSet());
-}
-
-// TODO(fkastenholz): this test seems to cause net_unittests timeouts
-// reverted from EndToEndTestWithTls to EndToEndTest
-TEST_P(EndToEndTest, InvalidStream) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- QuicString body(kMaxPacketSize, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- // Force the client to write with a stream ID belonging to a nonexistent
- // server-side stream.
- QuicSpdySession* session = client_->client()->client_session();
- QuicSessionPeer::SetNextOutgoingStreamId(session, GetNthServerInitiatedId(0));
-
- client_->SendCustomSynchronousRequest(headers, body);
- EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
- EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error());
-}
-
-// Test that if the server will close the connection if the client attempts
-// to send a request with overly large headers.
-TEST_P(EndToEndTest, LargeHeaders) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- QuicString body(kMaxPacketSize, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["key1"] = QuicString(15 * 1024, 'a');
- headers["key2"] = QuicString(15 * 1024, 'a');
- headers["key3"] = QuicString(15 * 1024, 'a');
-
- client_->SendCustomSynchronousRequest(headers, body);
- EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, client_->stream_error());
- EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
-}
-
-TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- QuicString large_body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- // Insert an invalid content_length field in request to trigger an early
- // response from server.
- headers["content-length"] = "-3";
-
- client_->SendCustomSynchronousRequest(headers, large_body);
- EXPECT_EQ("bad", client_->response_body());
- EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
- EXPECT_EQ(QUIC_STREAM_NO_ERROR, client_->stream_error());
- EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
-}
-
-// TODO(rch): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTestWithTls, DISABLED_MultipleTermination) {
- ASSERT_TRUE(Initialize());
-
- // Set the offset so we won't frame. Otherwise when we pick up termination
- // before HTTP framing is complete, we send an error and close the stream,
- // and the second write is picked up as writing on a closed stream.
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- ASSERT_TRUE(stream != nullptr);
- QuicStreamPeer::SetStreamBytesWritten(3, stream);
-
- client_->SendData("bar", true);
- client_->WaitForWriteToFlush();
-
- // By default the stream protects itself from writes after terminte is set.
- // Override this to test the server handling buggy clients.
- QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
-
- EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
-}
-
-// TODO(fkastenholz): this test seems to cause net_unittests timeouts
-// reverted from EndToEndTestWithTls to EndToEndTest
-TEST_P(EndToEndTest, Timeout) {
- client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500),
- QuicTime::Delta::FromMicroseconds(500));
- // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
- // that's enough to validate timeout in this case.
- Initialize();
- while (client_->client()->connected()) {
- client_->client()->WaitForEvents();
- }
-}
-
-TEST_P(EndToEndTestWithTls, MaxIncomingDynamicStreamsLimitRespected) {
- // Set a limit on maximum number of incoming dynamic streams.
- // Make sure the limit is respected.
- const uint32_t kServerMaxIncomingDynamicStreams = 1;
- server_config_.SetMaxIncomingDynamicStreamsToSend(
- kServerMaxIncomingDynamicStreams);
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Make the client misbehave after negotiation.
- const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
- QuicSessionPeer::SetMaxOpenOutgoingStreams(
- client_->client()->client_session(), kServerMaxStreams + 1);
-
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "3";
-
- // The server supports a small number of additional streams beyond the
- // negotiated limit. Open enough streams to go beyond that limit.
- for (int i = 0; i < kServerMaxStreams + 1; ++i) {
- client_->SendMessage(headers, "", /*fin=*/false);
- }
- client_->WaitForResponse();
-
- EXPECT_TRUE(client_->connected());
- EXPECT_EQ(QUIC_REFUSED_STREAM, client_->stream_error());
- EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
-}
-
-TEST_P(EndToEndTest, SetIndependentMaxIncomingDynamicStreamsLimits) {
- // Each endpoint can set max incoming dynamic streams independently.
- const uint32_t kClientMaxIncomingDynamicStreams = 2;
- const uint32_t kServerMaxIncomingDynamicStreams = 1;
- client_config_.SetMaxIncomingDynamicStreamsToSend(
- kClientMaxIncomingDynamicStreams);
- server_config_.SetMaxIncomingDynamicStreamsToSend(
- kServerMaxIncomingDynamicStreams);
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // The client has received the server's limit and vice versa.
- EXPECT_EQ(kServerMaxIncomingDynamicStreams,
- client_->client()->client_session()->max_open_outgoing_streams());
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicSession* server_session = dispatcher->session_map().begin()->second.get();
- EXPECT_EQ(kClientMaxIncomingDynamicStreams,
- server_session->max_open_outgoing_streams());
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, NegotiateCongestionControl) {
- ASSERT_TRUE(Initialize());
-
- // For PCC, the underlying implementation may be a stub with a
- // different name-tag. Skip the rest of this test.
- if (GetParam().congestion_control_tag == kTPCC) {
- return;
- }
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- CongestionControlType expected_congestion_control_type = kRenoBytes;
- switch (GetParam().congestion_control_tag) {
- case kRENO:
- expected_congestion_control_type = kRenoBytes;
- break;
- case kTBBR:
- expected_congestion_control_type = kBBR;
- break;
- case kQBIC:
- expected_congestion_control_type = kCubicBytes;
- break;
- default:
- QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
- }
-
- server_thread_->Pause();
- EXPECT_EQ(expected_congestion_control_type,
- QuicSentPacketManagerPeer::GetSendAlgorithm(
- *GetSentPacketManagerFromFirstServerSession())
- ->GetCongestionControlType());
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ClientSuggestsRTT) {
- // Client suggests initial RTT, verify it is used.
- const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
- client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- ASSERT_EQ(1u, dispatcher->session_map().size());
- const QuicSentPacketManager& client_sent_packet_manager =
- client_->client()->client_session()->connection()->sent_packet_manager();
- const QuicSentPacketManager* server_sent_packet_manager =
- GetSentPacketManagerFromFirstServerSession();
-
- EXPECT_EQ(kInitialRTT,
- client_sent_packet_manager.GetRttStats()->initial_rtt());
- EXPECT_EQ(kInitialRTT,
- server_sent_packet_manager->GetRttStats()->initial_rtt());
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, MaxInitialRTT) {
- // Client tries to suggest twice the server's max initial rtt and the server
- // uses the max.
- client_config_.SetInitialRoundTripTimeUsToSend(2 *
- kMaxInitialRoundTripTimeUs);
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- ASSERT_EQ(1u, dispatcher->session_map().size());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- const QuicSentPacketManager& client_sent_packet_manager =
- client_->client()->client_session()->connection()->sent_packet_manager();
-
- // Now that acks have been exchanged, the RTT estimate has decreased on the
- // server and is not infinite on the client.
- EXPECT_FALSE(
- client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
- const RttStats& server_rtt_stats =
- *session->connection()->sent_packet_manager().GetRttStats();
- EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
- server_rtt_stats.initial_rtt().ToMicroseconds());
- EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
- server_rtt_stats.smoothed_rtt().ToMicroseconds());
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, MinInitialRTT) {
- // Client tries to suggest 0 and the server uses the default.
- client_config_.SetInitialRoundTripTimeUsToSend(0);
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- ASSERT_EQ(1u, dispatcher->session_map().size());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- const QuicSentPacketManager& client_sent_packet_manager =
- client_->client()->client_session()->connection()->sent_packet_manager();
- const QuicSentPacketManager& server_sent_packet_manager =
- session->connection()->sent_packet_manager();
-
- // Now that acks have been exchanged, the RTT estimate has decreased on the
- // server and is not infinite on the client.
- EXPECT_FALSE(
- client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
- // Expect the default rtt of 100ms.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
- server_sent_packet_manager.GetRttStats()->initial_rtt());
- // Ensure the bandwidth is valid.
- client_sent_packet_manager.BandwidthEstimate();
- server_sent_packet_manager.BandwidthEstimate();
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, 0ByteConnectionId) {
- client_config_.SetBytesForConnectionIdToSend(0);
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- QuicPacketHeader* header = QuicConnectionPeer::GetLastHeader(
- client_->client()->client_session()->connection());
- EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, header->connection_id_length);
-}
-
-TEST_P(EndToEndTestWithTls, 8ByteConnectionId) {
- client_config_.SetBytesForConnectionIdToSend(8);
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
- QuicPacketHeader* header = QuicConnectionPeer::GetLastHeader(
- client_->client()->client_session()->connection());
- EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, header->connection_id_length);
-}
-
-TEST_P(EndToEndTestWithTls, 15ByteConnectionId) {
- client_config_.SetBytesForConnectionIdToSend(15);
- ASSERT_TRUE(Initialize());
-
- // Our server is permissive and allows for out of bounds values.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
- QuicPacketHeader* header = QuicConnectionPeer::GetLastHeader(
- client_->client()->client_session()->connection());
- EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, header->connection_id_length);
-}
-
-TEST_P(EndToEndTestWithTls, ResetConnection) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
- client_->ResetConnection();
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-// TODO(fkastenholz): this test seems to cause net_unittests timeouts
-// reverted from EndToEndTestWithTls to EndToEndTest
-TEST_P(EndToEndTest, MaxStreamsUberTest) {
- if (!BothSidesSupportStatelessRejects()) {
- // Connect with lower fake packet loss than we'd like to test. Until
- // b/10126687 is fixed, losing handshake packets is pretty brutal.
- // TODO(jokulik): Until we support redundant SREJ packets, don't
- // drop handshake packets for stateless rejects.
- SetPacketLossPercentage(1);
- }
- ASSERT_TRUE(Initialize());
- QuicString large_body(10240, 'a');
- int max_streams = 100;
-
- AddToCache("/large_response", 200, large_body);
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- SetPacketLossPercentage(10);
-
- for (int i = 0; i < max_streams; ++i) {
- EXPECT_LT(0, client_->SendRequest("/large_response"));
- }
-
- // WaitForEvents waits 50ms and returns true if there are outstanding
- // requests.
- while (client_->client()->WaitForEvents() == true) {
- }
-}
-
-TEST_P(EndToEndTestWithTls, StreamCancelErrorTest) {
- ASSERT_TRUE(Initialize());
- QuicString small_body(256, 'a');
-
- AddToCache("/small_response", 200, small_body);
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- QuicSession* session = client_->client()->client_session();
- // Lose the request.
- SetPacketLossPercentage(100);
- EXPECT_LT(0, client_->SendRequest("/small_response"));
- client_->client()->WaitForEvents();
- // Transmit the cancel, and ensure the connection is torn down properly.
- SetPacketLossPercentage(0);
- QuicStreamId stream_id = GetNthClientInitiatedId(0);
- session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0);
-
- // WaitForEvents waits 50ms and returns true if there are outstanding
- // requests.
- while (client_->client()->WaitForEvents() == true) {
- }
- // It should be completely fine to RST a stream before any data has been
- // received for that stream.
- EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
-}
-
-TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
- ASSERT_TRUE(Initialize());
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Store the client IP address which was used to send the first request.
- QuicIpAddress old_host =
- client_->client()->network_helper()->GetLatestClientAddress().host();
-
- // Migrate socket to the new IP address.
- QuicIpAddress new_host = TestLoopback(2);
- EXPECT_NE(old_host, new_host);
- ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
-
- // Send a request using the new socket.
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
- // Tests that the client's port can change during an established QUIC
- // connection, and that doing so does not result in the connection being
- // closed by the server.
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Store the client address which was used to send the first request.
- QuicSocketAddress old_address =
- client_->client()->network_helper()->GetLatestClientAddress();
- int old_fd = client_->client()->GetLatestFD();
-
- // Create a new socket before closing the old one, which will result in a new
- // ephemeral port.
- QuicClientPeer::CreateUDPSocketAndBind(client_->client());
-
- // Stop listening and close the old FD.
- QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
-
- // The packet writer needs to be updated to use the new FD.
- client_->client()->network_helper()->CreateQuicPacketWriter();
-
- // Change the internal state of the client and connection to use the new port,
- // this is done because in a real NAT rebinding the client wouldn't see any
- // port change, and so expects no change to incoming port.
- // This is kind of ugly, but needed as we are simply swapping out the client
- // FD rather than any more complex NAT rebinding simulation.
- int new_port =
- client_->client()->network_helper()->GetLatestClientAddress().port();
- QuicClientPeer::SetClientPort(client_->client(), new_port);
- QuicConnectionPeer::SetSelfAddress(
- client_->client()->client_session()->connection(),
- QuicSocketAddress(client_->client()
- ->client_session()
- ->connection()
- ->self_address()
- .host(),
- new_port));
-
- // Register the new FD for epoll events.
- int new_fd = client_->client()->GetLatestFD();
- EpollServer* eps = client_->epoll_server();
- eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
- EPOLLIN | EPOLLOUT | EPOLLET);
-
- // Send a second request, using the new FD.
- EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Verify that the client's ephemeral port is different.
- QuicSocketAddress new_address =
- client_->client()->network_helper()->GetLatestClientAddress();
- EXPECT_EQ(old_address.host(), new_address.host());
- EXPECT_NE(old_address.port(), new_address.port());
-}
-
-TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
- SetQuicReloadableFlag(quic_unified_iw_options, true);
- client_extra_copts_.push_back(kIW03);
-
- ASSERT_TRUE(Initialize());
-
- // Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
- server_thread_->Pause();
-
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- QuicConnection* server_connection = session->connection();
- QuicPacketCount cwnd =
- server_connection->sent_packet_manager().initial_congestion_window();
- EXPECT_EQ(3u, cwnd);
-}
-
-TEST_P(EndToEndTest, DifferentFlowControlWindows) {
- // Client and server can set different initial flow control receive windows.
- // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
- // in the crypto handshake.
- const uint32_t kClientStreamIFCW = 123456;
- const uint32_t kClientSessionIFCW = 234567;
- set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
- set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
-
- uint32_t kServerStreamIFCW = 32 * 1024;
- uint32_t kServerSessionIFCW = 48 * 1024;
- set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
- set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
-
- ASSERT_TRUE(Initialize());
-
- // Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Open a data stream to make sure the stream level flow control is updated.
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- stream->WriteOrBufferBody("hello", false, nullptr);
-
- // Client should have the right values for server's receive window.
- EXPECT_EQ(kServerStreamIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kServerSessionIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialSessionFlowControlWindowBytes());
- EXPECT_EQ(kServerStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
- stream->flow_controller()));
- EXPECT_EQ(kServerSessionIFCW,
- QuicFlowControllerPeer::SendWindowOffset(
- client_->client()->client_session()->flow_controller()));
-
- // Server should have the right values for client's receive window.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- EXPECT_EQ(kClientStreamIFCW,
- session->config()->ReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kClientSessionIFCW,
- session->config()->ReceivedInitialSessionFlowControlWindowBytes());
- EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
- session->flow_controller()));
- server_thread_->Resume();
-}
-
-// Test negotiation of IFWA connection option.
-TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
- const uint32_t kClientStreamIFCW = 123456;
- const uint32_t kClientSessionIFCW = 234567;
- set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
- set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
-
- uint32_t kServerStreamIFCW = 32 * 1024;
- uint32_t kServerSessionIFCW = 48 * 1024;
- set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
- set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
-
- // Bump the window.
- const uint32_t kExpectedStreamIFCW = 1024 * 1024;
- const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
- client_extra_copts_.push_back(kIFWA);
-
- ASSERT_TRUE(Initialize());
-
- // Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- // Open a data stream to make sure the stream level flow control is updated.
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
- stream->WriteOrBufferBody("hello", false, nullptr);
-
- // Client should have the right values for server's receive window.
- EXPECT_EQ(kExpectedStreamIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kExpectedSessionIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialSessionFlowControlWindowBytes());
- EXPECT_EQ(kExpectedStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
- stream->flow_controller()));
- EXPECT_EQ(kExpectedSessionIFCW,
- QuicFlowControllerPeer::SendWindowOffset(
- client_->client()->client_session()->flow_controller()));
-}
-
-TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
- // The special headers and crypto streams should be subject to per-stream flow
- // control limits, but should not be subject to connection level flow control
- const uint32_t kStreamIFCW = 32 * 1024;
- const uint32_t kSessionIFCW = 48 * 1024;
- set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
- set_client_initial_session_flow_control_receive_window(kSessionIFCW);
- set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
- set_server_initial_session_flow_control_receive_window(kSessionIFCW);
-
- ASSERT_TRUE(Initialize());
-
- // Wait for crypto handshake to finish. This should have contributed to the
- // crypto stream flow control window, but not affected the session flow
- // control window.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- QuicCryptoStream* crypto_stream = QuicSessionPeer::GetMutableCryptoStream(
- client_->client()->client_session());
- EXPECT_LT(
- QuicFlowControllerPeer::SendWindowSize(crypto_stream->flow_controller()),
- kStreamIFCW);
- EXPECT_EQ(kSessionIFCW,
- QuicFlowControllerPeer::SendWindowSize(
- client_->client()->client_session()->flow_controller()));
-
- // Send a request with no body, and verify that the connection level window
- // has not been affected.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
- QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(
- client_->client()->client_session());
- EXPECT_LT(
- QuicFlowControllerPeer::SendWindowSize(headers_stream->flow_controller()),
- kStreamIFCW);
- EXPECT_EQ(kSessionIFCW,
- QuicFlowControllerPeer::SendWindowSize(
- client_->client()->client_session()->flow_controller()));
-
- // Server should be in a similar state: connection flow control window should
- // not have any bytes marked as received.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- QuicFlowController* server_connection_flow_controller =
- session->flow_controller();
- EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
- server_connection_flow_controller));
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, FlowControlsSynced) {
- set_smaller_flow_control_receive_window();
-
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- server_thread_->Pause();
- QuicSpdySession* const client_session = client_->client()->client_session();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- auto* server_session = static_cast<QuicSpdySession*>(
- dispatcher->session_map().begin()->second.get());
- ExpectFlowControlsSynced(client_session->flow_controller(),
- server_session->flow_controller());
- ExpectFlowControlsSynced(
- QuicSessionPeer::GetMutableCryptoStream(client_session)
- ->flow_controller(),
- QuicSessionPeer::GetMutableCryptoStream(server_session)
- ->flow_controller());
- SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
- SpdySettingsIR settings_frame;
- settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE,
- kDefaultMaxUncompressedHeaderSize);
- SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
- QuicFlowController* client_header_stream_flow_controller =
- QuicSpdySessionPeer::GetHeadersStream(client_session)->flow_controller();
- QuicFlowController* server_header_stream_flow_controller =
- QuicSpdySessionPeer::GetHeadersStream(server_session)->flow_controller();
- if (GetQuicReloadableFlag(quic_send_max_header_list_size)) {
- // Both client and server are sending this SETTINGS frame, and the send
- // window is consumed. But because of timing issue, the server may send or
- // not send the frame, and the client may send/ not send / receive / not
- // receive the frame.
- // TODO(fayang): Rewrite this part because it is hacky.
- QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize(
- server_header_stream_flow_controller) -
- QuicFlowControllerPeer::SendWindowSize(
- client_header_stream_flow_controller);
- QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize(
- client_header_stream_flow_controller) -
- QuicFlowControllerPeer::SendWindowSize(
- server_header_stream_flow_controller);
- EXPECT_TRUE(win_difference1 == 0 || win_difference1 == frame.size());
- EXPECT_TRUE(win_difference2 == 0 || win_difference2 == frame.size());
- } else {
- ExpectFlowControlsSynced(
- QuicSpdySessionPeer::GetHeadersStream(client_session)
- ->flow_controller(),
- QuicSpdySessionPeer::GetHeadersStream(server_session)
- ->flow_controller());
- }
-
- if (GetQuicReloadableFlag(quic_send_max_header_list_size)) {
- // Client *may* have received the SETTINGs frame.
- // TODO(fayang): Rewrite this part because it is hacky.
- float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
- client_session->flow_controller())) /
- QuicFlowControllerPeer::ReceiveWindowSize(
- QuicSpdySessionPeer::GetHeadersStream(client_session)
- ->flow_controller());
- float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
- client_session->flow_controller())) /
- (QuicFlowControllerPeer::ReceiveWindowSize(
- QuicSpdySessionPeer::GetHeadersStream(client_session)
- ->flow_controller()) +
- frame.size());
- EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
- ratio2 == kSessionToStreamRatio);
- }
-
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTestWithTls, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
- // A stream created on receipt of a simple request with no body will never get
- // a stream frame with a FIN. Verify that we don't keep track of the stream in
- // the locally closed streams map: it will never be removed if so.
- ASSERT_TRUE(Initialize());
-
- // Send a simple headers only request, and receive response.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Now verify that the server is not waiting for a final FIN or RST.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- EXPECT_EQ(
- 0u,
- QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(session).size());
- server_thread_->Resume();
-}
-
-// A TestAckListener verifies that its OnAckNotification method has been
-// called exactly once on destruction.
-class TestAckListener : public QuicAckListenerInterface {
- public:
- explicit TestAckListener(int bytes_to_ack) : bytes_to_ack_(bytes_to_ack) {}
-
- void OnPacketAcked(int acked_bytes,
- QuicTime::Delta /*delta_largest_observed*/) override {
- ASSERT_LE(acked_bytes, bytes_to_ack_);
- bytes_to_ack_ -= acked_bytes;
- }
-
- void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
-
- bool has_been_notified() const { return bytes_to_ack_ == 0; }
-
- protected:
- // Object is ref counted.
- ~TestAckListener() override { EXPECT_EQ(0, bytes_to_ack_); }
-
- private:
- int bytes_to_ack_;
-};
-
-class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
- public:
- void OnCompleteResponse(QuicStreamId id,
- const SpdyHeaderBlock& response_headers,
- const QuicString& response_body) override {
- QUIC_DVLOG(1) << "response for stream " << id << " "
- << response_headers.DebugString() << "\n"
- << response_body;
- }
-};
-
-TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
- // Verify that even in the presence of packet loss and occasionally blocked
- // socket, an AckNotifierDelegate will get informed that the data it is
- // interested in has been ACKed. This tests end-to-end ACK notification, and
- // demonstrates that retransmissions do not break this functionality.
- if (!BothSidesSupportStatelessRejects()) {
- // TODO(jokulik): Until we support redundant SREJ packets, don't
- // drop handshake packets for stateless rejects.
- SetPacketLossPercentage(5);
- }
- ASSERT_TRUE(Initialize());
-
- // Wait for the server SHLO before upping the packet loss.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- SetPacketLossPercentage(30);
- client_writer_->set_fake_blocked_socket_percentage(10);
-
- // Create a POST request and send the headers only.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- client_->SendMessage(headers, "", /*fin=*/false);
-
- // Test the AckNotifier's ability to track multiple packets by making the
- // request body exceed the size of a single packet.
- QuicString request_string =
- "a request body bigger than one packet" + QuicString(kMaxPacketSize, '.');
-
- // The TestAckListener will cause a failure if not notified.
- QuicReferenceCountedPointer<TestAckListener> ack_listener(
- new TestAckListener(request_string.length()));
-
- // Send the request, and register the delegate for ACKs.
- client_->SendData(request_string, true, ack_listener);
- client_->WaitForResponse();
- EXPECT_EQ(kFooResponseBody, client_->response_body());
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Send another request to flush out any pending ACKs on the server.
- client_->SendSynchronousRequest("/bar");
-
- // Make sure the delegate does get the notification it expects.
- while (!ack_listener->has_been_notified()) {
- // Waits for up to 50 ms.
- client_->client()->WaitForEvents();
- }
-}
-
-// Send a public reset from the server.
-TEST_P(EndToEndTestWithTls, ServerSendPublicReset) {
- ASSERT_TRUE(Initialize());
-
- // Send the public reset.
- QuicConnectionId connection_id =
- client_->client()->client_session()->connection()->connection_id();
- QuicPublicResetPacket header;
- header.connection_id = connection_id;
- QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
- Perspective::IS_SERVER);
- std::unique_ptr<QuicEncryptedPacket> packet(
- framer.BuildPublicResetPacket(header));
- // We must pause the server's thread in order to call WritePacket without
- // race conditions.
- server_thread_->Pause();
- server_writer_->WritePacket(
- packet->data(), packet->length(), server_address_.host(),
- client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
- server_thread_->Resume();
-
- // The request should fail.
- EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
- EXPECT_TRUE(client_->response_headers()->empty());
- EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
-}
-
-// Send a public reset from the server for a different connection ID.
-// It should be ignored.
-TEST_P(EndToEndTestWithTls, ServerSendPublicResetWithDifferentConnectionId) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Send the public reset.
- QuicConnectionId incorrect_connection_id =
- client_->client()->client_session()->connection()->connection_id() + 1;
- QuicPublicResetPacket header;
- header.connection_id = incorrect_connection_id;
- QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
- Perspective::IS_SERVER);
- std::unique_ptr<QuicEncryptedPacket> packet(
- framer.BuildPublicResetPacket(header));
- testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
- client_->client()->client_session()->connection()->set_debug_visitor(
- &visitor);
- EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
- .Times(1);
- // We must pause the server's thread in order to call WritePacket without
- // race conditions.
- server_thread_->Pause();
- server_writer_->WritePacket(
- packet->data(), packet->length(), server_address_.host(),
- client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
- server_thread_->Resume();
-
- // The connection should be unaffected.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- client_->client()->client_session()->connection()->set_debug_visitor(nullptr);
-}
-
-// Send a public reset from the client for a different connection ID.
-// It should be ignored.
-TEST_P(EndToEndTestWithTls, ClientSendPublicResetWithDifferentConnectionId) {
- ASSERT_TRUE(Initialize());
-
- // Send the public reset.
- QuicConnectionId incorrect_connection_id =
- client_->client()->client_session()->connection()->connection_id() + 1;
- QuicPublicResetPacket header;
- header.connection_id = incorrect_connection_id;
- QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
- Perspective::IS_CLIENT);
- std::unique_ptr<QuicEncryptedPacket> packet(
- framer.BuildPublicResetPacket(header));
- client_writer_->WritePacket(
- packet->data(), packet->length(),
- client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
-
- // The connection should be unaffected.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-// Send a version negotiation packet from the server for a different
-// connection ID. It should be ignored.
-TEST_P(EndToEndTestWithTls,
- ServerSendVersionNegotiationWithDifferentConnectionId) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Send the version negotiation packet.
- QuicConnectionId incorrect_connection_id =
- client_->client()->client_session()->connection()->connection_id() + 1;
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(incorrect_connection_id, false,
- server_supported_versions_));
- testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
- client_->client()->client_session()->connection()->set_debug_visitor(
- &visitor);
- EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
- .Times(1);
- // We must pause the server's thread in order to call WritePacket without
- // race conditions.
- server_thread_->Pause();
- server_writer_->WritePacket(
- packet->data(), packet->length(), server_address_.host(),
- client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
- server_thread_->Resume();
-
- // The connection should be unaffected.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- client_->client()->client_session()->connection()->set_debug_visitor(nullptr);
-}
-
-// A bad header shouldn't tear down the connection, because the receiver can't
-// tell the connection ID.
-TEST_P(EndToEndTestWithTls, BadPacketHeaderTruncated) {
- ASSERT_TRUE(Initialize());
-
- // Start the connection.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Packet with invalid public flags.
- char packet[] = {// public flags (8 byte connection_id)
- 0x3C,
- // truncated connection ID
- 0x11};
- client_writer_->WritePacket(
- &packet[0], sizeof(packet),
- client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
- // Give the server time to process the packet.
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- EXPECT_EQ(QUIC_INVALID_PACKET_HEADER,
- QuicDispatcherPeer::GetAndClearLastError(dispatcher));
- server_thread_->Resume();
-
- // The connection should not be terminated.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-// A bad header shouldn't tear down the connection, because the receiver can't
-// tell the connection ID.
-TEST_P(EndToEndTestWithTls, BadPacketHeaderFlags) {
- ASSERT_TRUE(Initialize());
-
- // Start the connection.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Packet with invalid public flags.
- char packet[] = {
- // invalid public flags
- 0xFF,
- // connection_id
- 0x10,
- 0x32,
- 0x54,
- 0x76,
- 0x98,
- 0xBA,
- 0xDC,
- 0xFE,
- // packet sequence number
- 0xBC,
- 0x9A,
- 0x78,
- 0x56,
- 0x34,
- 0x12,
- // private flags
- 0x00,
- };
- client_writer_->WritePacket(
- &packet[0], sizeof(packet),
- client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
- // Give the server time to process the packet.
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- EXPECT_EQ(QUIC_INVALID_PACKET_HEADER,
- QuicDispatcherPeer::GetAndClearLastError(dispatcher));
- server_thread_->Resume();
-
- // The connection should not be terminated.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-// Send a packet from the client with bad encrypted data. The server should not
-// tear down the connection.
-TEST_P(EndToEndTestWithTls, BadEncryptedData) {
- ASSERT_TRUE(Initialize());
-
- // Start the connection.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- client_->client()->client_session()->connection()->connection_id(), false,
- false, 1, "At least 20 characters.", PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER));
- // Damage the encrypted data.
- QuicString damaged_packet(packet->data(), packet->length());
- damaged_packet[30] ^= 0x01;
- QUIC_DLOG(INFO) << "Sending bad packet.";
- client_writer_->WritePacket(
- damaged_packet.data(), damaged_packet.length(),
- client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
- // Give the server time to process the packet.
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
- // This error is sent to the connection's OnError (which ignores it), so the
- // dispatcher doesn't see it.
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- EXPECT_EQ(QUIC_NO_ERROR,
- QuicDispatcherPeer::GetAndClearLastError(dispatcher));
- server_thread_->Resume();
-
- // The connection should not be terminated.
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-}
-
-TEST_P(EndToEndTestWithTls, CanceledStreamDoesNotBecomeZombie) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- // Lose the request.
- SetPacketLossPercentage(100);
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- client_->SendMessage(headers, "test_body", /*fin=*/false);
- QuicSpdyClientStream* stream = client_->GetOrCreateStream();
-
- // Cancel the stream.
- stream->Reset(QUIC_STREAM_CANCELLED);
- QuicSession* session = client_->client()->client_session();
- // Verify canceled stream does not become zombie.
- EXPECT_TRUE(QuicSessionPeer::zombie_streams(session).empty());
- EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
-}
-
-// A test stream that gives |response_body_| as an error response body.
-class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
- public:
- ServerStreamWithErrorResponseBody(QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache,
- QuicString response_body)
- : QuicSimpleServerStream(id, session, response_cache),
- response_body_(std::move(response_body)) {}
-
- ~ServerStreamWithErrorResponseBody() override = default;
-
- protected:
- void SendErrorResponse() override {
- QUIC_DLOG(INFO) << "Sending error response for stream " << id();
- SpdyHeaderBlock headers;
- headers[":status"] = "500";
- headers["content-length"] =
- QuicTextUtils::Uint64ToString(response_body_.size());
- // This method must call CloseReadSide to cause the test case, StopReading
- // is not sufficient.
- QuicStreamPeer::CloseReadSide(this);
- SendHeadersAndBody(std::move(headers), response_body_);
- }
-
- QuicString response_body_;
-};
-
-class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
- public:
- explicit StreamWithErrorFactory(QuicString response_body)
- : response_body_(std::move(response_body)) {}
-
- ~StreamWithErrorFactory() override = default;
-
- QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache) override {
- return new ServerStreamWithErrorResponseBody(id, session, response_cache,
- response_body_);
- }
-
- private:
- QuicString response_body_;
-};
-
-// A test server stream that drops all received body.
-class ServerStreamThatDropsBody : public QuicSimpleServerStream {
- public:
- ServerStreamThatDropsBody(QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache)
- : QuicSimpleServerStream(id, session, response_cache) {}
-
- ~ServerStreamThatDropsBody() override = default;
-
- protected:
- void OnDataAvailable() override {
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- // No more data to read.
- break;
- }
- QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
- << id();
- MarkConsumed(iov.iov_len);
- }
-
- if (!sequencer()->IsClosed()) {
- sequencer()->SetUnblocked();
- return;
- }
-
- // If the sequencer is closed, then all the body, including the fin, has
- // been consumed.
- OnFinRead();
-
- if (write_side_closed() || fin_buffered()) {
- return;
- }
-
- SendResponse();
- }
-};
-
-class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
- public:
- ServerStreamThatDropsBodyFactory() = default;
-
- ~ServerStreamThatDropsBodyFactory() override = default;
-
- QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache) override {
- return new ServerStreamThatDropsBody(id, session, response_cache);
- }
-};
-
-// A test server stream that sends response with body size greater than 4GB.
-class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
- public:
- ServerStreamThatSendsHugeResponse(QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache,
- int64_t body_bytes)
- : QuicSimpleServerStream(id, session, response_cache),
- body_bytes_(body_bytes) {}
-
- ~ServerStreamThatSendsHugeResponse() override = default;
-
- protected:
- void SendResponse() override {
- QuicHttpResponseCache::Response response;
- QuicString body(body_bytes_, 'a');
- response.set_body(body);
- SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
- response.trailers().Clone());
- }
-
- private:
- // Use a explicit int64_t rather than size_t to simulate a 64-bit server
- // talking to a 32-bit client.
- int64_t body_bytes_;
-};
-
-class ServerStreamThatSendsHugeResponseFactory
- : public QuicTestServer::StreamFactory {
- public:
- explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
- : body_bytes_(body_bytes) {}
-
- ~ServerStreamThatSendsHugeResponseFactory() override = default;
-
- QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache) override {
- return new ServerStreamThatSendsHugeResponse(id, session, response_cache,
- body_bytes_);
- }
-
- int64_t body_bytes_;
-};
-
-// A test client stream that drops all received body.
-class ClientStreamThatDropsBody : public QuicSpdyClientStream {
- public:
- ClientStreamThatDropsBody(QuicStreamId id, QuicSpdyClientSession* session)
- : QuicSpdyClientStream(id, session) {}
- ~ClientStreamThatDropsBody() override = default;
-
- void OnDataAvailable() override {
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- break;
- }
- MarkConsumed(iov.iov_len);
- }
- if (sequencer()->IsClosed()) {
- OnFinRead();
- } else {
- sequencer()->SetUnblocked();
- }
- }
-};
-
-class ClientSessionThatDropsBody : public QuicSpdyClientSession {
- public:
- ClientSessionThatDropsBody(const QuicConfig& config,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSession(config,
- connection,
- server_id,
- crypto_config,
- push_promise_index) {}
-
- ~ClientSessionThatDropsBody() override = default;
-
- std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override {
- return QuicMakeUnique<ClientStreamThatDropsBody>(GetNextOutgoingStreamId(),
- this);
- }
-};
-
-class MockableQuicClientThatDropsBody : public MockableQuicClient {
- public:
- MockableQuicClientThatDropsBody(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server)
- : MockableQuicClient(server_address,
- server_id,
- config,
- supported_versions,
- epoll_server) {}
- ~MockableQuicClientThatDropsBody() override = default;
-
- std::unique_ptr<QuicSession> CreateQuicClientSession(
- QuicConnection* connection) override {
- return QuicMakeUnique<ClientSessionThatDropsBody>(
- *config(), connection, server_id(), crypto_config(),
- push_promise_index());
- }
-};
-
-class QuicTestClientThatDropsBody : public QuicTestClient {
- public:
- QuicTestClientThatDropsBody(QuicSocketAddress server_address,
- const QuicString& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions)
- : QuicTestClient(server_address,
- server_hostname,
- config,
- supported_versions) {
- set_client(new MockableQuicClientThatDropsBody(
- server_address,
- QuicServerId(server_hostname, server_address.port(),
- PRIVACY_MODE_DISABLED),
- config, supported_versions, epoll_server()));
- }
- ~QuicTestClientThatDropsBody() override = default;
-};
-
-TEST_P(EndToEndTest, EarlyResponseFinRecording) {
- set_smaller_flow_control_receive_window();
-
- // Verify that an incoming FIN is recorded in a stream object even if the read
- // side has been closed. This prevents an entry from being made in
- // locally_close_streams_highest_offset_ (which will never be deleted).
- // To set up the test condition, the server must do the following in order:
- // start sending the response and call CloseReadSide
- // receive the FIN of the request
- // send the FIN of the response
-
- // The response body must be larger than the flow control window so the server
- // must receive a window update from the client before it can finish sending
- // it.
- uint32_t response_body_size =
- 2 * client_config_.GetInitialStreamFlowControlWindowToSend();
- QuicString response_body(response_body_size, 'a');
-
- StreamWithErrorFactory stream_factory(response_body);
- SetSpdyStreamFactory(&stream_factory);
-
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // A POST that gets an early error response, after the headers are received
- // and before the body is received, due to invalid content-length.
- // Set an invalid content-length, so the request will receive an early 500
- // response.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/garbage";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] = "-1";
-
- // The body must be large enough that the FIN will be in a different packet
- // than the end of the headers, but short enough to not require a flow control
- // update. This allows headers processing to trigger the error response
- // before the request FIN is processed but receive the request FIN before the
- // response is sent completely.
- const uint32_t kRequestBodySize = kMaxPacketSize + 10;
- QuicString request_body(kRequestBodySize, 'a');
-
- // Send the request.
- client_->SendMessage(headers, request_body);
- client_->WaitForResponse();
- EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
-
- // Pause the server so we can access the server's internals without races.
- server_thread_->Pause();
-
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- QuicDispatcher::SessionMap const& map =
- QuicDispatcherPeer::session_map(dispatcher);
- QuicDispatcher::SessionMap::const_iterator it = map.begin();
- EXPECT_TRUE(it != map.end());
- QuicSession* server_session = it->second.get();
-
- // The stream is not waiting for the arrival of the peer's final offset.
- EXPECT_EQ(
- 0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
- .size());
-
- server_thread_->Resume();
-}
-
-TEST_P(EndToEndTestWithTls, Trailers) {
- // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Set reordering to ensure that Trailers arriving before body is ok.
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(30);
-
- // Add a response with headers, body, and trailers.
- const QuicString kBody = "body content";
-
- SpdyHeaderBlock headers;
- headers[":status"] = "200";
- headers[":version"] = "HTTP/1.1";
- headers["content-length"] = QuicTextUtils::Uint64ToString(kBody.size());
-
- SpdyHeaderBlock trailers;
- trailers["some-trailing-header"] = "trailing-header-value";
-
- response_cache_.AddResponse(server_hostname_, "/trailer_url",
- std::move(headers), kBody, trailers.Clone());
-
- EXPECT_EQ(kBody, client_->SendSynchronousRequest("/trailer_url"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
- EXPECT_EQ(trailers, client_->response_trailers());
-}
-
-class EndToEndTestServerPush : public EndToEndTest {
- protected:
- const size_t kNumMaxStreams = 10;
-
- EndToEndTestServerPush() : EndToEndTest() {
- client_config_.SetMaxStreamsPerConnection(kNumMaxStreams, kNumMaxStreams);
- client_config_.SetMaxIncomingDynamicStreamsToSend(kNumMaxStreams);
- server_config_.SetMaxStreamsPerConnection(kNumMaxStreams, kNumMaxStreams);
- server_config_.SetMaxIncomingDynamicStreamsToSend(kNumMaxStreams);
- support_server_push_ = true;
- }
-
- // Add a request with its response and |num_resources| push resources into
- // cache.
- // If |resource_size| == 0, response body of push resources use default string
- // concatenating with resource url. Otherwise, generate a string of
- // |resource_size| as body.
- void AddRequestAndResponseWithServerPush(QuicString host,
- QuicString path,
- QuicString response_body,
- QuicString* push_urls,
- const size_t num_resources,
- const size_t resource_size) {
- bool use_large_response = resource_size != 0;
- QuicString large_resource;
- if (use_large_response) {
- // Generate a response common body larger than flow control window for
- // push response.
- large_resource = QuicString(resource_size, 'a');
- }
- std::list<QuicHttpResponseCache::ServerPushInfo> push_resources;
- for (size_t i = 0; i < num_resources; ++i) {
- QuicString url = push_urls[i];
- QuicUrl resource_url(url);
- QuicString body =
- use_large_response
- ? large_resource
- : QuicStrCat("This is server push response body for ", url);
- SpdyHeaderBlock response_headers;
- response_headers[":version"] = "HTTP/1.1";
- response_headers[":status"] = "200";
- response_headers["content-length"] =
- QuicTextUtils::Uint64ToString(body.size());
- push_resources.push_back(QuicHttpResponseCache::ServerPushInfo(
- resource_url, std::move(response_headers), kV3LowestPriority, body));
- }
-
- response_cache_.AddSimpleResponseWithServerPushResources(
- host, path, 200, response_body, push_resources);
- }
-};
-
-// Run all server push end to end tests with all supported versions.
-INSTANTIATE_TEST_CASE_P(EndToEndTestsServerPush,
- EndToEndTestServerPush,
- ::testing::ValuesIn(GetTestParams(false)));
-
-TEST_P(EndToEndTestServerPush, ServerPush) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(30);
-
- // Add a response with headers, body, and push resources.
- const QuicString kBody = "body content";
- size_t kNumResources = 4;
- QuicString push_urls[] = {"https://example.com/font.woff",
- "https://example.com/script.js",
- "https://fonts.example.com/font.woff",
- "https://example.com/logo-hires.jpg"};
- AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
- push_urls, kNumResources, 0);
-
- client_->client()->set_response_listener(
- std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
- new TestResponseListener));
-
- QUIC_DVLOG(1) << "send request for /push_example";
- EXPECT_EQ(kBody, client_->SendSynchronousRequest(
- "https://example.com/push_example"));
- QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(
- client_->client()->client_session());
- QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
- // Headers stream's sequencer buffer shouldn't be released because server push
- // hasn't finished yet.
- EXPECT_TRUE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
-
- for (const QuicString& url : push_urls) {
- QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
- QuicString expected_body =
- QuicStrCat("This is server push response body for ", url);
- QuicString response_body = client_->SendSynchronousRequest(url);
- QUIC_DVLOG(1) << "response body " << response_body;
- EXPECT_EQ(expected_body, response_body);
- }
- EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
-}
-
-TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
- // Tests that sending a request which has 4 push resources will trigger server
- // to push those 4 resources and client can handle pushed resources and match
- // them with requests later.
- ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(30);
-
- // Add a response with headers, body, and push resources.
- const QuicString kBody = "body content";
- size_t const kNumResources = 4;
- QuicString push_urls[] = {
- "https://example.com/font.woff", "https://example.com/script.js",
- "https://fonts.example.com/font.woff",
- "https://example.com/logo-hires.jpg",
- };
- AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
- push_urls, kNumResources, 0);
- client_->client()->set_response_listener(
- std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
- new TestResponseListener));
-
- // Send the first request: this will trigger the server to send all the push
- // resources associated with this request, and these will be cached by the
- // client.
- EXPECT_EQ(kBody, client_->SendSynchronousRequest(
- "https://example.com/push_example"));
-
- for (const QuicString& url : push_urls) {
- // Sending subsequent requesets will not actually send anything on the wire,
- // as the responses are already in the client's cache.
- QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
- QuicString expected_body =
- QuicStrCat("This is server push response body for ", url);
- QuicString response_body = client_->SendSynchronousRequest(url);
- QUIC_DVLOG(1) << "response body " << response_body;
- EXPECT_EQ(expected_body, response_body);
- }
- // Expect only original request has been sent and push responses have been
- // received as normal response.
- EXPECT_EQ(1u, client_->num_requests());
- EXPECT_EQ(1u + kNumResources, client_->num_responses());
-}
-
-TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
- // Tests that when streams are not blocked by flow control or congestion
- // control, pushing even more resources than max number of open outgoing
- // streams should still work because all response streams get closed
- // immediately after pushing resources.
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(30);
-
- // Add a response with headers, body, and push resources.
- const QuicString kBody = "body content";
-
- // One more resource than max number of outgoing stream of this session.
- const size_t kNumResources = 1 + kNumMaxStreams; // 11.
- QuicString push_urls[11];
- for (size_t i = 0; i < kNumResources; ++i) {
- push_urls[i] = QuicStrCat("https://example.com/push_resources", i);
- }
- AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
- push_urls, kNumResources, 0);
- client_->client()->set_response_listener(
- std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
- new TestResponseListener));
-
- // Send the first request: this will trigger the server to send all the push
- // resources associated with this request, and these will be cached by the
- // client.
- EXPECT_EQ(kBody, client_->SendSynchronousRequest(
- "https://example.com/push_example"));
-
- for (const QuicString& url : push_urls) {
- // Sending subsequent requesets will not actually send anything on the wire,
- // as the responses are already in the client's cache.
- EXPECT_EQ(QuicStrCat("This is server push response body for ", url),
- client_->SendSynchronousRequest(url));
- }
-
- // Only 1 request should have been sent.
- EXPECT_EQ(1u, client_->num_requests());
- // The responses to the original request and all the promised resources
- // should have been received.
- EXPECT_EQ(12u, client_->num_responses());
-}
-
-TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
- // Tests that when server tries to send more large resources(large enough to
- // be blocked by flow control window or congestion control window) than max
- // open outgoing streams , server can open upto max number of outgoing
- // streams for them, and the rest will be queued up.
-
- // Reset flow control windows.
- size_t kFlowControlWnd = 20 * 1024; // 20KB.
- // Response body is larger than 1 flow controlblock window.
- size_t kBodySize = kFlowControlWnd * 2;
- set_client_initial_stream_flow_control_receive_window(kFlowControlWnd);
- // Make sure conntection level flow control window is large enough not to
- // block data being sent out though they will be blocked by stream level one.
- set_client_initial_session_flow_control_receive_window(
- kBodySize * kNumMaxStreams + 1024);
-
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
- SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
- SetReorderPercentage(30);
-
- // Add a response with headers, body, and push resources.
- const QuicString kBody = "body content";
-
- const size_t kNumResources = kNumMaxStreams + 1;
- QuicString push_urls[11];
- for (size_t i = 0; i < kNumResources; ++i) {
- push_urls[i] = QuicStrCat("http://example.com/push_resources", i);
- }
- AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
- push_urls, kNumResources, kBodySize);
-
- client_->client()->set_response_listener(
- std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
- new TestResponseListener));
-
- client_->SendRequest("https://example.com/push_example");
-
- // Pause after the first response arrives.
- while (!client_->response_complete()) {
- // Because of priority, the first response arrived should be to original
- // request.
- client_->WaitForResponse();
- }
-
- // Check server session to see if it has max number of outgoing streams opened
- // though more resources need to be pushed.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- ASSERT_EQ(1u, dispatcher->session_map().size());
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- EXPECT_EQ(kNumMaxStreams, session->GetNumOpenOutgoingStreams());
- server_thread_->Resume();
-
- EXPECT_EQ(1u, client_->num_requests());
- EXPECT_EQ(1u, client_->num_responses());
- EXPECT_EQ(kBody, client_->response_body());
-
- // "Send" request for a promised resources will not really send out it because
- // its response is being pushed(but blocked). And the following ack and
- // flow control behavior of SendSynchronousRequests()
- // will unblock the stream to finish receiving response.
- client_->SendSynchronousRequest(push_urls[0]);
- EXPECT_EQ(1u, client_->num_requests());
- EXPECT_EQ(2u, client_->num_responses());
-
- // Do same thing for the rest 10 resources.
- for (size_t i = 1; i < kNumResources; ++i) {
- client_->SendSynchronousRequest(push_urls[i]);
- }
-
- // Because of server push, client gets all pushed resources without actually
- // sending requests for them.
- EXPECT_EQ(1u, client_->num_requests());
- // Including response to original request, 12 responses in total were
- // recieved.
- EXPECT_EQ(12u, client_->num_responses());
-}
-
-// TODO(fayang): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
- // This test tests a huge post with introduced packet loss from client to
- // server and body size greater than 4GB, making sure QUIC code does not break
- // for 32-bit builds.
- ServerStreamThatDropsBodyFactory stream_factory;
- SetSpdyStreamFactory(&stream_factory);
- ASSERT_TRUE(Initialize());
- // Set client's epoll server's time out to 0 to make this test be finished
- // within a short time.
- client_->epoll_server()->set_timeout_in_us(0);
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- SetPacketLossPercentage(1);
- // To avoid storing the whole request body in memory, use a loop to repeatedly
- // send body size of kSizeBytes until the whole request body size is reached.
- const int kSizeBytes = 128 * 1024;
- // Request body size is 4G plus one more kSizeBytes.
- int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
- ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
- QuicString body(kSizeBytes, 'a');
-
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["content-length"] =
- QuicTextUtils::Uint64ToString(request_body_size_bytes);
-
- client_->SendMessage(headers, "", /*fin=*/false);
-
- for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
- bool fin = (i == request_body_size_bytes - 1);
- client_->SendData(QuicString(body.data(), kSizeBytes), fin);
- client_->client()->WaitForEvents();
- }
- VerifyCleanConnection(true);
-}
-
-// TODO(fayang): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
- // This test tests a huge response with introduced loss from server to client
- // and body size greater than 4GB, making sure QUIC code does not break for
- // 32-bit builds.
- const int kSizeBytes = 128 * 1024;
- int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
- ASSERT_LT(4294967296, response_body_size_bytes);
- ServerStreamThatSendsHugeResponseFactory stream_factory(
- response_body_size_bytes);
- SetSpdyStreamFactory(&stream_factory);
-
- StartServer();
-
- // Use a quic client that drops received body.
- QuicTestClient* client = new QuicTestClientThatDropsBody(
- server_address_, server_hostname_, client_config_,
- client_supported_versions_);
- client->UseWriter(client_writer_);
- client->Connect();
- client_.reset(client);
- static EpollEvent event(EPOLLOUT);
- client_writer_->Initialize(
- QuicConnectionPeer::GetHelper(
- client_->client()->client_session()->connection()),
- QuicConnectionPeer::GetAlarmFactory(
- client_->client()->client_session()->connection()),
- new ClientDelegate(client_->client()));
- initialized_ = true;
- ASSERT_TRUE(client_->client()->connected());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- SetPacketLossPercentage(1);
- client_->SendRequest("/huge_response");
- client_->WaitForResponse();
- // TODO(fayang): Fix this test to work with stateless rejects.
- if (!BothSidesSupportStatelessRejects()) {
- VerifyCleanConnection(true);
- }
-}
-
-TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
- // Tests that when client side has no active request and no waiting
- // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
- ASSERT_TRUE(Initialize());
- client_->SendSynchronousRequest("/foo");
- QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(
- client_->client()->client_session());
- QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
- EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
-}
-
-TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
- ASSERT_TRUE(Initialize());
- SpdyHeaderBlock headers;
- headers[":method"] = "GET";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
- headers["key"] = QuicString(64 * 1024, 'a');
-
- client_->SendMessage(headers, "");
- client_->WaitForResponse();
- EXPECT_EQ(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
- client_->connection_error());
-}
-
-class WindowUpdateObserver : public QuicConnectionDebugVisitor {
- public:
- WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
-
- size_t num_window_update_frames() const { return num_window_update_frames_; }
-
- size_t num_ping_frames() const { return num_ping_frames_; }
-
- void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
- const QuicTime& receive_time) override {
- ++num_window_update_frames_;
- }
-
- void OnPingFrame(const QuicPingFrame& frame) override { ++num_ping_frames_; }
-
- private:
- size_t num_window_update_frames_;
- size_t num_ping_frames_;
-};
-
-TEST_P(EndToEndTest, WindowUpdateInAck) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- WindowUpdateObserver observer;
- QuicConnection* client_connection =
- client_->client()->client_session()->connection();
- client_connection->set_debug_visitor(&observer);
- QuicTransportVersion version = client_connection->transport_version();
- // 100KB body.
- QuicString body(100 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- EXPECT_EQ(kFooResponseBody,
- client_->SendCustomSynchronousRequest(headers, body));
- client_->Disconnect();
- if (version > QUIC_VERSION_38) {
- EXPECT_LT(0u, observer.num_window_update_frames());
- if (GetQuicReloadableFlag(quic_remove_redundant_ping)) {
- EXPECT_EQ(0u, observer.num_ping_frames());
- } else {
- // A redundant PING frame is bundled with each WINDOW_UPDATE frame.
- EXPECT_EQ(observer.num_window_update_frames(),
- observer.num_ping_frames());
- }
- } else {
- EXPECT_EQ(0u, observer.num_window_update_frames());
- }
-}
-
-TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
- ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- QuicConfig* config = client_->client()->session()->config();
- EXPECT_TRUE(config->HasReceivedStatelessResetToken());
- EXPECT_EQ(1010101u, config->ReceivedStatelessResetToken());
- client_->Disconnect();
-}
-
-// Regression test of b/70782529.
-TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
- ASSERT_TRUE(Initialize());
- BadPacketWriter* bad_writer =
- new BadPacketWriter(/*packet_causing_write_error=*/5,
- /*error_code=*/90);
- std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
-
- // 1 MB body.
- QuicString body(1024 * 1024, 'a');
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/foo";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- client->SendCustomSynchronousRequest(headers, body);
-}
-
-// Regression test for b/71711996. This test sends a connectivity probing packet
-// as its last sent packet, and makes sure the server's ACK of that packet does
-// not cause the client to fail.
-TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
- ASSERT_TRUE(Initialize());
-
- EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
-
- // Wait for the client's ACK (of the response) to be received by the server.
- client_->WaitForDelayedAcks();
-
- // We are sending a connectivity probing packet from an unchanged client
- // address, so the server will not respond to us with a connectivity probing
- // packet, however the server should send an ack-only packet to us.
- client_->SendConnectivityProbing();
-
- // Wait for the server's last ACK to be received by the client.
- client_->WaitForDelayedAcks();
-}
-
-class EndToEndBufferedPacketsTest : public EndToEndTest {
- public:
- void CreateClientWithWriter() override {
- QUIC_LOG(ERROR) << "create client with reorder_writer_ ";
- reorder_writer_ = new PacketReorderingWriter();
- client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
- }
-
- void SetUp() override {
- // Don't initialize client writer in base class.
- server_writer_ = new PacketDroppingTestWriter();
- }
-
- protected:
- PacketReorderingWriter* reorder_writer_;
-};
-
-INSTANTIATE_TEST_CASE_P(EndToEndBufferedPacketsTests,
- EndToEndBufferedPacketsTest,
- testing::ValuesIn(GetTestParams(false)));
-
-TEST_P(EndToEndBufferedPacketsTest, Buffer0RttRequest) {
- ASSERT_TRUE(Initialize());
- // Finish one request to make sure handshake established.
- client_->SendSynchronousRequest("/foo");
- // Disconnect for next 0-rtt request.
- client_->Disconnect();
-
- // Client get valid STK now. Do a 0-rtt request.
- // Buffer a CHLO till another packets sent out.
- reorder_writer_->SetDelay(1);
- // Only send out a CHLO.
- client_->client()->Initialize();
- client_->client()->StartConnect();
- ASSERT_TRUE(client_->client()->connected());
-
- // Send a request before handshake finishes.
- SpdyHeaderBlock headers;
- headers[":method"] = "POST";
- headers[":path"] = "/bar";
- headers[":scheme"] = "https";
- headers[":authority"] = server_hostname_;
-
- client_->SendMessage(headers, "");
- client_->WaitForResponse();
- EXPECT_EQ(kBarResponseBody, client_->response_body());
- QuicConnectionStats client_stats =
- client_->client()->client_session()->connection()->GetStats();
- EXPECT_EQ(0u, client_stats.packets_lost);
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
-}
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/platform/impl/quic_epoll_clock.cc b/chromium/net/tools/quic/platform/impl/quic_epoll_clock.cc
deleted file mode 100644
index c44c9dd44fd..00000000000
--- a/chromium/net/tools/quic/platform/impl/quic_epoll_clock.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/tools/quic/platform/impl/quic_epoll_clock.h"
-
-#include "net/tools/epoll_server/epoll_server.h"
-
-namespace net {
-
-QuicEpollClock::QuicEpollClock(EpollServer* epoll_server)
- : epoll_server_(epoll_server) {}
-
-QuicEpollClock::~QuicEpollClock() = default;
-
-QuicTime QuicEpollClock::ApproximateNow() const {
- return QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(
- epoll_server_->ApproximateNowInUsec());
-}
-
-QuicTime QuicEpollClock::Now() const {
- return QuicTime::Zero() +
- QuicTime::Delta::FromMicroseconds(epoll_server_->NowInUsec());
-}
-
-QuicWallTime QuicEpollClock::WallNow() const {
- return QuicWallTime::FromUNIXMicroseconds(
- epoll_server_->ApproximateNowInUsec());
-}
-
-QuicTime QuicEpollClock::ConvertWallTimeToQuicTime(
- const QuicWallTime& walltime) const {
- return QuicTime::Zero() +
- QuicTime::Delta::FromMicroseconds(walltime.ToUNIXMicroseconds());
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/platform/impl/quic_epoll_clock.h b/chromium/net/tools/quic/platform/impl/quic_epoll_clock.h
deleted file mode 100644
index 8c125bcacdc..00000000000
--- a/chromium/net/tools/quic/platform/impl/quic_epoll_clock.h
+++ /dev/null
@@ -1,49 +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_TOOLS_QUIC_PLATFORM_IMPL_QUIC_EPOLL_CLOCK_H_
-#define NET_TOOLS_QUIC_PLATFORM_IMPL_QUIC_EPOLL_CLOCK_H_
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "net/quic/core/quic_time.h"
-#include "net/quic/platform/api/quic_clock.h"
-
-namespace net {
-
-class EpollServer;
-
-// Clock to efficiently retrieve an approximately accurate time from an
-// EpollServer.
-class QuicEpollClock : public QuicClock {
- public:
- explicit QuicEpollClock(EpollServer* epoll_server);
- ~QuicEpollClock() override;
-
- // Returns the approximate current time as a QuicTime object.
- QuicTime ApproximateNow() const override;
-
- // Returns the current time as a QuicTime object.
- // Note: this uses significant resources, please use only if needed.
- QuicTime Now() const override;
-
- // Returns the current time as a QuicWallTime object.
- // Note: this uses significant resources, please use only if needed.
- QuicWallTime WallNow() const override;
-
- // Override to do less work in this implementation. The epoll clock is
- // already based on system (unix epoch) time, no conversion required.
- QuicTime ConvertWallTimeToQuicTime(
- const QuicWallTime& walltime) const override;
-
- protected:
- EpollServer* epoll_server_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(QuicEpollClock);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_PLATFORM_IMPL_QUIC_EPOLL_CLOCK_H_
diff --git a/chromium/net/tools/quic/platform/impl/quic_epoll_clock_test.cc b/chromium/net/tools/quic/platform/impl/quic_epoll_clock_test.cc
deleted file mode 100644
index 52115a72c12..00000000000
--- a/chromium/net/tools/quic/platform/impl/quic_epoll_clock_test.cc
+++ /dev/null
@@ -1,48 +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/tools/quic/platform/impl/quic_epoll_clock.h"
-
-#include "net/quic/platform/api/quic_test.h"
-#include "net/tools/quic/test_tools/mock_epoll_server.h"
-
-namespace net {
-namespace test {
-
-class QuicEpollClockTest : public QuicTest {};
-
-TEST_F(QuicEpollClockTest, ApproximateNowInUsec) {
- MockEpollServer epoll_server;
- QuicEpollClock clock(&epoll_server);
-
- epoll_server.set_now_in_usec(1000000);
- EXPECT_EQ(1000000,
- (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
- EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
- EXPECT_EQ(1000000u, clock.WallNow().ToUNIXMicroseconds());
-
- epoll_server.AdvanceBy(5);
- EXPECT_EQ(1000005,
- (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
- EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
- EXPECT_EQ(1000005u, clock.WallNow().ToUNIXMicroseconds());
-
- epoll_server.AdvanceBy(10 * 1000000);
- EXPECT_EQ(11u, clock.WallNow().ToUNIXSeconds());
- EXPECT_EQ(11000005u, clock.WallNow().ToUNIXMicroseconds());
-}
-
-TEST_F(QuicEpollClockTest, NowInUsec) {
- MockEpollServer epoll_server;
- QuicEpollClock clock(&epoll_server);
-
- epoll_server.set_now_in_usec(1000000);
- EXPECT_EQ(1000000, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
-
- epoll_server.AdvanceBy(5);
- EXPECT_EQ(1000005, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/platform/impl/quic_socket_utils.cc b/chromium/net/tools/quic/platform/impl/quic_socket_utils.cc
deleted file mode 100644
index 434e96efec1..00000000000
--- a/chromium/net/tools/quic/platform/impl/quic_socket_utils.cc
+++ /dev/null
@@ -1,319 +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/tools/quic/platform/impl/quic_socket_utils.h"
-
-#include <errno.h>
-#include <linux/net_tstamp.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <string>
-
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-
-#ifndef SO_RXQ_OVFL
-#define SO_RXQ_OVFL 40
-#endif
-
-using std::string;
-
-namespace net {
-
-// static
-void QuicSocketUtils::GetAddressAndTimestampFromMsghdr(
- struct msghdr* hdr,
- QuicIpAddress* address,
- QuicWallTime* walltimestamp) {
- if (hdr->msg_controllen > 0) {
- for (cmsghdr* cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
- cmsg = CMSG_NXTHDR(hdr, cmsg)) {
- char* addr_data = nullptr;
- int len = 0;
- if (cmsg->cmsg_type == IPV6_PKTINFO) {
- in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
- addr_data = reinterpret_cast<char*>(&info->ipi6_addr);
- len = sizeof(in6_addr);
- address->FromPackedString(addr_data, len);
- } else if (cmsg->cmsg_type == IP_PKTINFO) {
- in_pktinfo* info = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
- addr_data = reinterpret_cast<char*>(&info->ipi_addr);
- len = sizeof(in_addr);
- address->FromPackedString(addr_data, len);
- } else if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SO_TIMESTAMPING) {
- LinuxTimestamping* lts =
- reinterpret_cast<LinuxTimestamping*>(CMSG_DATA(cmsg));
- timespec* ts = &lts->systime;
- int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) +
- (static_cast<int64_t>(ts->tv_nsec) / 1000);
- *walltimestamp = QuicWallTime::FromUNIXMicroseconds(usec);
- }
- }
- }
-}
-
-// static
-bool QuicSocketUtils::GetOverflowFromMsghdr(struct msghdr* hdr,
- QuicPacketCount* dropped_packets) {
- if (hdr->msg_controllen > 0) {
- struct cmsghdr* cmsg;
- for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
- cmsg = CMSG_NXTHDR(hdr, cmsg)) {
- if (cmsg->cmsg_type == SO_RXQ_OVFL) {
- *dropped_packets = *(reinterpret_cast<uint32_t*> CMSG_DATA(cmsg));
- return true;
- }
- }
- }
- return false;
-}
-
-// static
-bool QuicSocketUtils::GetTtlFromMsghdr(struct msghdr* hdr, int* ttl) {
- if (hdr->msg_controllen > 0) {
- struct cmsghdr* cmsg;
- for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
- cmsg = CMSG_NXTHDR(hdr, cmsg)) {
- if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
- (cmsg->cmsg_level == IPPROTO_IPV6 &&
- cmsg->cmsg_type == IPV6_HOPLIMIT)) {
- *ttl = *(reinterpret_cast<int*>(CMSG_DATA(cmsg)));
- return true;
- }
- }
- }
- return false;
-}
-
-// static
-int QuicSocketUtils::SetGetAddressInfo(int fd, int address_family) {
- int get_local_ip = 1;
- int rc = setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip,
- sizeof(get_local_ip));
- if (rc == 0 && address_family == AF_INET6) {
- rc = setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_local_ip,
- sizeof(get_local_ip));
- }
- return rc;
-}
-
-// static
-int QuicSocketUtils::SetGetSoftwareReceiveTimestamp(int fd) {
- int timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
- return setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &timestamping,
- sizeof(timestamping));
-}
-
-// static
-bool QuicSocketUtils::SetSendBufferSize(int fd, size_t size) {
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) != 0) {
- LOG(ERROR) << "Failed to set socket send size";
- return false;
- }
- return true;
-}
-
-// static
-bool QuicSocketUtils::SetReceiveBufferSize(int fd, size_t size) {
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) != 0) {
- LOG(ERROR) << "Failed to set socket recv size";
- return false;
- }
- return true;
-}
-
-// static
-int QuicSocketUtils::ReadPacket(int fd,
- char* buffer,
- size_t buf_len,
- QuicPacketCount* dropped_packets,
- QuicIpAddress* self_address,
- QuicWallTime* walltimestamp,
- QuicSocketAddress* peer_address) {
- DCHECK(peer_address != nullptr);
- char cbuf[kSpaceForCmsg];
- memset(cbuf, 0, arraysize(cbuf));
-
- iovec iov = {buffer, buf_len};
- struct sockaddr_storage raw_address;
- msghdr hdr;
-
- hdr.msg_name = &raw_address;
- hdr.msg_namelen = sizeof(sockaddr_storage);
- hdr.msg_iov = &iov;
- hdr.msg_iovlen = 1;
- hdr.msg_flags = 0;
-
- struct cmsghdr* cmsg = reinterpret_cast<struct cmsghdr*>(cbuf);
- cmsg->cmsg_len = arraysize(cbuf);
- hdr.msg_control = cmsg;
- hdr.msg_controllen = arraysize(cbuf);
-
- int bytes_read = recvmsg(fd, &hdr, 0);
-
- // Return before setting dropped packets: if we get EAGAIN, it will
- // be 0.
- if (bytes_read < 0 && errno != 0) {
- if (errno != EAGAIN) {
- LOG(ERROR) << "Error reading " << strerror(errno);
- }
- return -1;
- }
-
- if (hdr.msg_controllen >= arraysize(cbuf)) {
- QUIC_BUG << "Incorrectly set control length: " << hdr.msg_controllen
- << ", expected " << arraysize(cbuf);
- return -1;
- }
-
- if (dropped_packets != nullptr) {
- GetOverflowFromMsghdr(&hdr, dropped_packets);
- }
-
- QuicIpAddress stack_address;
- if (self_address == nullptr) {
- self_address = &stack_address;
- }
-
- QuicWallTime stack_walltimestamp = QuicWallTime::FromUNIXMicroseconds(0);
- if (walltimestamp == nullptr) {
- walltimestamp = &stack_walltimestamp;
- }
-
- GetAddressAndTimestampFromMsghdr(&hdr, self_address, walltimestamp);
-
- *peer_address = QuicSocketAddress(raw_address);
- return bytes_read;
-}
-
-size_t QuicSocketUtils::SetIpInfoInCmsg(const QuicIpAddress& self_address,
- cmsghdr* cmsg) {
- string address_string;
- if (self_address.IsIPv4()) {
- cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
- cmsg->cmsg_level = IPPROTO_IP;
- cmsg->cmsg_type = IP_PKTINFO;
- in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
- memset(pktinfo, 0, sizeof(in_pktinfo));
- pktinfo->ipi_ifindex = 0;
- address_string = self_address.ToPackedString();
- memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
- address_string.length());
- return sizeof(in_pktinfo);
- } else if (self_address.IsIPv6()) {
- cmsg->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
- cmsg->cmsg_level = IPPROTO_IPV6;
- cmsg->cmsg_type = IPV6_PKTINFO;
- in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
- memset(pktinfo, 0, sizeof(in6_pktinfo));
- address_string = self_address.ToPackedString();
- memcpy(&pktinfo->ipi6_addr, address_string.c_str(),
- address_string.length());
- return sizeof(in6_pktinfo);
- } else {
- NOTREACHED() << "Unrecognized IPAddress";
- return 0;
- }
-}
-
-// static
-WriteResult QuicSocketUtils::WritePacket(
- int fd,
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) {
- sockaddr_storage raw_address = peer_address.generic_address();
- iovec iov = {const_cast<char*>(buffer), buf_len};
-
- msghdr hdr;
- hdr.msg_name = &raw_address;
- hdr.msg_namelen = raw_address.ss_family == AF_INET ? sizeof(sockaddr_in)
- : sizeof(sockaddr_in6);
- hdr.msg_iov = &iov;
- hdr.msg_iovlen = 1;
- hdr.msg_flags = 0;
-
- const int kSpaceForIpv4 = CMSG_SPACE(sizeof(in_pktinfo));
- const int kSpaceForIpv6 = CMSG_SPACE(sizeof(in6_pktinfo));
- // kSpaceForIp should be big enough to hold both IPv4 and IPv6 packet info.
- const int kSpaceForIp =
- (kSpaceForIpv4 < kSpaceForIpv6) ? kSpaceForIpv6 : kSpaceForIpv4;
- char cbuf[kSpaceForIp];
- if (!self_address.IsInitialized()) {
- hdr.msg_control = nullptr;
- hdr.msg_controllen = 0;
- } else {
- hdr.msg_control = cbuf;
- hdr.msg_controllen = kSpaceForIp;
- cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
- SetIpInfoInCmsg(self_address, cmsg);
- hdr.msg_controllen = cmsg->cmsg_len;
- }
-
- int rc;
- do {
- rc = sendmsg(fd, &hdr, 0);
- } while (rc < 0 && errno == EINTR);
- if (rc >= 0) {
- return WriteResult(WRITE_STATUS_OK, rc);
- }
- return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
- ? WRITE_STATUS_BLOCKED
- : WRITE_STATUS_ERROR,
- errno);
-}
-
-// static
-int QuicSocketUtils::CreateUDPSocket(const QuicSocketAddress& address,
- int32_t receive_buffer_size,
- int32_t send_buffer_size,
- bool* overflow_supported) {
- int address_family = address.host().AddressFamilyToInt();
- int fd = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
- if (fd < 0) {
- QUIC_LOG(ERROR) << "socket() failed: " << strerror(errno);
- return -1;
- }
-
- int get_overflow = 1;
- int rc = setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
- sizeof(get_overflow));
- if (rc < 0) {
- QUIC_DLOG(WARNING) << "Socket overflow detection not supported";
- } else {
- *overflow_supported = true;
- }
-
- if (!SetReceiveBufferSize(fd, receive_buffer_size)) {
- return -1;
- }
-
- if (!SetSendBufferSize(fd, send_buffer_size)) {
- return -1;
- }
-
- rc = SetGetAddressInfo(fd, address_family);
- if (rc < 0) {
- LOG(ERROR) << "IP detection not supported" << strerror(errno);
- return -1;
- }
-
- rc = SetGetSoftwareReceiveTimestamp(fd);
- if (rc < 0) {
- QUIC_LOG(WARNING) << "SO_TIMESTAMPING not supported; using fallback: "
- << strerror(errno);
- }
-
- return fd;
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/platform/impl/quic_socket_utils.h b/chromium/net/tools/quic/platform/impl/quic_socket_utils.h
deleted file mode 100644
index 6db434fad5a..00000000000
--- a/chromium/net/tools/quic/platform/impl/quic_socket_utils.h
+++ /dev/null
@@ -1,134 +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 socket related helper methods for quic.
-
-#ifndef NET_TOOLS_QUIC_PLATFORM_IMPL_QUIC_SOCKET_UTILS_H_
-#define NET_TOOLS_QUIC_PLATFORM_IMPL_QUIC_SOCKET_UTILS_H_
-
-#include <netinet/in.h>
-#include <stddef.h>
-#include <sys/socket.h>
-
-#include <string>
-
-#include "base/macros.h"
-#include "net/base/ip_address.h"
-#include "net/base/ip_endpoint.h"
-#include "net/quic/core/quic_bandwidth.h"
-#include "net/quic/core/quic_types.h"
-
-namespace net {
-class QuicIpAddress;
-class QuicSocketAddress;
-
-// This is the structure that SO_TIMESTAMPING fills into the cmsg header. It is
-// well-defined, but does not have a definition in a public header. See
-// https://www.kernel.org/doc/Documentation/networking/timestamping.txt for more
-// information.
-struct LinuxTimestamping {
- // The converted system time of the timestamp.
- struct timespec systime;
- // Deprecated; serves only as padding.
- struct timespec hwtimetrans;
- // The raw hardware timestamp.
- struct timespec hwtimeraw;
-};
-
-class QuicSocketUtils {
- public:
- // The first integer is for overflow. The in6_pktinfo is the larger of the
- // address structures present. LinuxTimestamping is present for socket
- // timestamping. The subsequent int is for ttl.
- // The final int is a sentinel so the msg_controllen feedback
- // can be used to detect larger control messages than there is space for.
- static const int kSpaceForCmsg =
- CMSG_SPACE(CMSG_LEN(sizeof(int)) + CMSG_LEN(sizeof(in6_pktinfo)) +
- CMSG_LEN(sizeof(LinuxTimestamping)) +
- CMSG_LEN(sizeof(int)) +
- CMSG_LEN(sizeof(int)));
-
- // Fills in |address| if |hdr| contains IP_PKTINFO or IPV6_PKTINFO. Fills in
- // |timestamp| if |hdr| contains |SO_TIMESTAMPING|. |address| and |timestamp|
- // must not be null.
- static void GetAddressAndTimestampFromMsghdr(struct msghdr* hdr,
- QuicIpAddress* address,
- QuicWallTime* walltimestamp);
-
- // If the msghdr contains an SO_RXQ_OVFL entry, this will set dropped_packets
- // to the correct value and return true. Otherwise it will return false.
- static bool GetOverflowFromMsghdr(struct msghdr* hdr,
- QuicPacketCount* dropped_packets);
-
- // If the msghdr contains an IP_TTL entry, this will set ttl to the correct
- // value and return true. Otherwise it will return false.
- static bool GetTtlFromMsghdr(struct msghdr* hdr, int* ttl);
-
- // Sets either IP_PKTINFO or IPV6_PKTINFO on the socket, based on
- // address_family. Returns the return code from setsockopt.
- static int SetGetAddressInfo(int fd, int address_family);
-
- // Sets SO_TIMESTAMPING on the socket for software receive timestamping.
- // Returns the return code from setsockopt.
- static int SetGetSoftwareReceiveTimestamp(int fd);
-
- // Sets the send buffer size to |size| and returns false if it fails.
- static bool SetSendBufferSize(int fd, size_t size);
-
- // Sets the receive buffer size to |size| and returns false if it fails.
- static bool SetReceiveBufferSize(int fd, size_t size);
-
- // Reads buf_len from the socket. If reading is successful, returns bytes
- // read and sets peer_address to the peer address. Otherwise returns -1.
- //
- // If dropped_packets is non-null, it will be set to the number of packets
- // dropped on the socket since the socket was created, assuming the kernel
- // supports this feature.
- //
- // If self_address is non-null, it will be set to the address the peer sent
- // packets to, assuming a packet was read.
- //
- // If timestamp is non-null, it will be filled with the timestamp of the
- // received packet, assuming a packet was read and the platform supports
- // packet receipt timestamping. If the platform does not support packet
- // receipt timestamping, timestamp will not be changed.
- static int ReadPacket(int fd,
- char* buffer,
- size_t buf_len,
- QuicPacketCount* dropped_packets,
- QuicIpAddress* self_address,
- QuicWallTime* walltimestamp,
- QuicSocketAddress* peer_address);
-
- // Writes buf_len to the socket. If writing is successful, sets the result's
- // status to WRITE_STATUS_OK and sets bytes_written. Otherwise sets the
- // result's status to WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR and sets
- // error_code to errno.
- static WriteResult WritePacket(int fd,
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address);
-
- // A helper for WritePacket which fills in the cmsg with the supplied self
- // address.
- // Returns the length of the packet info structure used.
- static size_t SetIpInfoInCmsg(const QuicIpAddress& self_address,
- cmsghdr* cmsg);
-
- // Creates a UDP socket and sets appropriate socket options for QUIC.
- // Returns the created FD if successful, -1 otherwise.
- // |overflow_supported| is set to true if the socket supports it.
- static int CreateUDPSocket(const QuicSocketAddress& address,
- int32_t receive_buffer_size,
- int32_t send_buffer_size,
- bool* overflow_supported);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(QuicSocketUtils);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_PLATFORM_IMPL_QUIC_SOCKET_UTILS_H_
diff --git a/chromium/net/tools/quic/platform/impl/quic_socket_utils_test.cc b/chromium/net/tools/quic/platform/impl/quic_socket_utils_test.cc
deleted file mode 100644
index 7d5d173b828..00000000000
--- a/chromium/net/tools/quic/platform/impl/quic_socket_utils_test.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2013 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/tools/quic/platform/impl/quic_socket_utils.h"
-
-#include <fcntl.h>
-
-#include <array>
-
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_test.h"
-
-namespace net {
-namespace test {
-namespace {
-
-// A test fixture is used to ensure that all sockets are closed down gracefully
-// upon test completion. Also provides a convenient API to Bind not presently
-// available in QuicSocketUtils.
-class QuicSocketUtilsTest : public QuicTest {
- protected:
- ~QuicSocketUtilsTest() override {
- for (int fd : open_sockets_) {
- close(fd);
- }
- }
-
- int CreateUDPSocket(const QuicSocketAddress& address) {
- bool overflow_supported = false;
- int fd = QuicSocketUtils::CreateUDPSocket(
- address, /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer, &overflow_supported);
- if (fd != -1) {
- open_sockets_.push_back(fd);
- }
- return fd;
- }
-
- int CreateBoundUDPSocket(QuicSocketAddress* address) {
- int fd = CreateUDPSocket(*address);
- *address = BindSocket(fd, *address);
- if (!address->IsInitialized()) {
- close(fd);
- fd = -1;
- }
- return fd;
- }
-
- QuicSocketAddress BindSocket(int fd, const QuicSocketAddress& address) {
- QuicSocketAddress bound_address;
-
- if (fd == -1) {
- return bound_address;
- }
-
- sockaddr_storage bind_addr_native = address.generic_address();
- socklen_t bind_addr_size = 0;
-
- switch (address.host().address_family()) {
- case IpAddressFamily::IP_V4:
- bind_addr_size = sizeof(struct sockaddr_in);
- break;
- case IpAddressFamily::IP_V6:
- bind_addr_size = sizeof(struct sockaddr_in6);
- break;
- case IpAddressFamily::IP_UNSPEC:
- QUIC_LOG(FATAL) << "Unspecified IP address family";
- }
-
- int rc = bind(fd, reinterpret_cast<sockaddr*>(&bind_addr_native),
- bind_addr_size);
- if (rc != 0) {
- QUIC_LOG(ERROR) << "Failed to bind socket to " << address.ToString()
- << ": " << strerror(errno);
- return bound_address;
- }
-
- rc = bound_address.FromSocket(fd);
- if (rc != 0) {
- QUIC_LOG(ERROR) << "Failed to get bound socket address from fd: "
- << strerror(errno);
- bound_address = QuicSocketAddress();
- }
- return bound_address;
- }
-
- private:
- std::vector<int> open_sockets_;
-};
-
-// This test verifies that QuicSocketUtils creates a non-blocking socket
-// successfully by seeing if a read blocks.
-TEST_F(QuicSocketUtilsTest, NonBlockingSocket) {
- std::array<char, 512> buffer;
-
- QuicIpAddress localhost = QuicIpAddress::Loopback4();
- QuicSocketAddress addr(localhost, 0);
-
- int fd = CreateUDPSocket(addr);
- ASSERT_NE(-1, fd);
-
- int fd_flags = fcntl(fd, F_GETFL, 0);
-
- // Assert so that the test errors out quickly rather than blocking below and
- // relying on timeouts.
- ASSERT_TRUE(fd_flags & O_NONBLOCK) << "Socket not reporting as non-blocking";
-
- QuicIpAddress target_server_addr;
- auto walltimestamp = QuicWallTime::Zero();
- QuicSocketAddress remote_addr;
- int bytes_read = QuicSocketUtils::ReadPacket(fd, buffer.data(), buffer.size(),
- nullptr, &target_server_addr,
- &walltimestamp, &remote_addr);
- EXPECT_EQ(-1, bytes_read);
-}
-
-// This test verifies that we can successfully WritePacket/ReadPacket between
-// two localhost sockets.
-TEST_F(QuicSocketUtilsTest, PacketRoundTrip) {
- QuicIpAddress localhost = QuicIpAddress::Loopback4();
- QuicSocketAddress client_addr(localhost, 0);
- QuicSocketAddress server_addr(localhost, 0);
-
- int server_fd = CreateBoundUDPSocket(&server_addr);
- int client_fd = CreateUDPSocket(client_addr);
-
- ASSERT_NE(-1, server_fd);
- ASSERT_NE(-1, client_fd);
-
- {
- std::array<char, 512> write_buffer;
- for (size_t i = 0; i < write_buffer.size(); i++) {
- write_buffer[i] = static_cast<char>(i);
- }
- auto res = QuicSocketUtils::WritePacket(client_fd, write_buffer.data(),
- write_buffer.size(),
- QuicIpAddress(), server_addr);
- ASSERT_EQ(WRITE_STATUS_OK, res.status) << "Failed to write with error "
- << res.error_code;
- EXPECT_EQ(512, res.bytes_written);
- }
-
- fd_set read_fds;
- FD_ZERO(&read_fds);
- FD_SET(server_fd, &read_fds);
-
- timeval select_timeout;
- select_timeout.tv_sec = 5;
- select_timeout.tv_usec = 0;
-
- int select_rc =
- select(1 + server_fd, &read_fds, nullptr, nullptr, &select_timeout);
- EXPECT_EQ(select_rc, 1) << "server_fd didn't become read selectable: "
- << errno;
-
- {
- std::array<char, 1024> read_buffer;
- QuicIpAddress target_server_addr;
- auto walltimestamp = QuicWallTime::Zero();
- QuicSocketAddress remote_addr;
- int bytes_read = QuicSocketUtils::ReadPacket(
- server_fd, read_buffer.data(), read_buffer.size(), nullptr,
- &target_server_addr, &walltimestamp, &remote_addr);
- EXPECT_EQ(512, bytes_read);
- for (int i = 0; i < bytes_read; i++) {
- EXPECT_EQ(static_cast<char>(i), read_buffer[i]);
- }
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_client.cc b/chromium/net/tools/quic/quic_client.cc
deleted file mode 100644
index 49af6ae8a59..00000000000
--- a/chromium/net/tools/quic/quic_client.cc
+++ /dev/null
@@ -1,96 +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/tools/quic/quic_client.h"
-
-#include <errno.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "base/run_loop.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_data_reader.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-#include "net/tools/quic/quic_epoll_alarm_factory.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-
-#ifndef SO_RXQ_OVFL
-#define SO_RXQ_OVFL 40
-#endif
-
-// TODO(rtenneti): Add support for MMSG_MORE.
-#define MMSG_MORE 0
-using std::string;
-
-namespace net {
-
-QuicClient::QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicClient(
- server_address,
- server_id,
- supported_versions,
- QuicConfig(),
- epoll_server,
- QuicWrapUnique(new QuicClientEpollNetworkHelper(epoll_server, this)),
- std::move(proof_verifier)) {}
-
-QuicClient::QuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicClient(server_address,
- server_id,
- supported_versions,
- QuicConfig(),
- epoll_server,
- std::move(network_helper),
- std::move(proof_verifier)) {}
-
-QuicClient::QuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- EpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicSpdyClientBase(
- server_id,
- supported_versions,
- config,
- new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
- new QuicEpollAlarmFactory(epoll_server),
- std::move(network_helper),
- std::move(proof_verifier)) {
- set_server_address(server_address);
-}
-
-QuicClient::~QuicClient() = default;
-
-QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() {
- return static_cast<QuicClientEpollNetworkHelper*>(network_helper());
-}
-
-const QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() const {
- return static_cast<const QuicClientEpollNetworkHelper*>(network_helper());
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_client.h b/chromium/net/tools/quic/quic_client.h
deleted file mode 100644
index 031cdff92ea..00000000000
--- a/chromium/net/tools/quic/quic_client.h
+++ /dev/null
@@ -1,76 +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.
-//
-// A toy client, which connects to a specified port and sends QUIC
-// request to that endpoint.
-
-#ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_
-#define NET_TOOLS_QUIC_QUIC_CLIENT_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "base/command_line.h"
-#include "base/macros.h"
-#include "net/quic/core/quic_client_push_promise_index.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/core/quic_spdy_stream.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/quic_client_base.h"
-#include "net/tools/quic/quic_client_epoll_network_helper.h"
-#include "net/tools/quic/quic_packet_reader.h"
-#include "net/tools/quic/quic_process_packet_interface.h"
-#include "net/tools/quic/quic_spdy_client_base.h"
-#include "net/tools/quic/quic_spdy_client_session.h"
-
-namespace net {
-
-class QuicServerId;
-
-namespace test {
-class QuicClientPeer;
-} // namespace test
-
-class QuicClient : public QuicSpdyClientBase {
- public:
- // This will create its own QuicClientEpollNetworkHelper.
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier);
- // This will take ownership of a passed in network primitive.
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier);
- QuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- EpollServer* epoll_server,
- std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier);
-
- ~QuicClient() override;
-
- // Exposed for the quic client test.
- int GetLatestFD() const { return epoll_network_helper()->GetLatestFD(); }
-
- QuicClientEpollNetworkHelper* epoll_network_helper();
- const QuicClientEpollNetworkHelper* epoll_network_helper() const;
-
- private:
- friend class test::QuicClientPeer;
-
- DISALLOW_COPY_AND_ASSIGN(QuicClient);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_
diff --git a/chromium/net/tools/quic/quic_client_base.cc b/chromium/net/tools/quic/quic_client_base.cc
deleted file mode 100644
index c8fa05f4d48..00000000000
--- a/chromium/net/tools/quic/quic_client_base.cc
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (c) 2015 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/tools/quic/quic_client_base.h"
-
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/core/tls_client_handshaker.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-
-using base::StringToInt;
-using std::string;
-
-namespace net {
-
-QuicClientBase::NetworkHelper::~NetworkHelper() = default;
-
-QuicClientBase::QuicClientBase(
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<NetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : server_id_(server_id),
- initialized_(false),
- local_port_(0),
- config_(config),
- crypto_config_(std::move(proof_verifier),
- TlsClientHandshaker::CreateSslCtx()),
- helper_(helper),
- alarm_factory_(alarm_factory),
- supported_versions_(supported_versions),
- initial_max_packet_length_(0),
- num_stateless_rejects_received_(0),
- num_sent_client_hellos_(0),
- connection_error_(QUIC_NO_ERROR),
- connected_or_attempting_connect_(false),
- network_helper_(std::move(network_helper)) {}
-
-QuicClientBase::~QuicClientBase() = default;
-
-bool QuicClientBase::Initialize() {
- num_sent_client_hellos_ = 0;
- num_stateless_rejects_received_ = 0;
- connection_error_ = QUIC_NO_ERROR;
- connected_or_attempting_connect_ = false;
-
- // If an initial flow control window has not explicitly been set, then use the
- // same values that Chrome uses.
- const uint32_t kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
- const uint32_t kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
- if (config()->GetInitialStreamFlowControlWindowToSend() ==
- kMinimumFlowControlSendWindow) {
- config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize);
- }
- if (config()->GetInitialSessionFlowControlWindowToSend() ==
- kMinimumFlowControlSendWindow) {
- config()->SetInitialSessionFlowControlWindowToSend(
- kSessionMaxRecvWindowSize);
- }
-
- if (!network_helper_->CreateUDPSocketAndBind(server_address_,
- bind_to_address_, local_port_)) {
- return false;
- }
-
- initialized_ = true;
- return true;
-}
-
-bool QuicClientBase::Connect() {
- // Attempt multiple connects until the maximum number of client hellos have
- // been sent.
- while (!connected() &&
- GetNumSentClientHellos() <= QuicCryptoClientStream::kMaxClientHellos) {
- StartConnect();
- while (EncryptionBeingEstablished()) {
- WaitForEvents();
- }
- if (GetQuicReloadableFlag(enable_quic_stateless_reject_support) &&
- connected()) {
- // Resend any previously queued data.
- ResendSavedData();
- }
- if (session() != nullptr &&
- session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
- // We've successfully created a session but we're not connected, and there
- // is no stateless reject to recover from. Give up trying.
- break;
- }
- }
- if (!connected() &&
- GetNumSentClientHellos() > QuicCryptoClientStream::kMaxClientHellos &&
- session() != nullptr &&
- session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
- // The overall connection failed due too many stateless rejects.
- set_connection_error(QUIC_CRYPTO_TOO_MANY_REJECTS);
- }
- return session()->connection()->connected();
-}
-
-void QuicClientBase::StartConnect() {
- DCHECK(initialized_);
- DCHECK(!connected());
- QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
- if (connected_or_attempting_connect()) {
- // If the last error was not a stateless reject, then the queued up data
- // does not need to be resent.
- if (session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
- ClearDataToResend();
- }
- // Before we destroy the last session and create a new one, gather its stats
- // and update the stats for the overall connection.
- UpdateStats();
- }
-
- session_ = CreateQuicClientSession(new QuicConnection(
- GetNextConnectionId(), server_address(), helper(), alarm_factory(),
- writer,
- /* owns_writer= */ false, Perspective::IS_CLIENT, supported_versions()));
- if (initial_max_packet_length_ != 0) {
- session()->connection()->SetMaxPacketLength(initial_max_packet_length_);
- }
- // Reset |writer()| after |session()| so that the old writer outlives the old
- // session.
- set_writer(writer);
- InitializeSession();
- set_connected_or_attempting_connect(true);
-}
-
-void QuicClientBase::InitializeSession() {
- session()->Initialize();
-}
-
-void QuicClientBase::Disconnect() {
- DCHECK(initialized_);
-
- initialized_ = false;
- if (connected()) {
- session()->connection()->CloseConnection(
- QUIC_PEER_GOING_AWAY, "Client disconnecting",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }
-
- ClearDataToResend();
-
- network_helper_->CleanUpAllUDPSockets();
-}
-
-ProofVerifier* QuicClientBase::proof_verifier() const {
- return crypto_config_.proof_verifier();
-}
-
-bool QuicClientBase::EncryptionBeingEstablished() {
- return !session_->IsEncryptionEstablished() &&
- session_->connection()->connected();
-}
-
-bool QuicClientBase::WaitForEvents() {
- DCHECK(connected());
-
- network_helper_->RunEventLoop();
-
- DCHECK(session() != nullptr);
- if (!connected() &&
- session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
- DCHECK(GetQuicReloadableFlag(enable_quic_stateless_reject_support));
- QUIC_DLOG(INFO) << "Detected stateless reject while waiting for events. "
- << "Attempting to reconnect.";
- Connect();
- }
-
- return session()->num_active_requests() != 0;
-}
-
-bool QuicClientBase::MigrateSocket(const QuicIpAddress& new_host) {
- if (!connected()) {
- return false;
- }
-
- network_helper_->CleanUpAllUDPSockets();
-
- set_bind_to_address(new_host);
- if (!network_helper_->CreateUDPSocketAndBind(server_address_,
- bind_to_address_, local_port_)) {
- return false;
- }
-
- session()->connection()->SetSelfAddress(
- network_helper_->GetLatestClientAddress());
-
- QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
- set_writer(writer);
- session()->connection()->SetQuicPacketWriter(writer, false);
-
- return true;
-}
-
-QuicSession* QuicClientBase::session() {
- return session_.get();
-}
-
-QuicClientBase::NetworkHelper* QuicClientBase::network_helper() {
- return network_helper_.get();
-}
-
-const QuicClientBase::NetworkHelper* QuicClientBase::network_helper() const {
- return network_helper_.get();
-}
-
-void QuicClientBase::WaitForStreamToClose(QuicStreamId id) {
- DCHECK(connected());
-
- while (connected() && !session_->IsClosedStream(id)) {
- WaitForEvents();
- }
-}
-
-bool QuicClientBase::WaitForCryptoHandshakeConfirmed() {
- DCHECK(connected());
-
- while (connected() && !session_->IsCryptoHandshakeConfirmed()) {
- WaitForEvents();
- }
-
- // If the handshake fails due to a timeout, the connection will be closed.
- QUIC_LOG_IF(ERROR, !connected()) << "Handshake with server failed.";
- return connected();
-}
-
-bool QuicClientBase::connected() const {
- return session_.get() && session_->connection() &&
- session_->connection()->connected();
-}
-
-bool QuicClientBase::goaway_received() const {
- return session_ != nullptr && session_->goaway_received();
-}
-
-int QuicClientBase::GetNumSentClientHellos() {
- // If we are not actively attempting to connect, the session object
- // corresponds to the previous connection and should not be used.
- const int current_session_hellos = !connected_or_attempting_connect_
- ? 0
- : GetNumSentClientHellosFromSession();
- return num_sent_client_hellos_ + current_session_hellos;
-}
-
-void QuicClientBase::UpdateStats() {
- num_sent_client_hellos_ += GetNumSentClientHellosFromSession();
- if (session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
- ++num_stateless_rejects_received_;
- }
-}
-
-int QuicClientBase::GetNumReceivedServerConfigUpdates() {
- // If we are not actively attempting to connect, the session object
- // corresponds to the previous connection and should not be used.
- // We do not need to take stateless rejects into account, since we
- // don't expect any scup messages to be sent during a
- // statelessly-rejected connection.
- return !connected_or_attempting_connect_
- ? 0
- : GetNumReceivedServerConfigUpdatesFromSession();
-}
-
-QuicErrorCode QuicClientBase::connection_error() const {
- // Return the high-level error if there was one. Otherwise, return the
- // connection error from the last session.
- if (connection_error_ != QUIC_NO_ERROR) {
- return connection_error_;
- }
- if (session_ == nullptr) {
- return QUIC_NO_ERROR;
- }
- return session_->error();
-}
-
-QuicConnectionId QuicClientBase::GetNextConnectionId() {
- QuicConnectionId server_designated_id = GetNextServerDesignatedConnectionId();
- return server_designated_id ? server_designated_id
- : GenerateNewConnectionId();
-}
-
-QuicConnectionId QuicClientBase::GetNextServerDesignatedConnectionId() {
- QuicCryptoClientConfig::CachedState* cached =
- crypto_config_.LookupOrCreate(server_id_);
- // If the cached state indicates that we should use a server-designated
- // connection ID, then return that connection ID.
- CHECK(cached != nullptr) << "QuicClientCryptoConfig::LookupOrCreate returned "
- << "unexpected nullptr.";
- return cached->has_server_designated_connection_id()
- ? cached->GetNextServerDesignatedConnectionId()
- : 0;
-}
-
-QuicConnectionId QuicClientBase::GenerateNewConnectionId() {
- return QuicRandom::GetInstance()->RandUint64();
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_client_base.h b/chromium/net/tools/quic/quic_client_base.h
deleted file mode 100644
index f3d1d5aeee2..00000000000
--- a/chromium/net/tools/quic/quic_client_base.h
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright (c) 2015 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.
-//
-// A base class for the toy client, which connects to a specified port and sends
-// QUIC request to that endpoint.
-
-#ifndef NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_
-#define NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "net/quic/core/crypto/crypto_handshake.h"
-#include "net/quic/core/quic_client_push_promise_index.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/tools/quic/quic_spdy_client_session.h"
-#include "net/tools/quic/quic_spdy_client_stream.h"
-
-namespace net {
-
-class ProofVerifier;
-class QuicServerId;
-
-// QuicClientBase handles establishing a connection to the passed in
-// server id, including ensuring that it supports the passed in versions
-// and config.
-// Subclasses derived from this class are responsible for creating the
-// actual QuicSession instance, as well as defining functions that
-// create and run the underlying network transport.
-class QuicClientBase {
- public:
- // An interface to various network events that the QuicClient will need to
- // interact with.
- class NetworkHelper {
- public:
- virtual ~NetworkHelper();
-
- // Runs one iteration of the event loop.
- virtual void RunEventLoop() = 0;
-
- // Used during initialization: creates the UDP socket FD, sets socket
- // options, and binds the socket to our address.
- virtual bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
- QuicIpAddress bind_to_address,
- int bind_to_port) = 0;
-
- // Unregister and close all open UDP sockets.
- virtual void CleanUpAllUDPSockets() = 0;
-
- // If the client has at least one UDP socket, return address of the latest
- // created one. Otherwise, return an empty socket address.
- virtual QuicSocketAddress GetLatestClientAddress() const = 0;
-
- // Creates a packet writer to be used for the next connection.
- virtual QuicPacketWriter* CreateQuicPacketWriter() = 0;
- };
-
- QuicClientBase(const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<NetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier);
-
- virtual ~QuicClientBase();
-
- // Initializes the client to create a connection. Should be called exactly
- // once before calling StartConnect or Connect. Returns true if the
- // initialization succeeds, false otherwise.
- virtual bool Initialize();
-
- // "Connect" to the QUIC server, including performing synchronous crypto
- // handshake.
- bool Connect();
-
- // Start the crypto handshake. This can be done in place of the synchronous
- // Connect(), but callers are responsible for making sure the crypto handshake
- // completes.
- void StartConnect();
-
- // Calls session()->Initialize(). Subclasses may override this if any extra
- // initialization needs to be done. Subclasses should expect that session()
- // is non-null and valid.
- virtual void InitializeSession();
-
- // Disconnects from the QUIC server.
- void Disconnect();
-
- // Returns true if the crypto handshake has yet to establish encryption.
- // Returns false if encryption is active (even if the server hasn't confirmed
- // the handshake) or if the connection has been closed.
- bool EncryptionBeingEstablished();
-
- // Wait for events until the stream with the given ID is closed.
- void WaitForStreamToClose(QuicStreamId id);
-
- // Wait for events until the handshake is confirmed.
- // Returns true if the crypto handshake succeeds, false otherwise.
- bool WaitForCryptoHandshakeConfirmed() WARN_UNUSED_RESULT;
-
- // Wait up to 50ms, and handle any events which occur.
- // Returns true if there are any outstanding requests.
- bool WaitForEvents();
-
- // Migrate to a new socket during an active connection.
- bool MigrateSocket(const QuicIpAddress& new_host);
-
- QuicSession* session();
-
- bool connected() const;
- bool goaway_received() const;
-
- const QuicServerId& server_id() const { return server_id_; }
-
- // This should only be set before the initial Connect()
- void set_server_id(const QuicServerId& server_id) { server_id_ = server_id; }
-
- void SetUserAgentID(const std::string& user_agent_id) {
- crypto_config_.set_user_agent_id(user_agent_id);
- }
-
- // SetChannelIDSource sets a ChannelIDSource that will be called, when the
- // server supports channel IDs, to obtain a channel ID for signing a message
- // proving possession of the channel ID. This object takes ownership of
- // |source|.
- void SetChannelIDSource(ChannelIDSource* source) {
- crypto_config_.SetChannelIDSource(source);
- }
-
- // UseTokenBinding enables token binding negotiation in the client. This
- // should only be called before the initial Connect(). The client will still
- // need to check that token binding is negotiated with the server, and add
- // token binding headers to requests if so. server, and add token binding
- // headers to requests if so. The negotiated token binding parameters can be
- // found on the QuicCryptoNegotiatedParameters object in
- // token_binding_key_param.
- void UseTokenBinding() {
- crypto_config_.tb_key_params = QuicTagVector{kTB10};
- }
-
- const ParsedQuicVersionVector& supported_versions() const {
- return supported_versions_;
- }
-
- void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
- supported_versions_ = versions;
- }
-
- QuicConfig* config() { return &config_; }
-
- QuicCryptoClientConfig* crypto_config() { return &crypto_config_; }
-
- // Change the initial maximum packet size of the connection. Has to be called
- // before Connect()/StartConnect() in order to have any effect.
- void set_initial_max_packet_length(QuicByteCount initial_max_packet_length) {
- initial_max_packet_length_ = initial_max_packet_length;
- }
-
- int num_stateless_rejects_received() const {
- return num_stateless_rejects_received_;
- }
-
- // The number of client hellos sent, taking stateless rejects into
- // account. In the case of a stateless reject, the initial
- // connection object may be torn down and a new one created. The
- // user cannot rely upon the latest connection object to get the
- // total number of client hellos sent, and should use this function
- // instead.
- int GetNumSentClientHellos();
-
- // Gather the stats for the last session and update the stats for the overall
- // connection.
- void UpdateStats();
-
- // The number of server config updates received. We assume no
- // updates can be sent during a previously, statelessly rejected
- // connection, so only the latest session is taken into account.
- int GetNumReceivedServerConfigUpdates();
-
- // Returns any errors that occurred at the connection-level (as
- // opposed to the session-level). When a stateless reject occurs,
- // the error of the last session may not reflect the overall state
- // of the connection.
- QuicErrorCode connection_error() const;
- void set_connection_error(QuicErrorCode connection_error) {
- connection_error_ = connection_error;
- }
-
- bool connected_or_attempting_connect() const {
- return connected_or_attempting_connect_;
- }
- void set_connected_or_attempting_connect(
- bool connected_or_attempting_connect) {
- connected_or_attempting_connect_ = connected_or_attempting_connect;
- }
-
- QuicPacketWriter* writer() { return writer_.get(); }
- void set_writer(QuicPacketWriter* writer) {
- if (writer_.get() != writer) {
- writer_.reset(writer);
- }
- }
- void reset_writer() { writer_.reset(); }
-
- ProofVerifier* proof_verifier() const;
-
- void set_bind_to_address(QuicIpAddress address) {
- bind_to_address_ = address;
- }
-
- QuicIpAddress bind_to_address() const { return bind_to_address_; }
-
- void set_local_port(int local_port) { local_port_ = local_port; }
-
- int local_port() const { return local_port_; }
-
- const QuicSocketAddress& server_address() const { return server_address_; }
-
- void set_server_address(const QuicSocketAddress& server_address) {
- server_address_ = server_address;
- }
-
- QuicConnectionHelperInterface* helper() { return helper_.get(); }
-
- NetworkHelper* network_helper();
- const NetworkHelper* network_helper() const;
-
- bool initialized() const { return initialized_; }
-
- protected:
- // TODO(rch): Move GetNumSentClientHellosFromSession and
- // GetNumReceivedServerConfigUpdatesFromSession into a new/better
- // QuicSpdyClientSession class. The current inherits dependencies from
- // Spdy. When that happens this class and all its subclasses should
- // work with QuicSpdyClientSession instead of QuicSession.
- // That will obviate the need for the pure virtual functions below.
-
- // Extract the number of sent client hellos from the session.
- virtual int GetNumSentClientHellosFromSession() = 0;
-
- // The number of server config updates received. We assume no
- // updates can be sent during a previously, statelessly rejected
- // connection, so only the latest session is taken into account.
- virtual int GetNumReceivedServerConfigUpdatesFromSession() = 0;
-
- // If this client supports buffering data, resend it.
- virtual void ResendSavedData() = 0;
-
- // If this client supports buffering data, clear it.
- virtual void ClearDataToResend() = 0;
-
- // Takes ownership of |connection|. If you override this function,
- // you probably want to call ResetSession() in your destructor.
- // TODO(rch): Change the connection parameter to take in a
- // std::unique_ptr<QuicConnection> instead.
- virtual std::unique_ptr<QuicSession> CreateQuicClientSession(
- QuicConnection* connection) = 0;
-
- // Generates the next ConnectionId for |server_id_|. By default, if the
- // cached server config contains a server-designated ID, that ID will be
- // returned. Otherwise, the next random ID will be returned.
- QuicConnectionId GetNextConnectionId();
-
- // Returns the next server-designated ConnectionId from the cached config for
- // |server_id_|, if it exists. Otherwise, returns 0.
- QuicConnectionId GetNextServerDesignatedConnectionId();
-
- // Generates a new, random connection ID (as opposed to a server-designated
- // connection ID).
- virtual QuicConnectionId GenerateNewConnectionId();
-
- QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
-
- // Subclasses may need to explicitly clear the session on destruction
- // if they create it with objects that will be destroyed before this is.
- // You probably want to call this if you override CreateQuicSpdyClientSession.
- void ResetSession() { session_.reset(); }
-
- private:
- // |server_id_| is a tuple (hostname, port, is_https) of the server.
- QuicServerId server_id_;
-
- // Tracks if the client is initialized to connect.
- bool initialized_;
-
- // Address of the server.
- QuicSocketAddress server_address_;
-
- // If initialized, the address to bind to.
- QuicIpAddress bind_to_address_;
-
- // Local port to bind to. Initialize to 0.
- int local_port_;
-
- // config_ and crypto_config_ contain configuration and cached state about
- // servers.
- QuicConfig config_;
- QuicCryptoClientConfig crypto_config_;
-
- // Helper to be used by created connections. Must outlive |session_|.
- std::unique_ptr<QuicConnectionHelperInterface> helper_;
-
- // Alarm factory to be used by created connections. Must outlive |session_|.
- std::unique_ptr<QuicAlarmFactory> alarm_factory_;
-
- // Writer used to actually send packets to the wire. Must outlive |session_|.
- std::unique_ptr<QuicPacketWriter> writer_;
-
- // Session which manages streams.
- std::unique_ptr<QuicSession> session_;
-
- // This vector contains QUIC versions which we currently support.
- // This should be ordered such that the highest supported version is the first
- // element, with subsequent elements in descending order (versions can be
- // skipped as necessary). We will always pick supported_versions_[0] as the
- // initial version to use.
- ParsedQuicVersionVector supported_versions_;
-
- // The initial value of maximum packet size of the connection. If set to
- // zero, the default is used.
- QuicByteCount initial_max_packet_length_;
-
- // The number of stateless rejects received during the current/latest
- // connection.
- // TODO(jokulik): Consider some consistent naming scheme (or other) for member
- // variables that are kept per-request, per-connection, and over the client's
- // lifetime.
- int num_stateless_rejects_received_;
-
- // The number of hellos sent during the current/latest connection.
- int num_sent_client_hellos_;
-
- // Used to store any errors that occurred with the overall connection (as
- // opposed to that associated with the last session object).
- QuicErrorCode connection_error_;
-
- // True when the client is attempting to connect or re-connect the session (in
- // the case of a stateless reject). Set to false between a call to
- // Disconnect() and the subsequent call to StartConnect(). When
- // connected_or_attempting_connect_ is false, the session object corresponds
- // to the previous client-level connection.
- bool connected_or_attempting_connect_;
-
- // The network helper used to create sockets and manage the event loop.
- // Not owned by this class.
- std::unique_ptr<NetworkHelper> network_helper_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicClientBase);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_
diff --git a/chromium/net/tools/quic/quic_client_bin.cc b/chromium/net/tools/quic/quic_client_bin.cc
deleted file mode 100644
index 7a2249b80e9..00000000000
--- a/chromium/net/tools/quic/quic_client_bin.cc
+++ /dev/null
@@ -1,384 +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.
-
-// A binary wrapper for QuicClient.
-// Connects to a host using QUIC, sends a request to the provided URL, and
-// displays the response.
-//
-// Some usage examples:
-//
-// TODO(rtenneti): make --host optional by getting IP Address of URL's host.
-//
-// Get IP address of the www.google.com
-// IP=`dig www.google.com +short | head -1`
-//
-// Standard request/response:
-// quic_client http://www.google.com --host=${IP}
-// quic_client http://www.google.com --quiet --host=${IP}
-// quic_client https://www.google.com --port=443 --host=${IP}
-//
-// Use a specific version:
-// quic_client http://www.google.com --quic_version=23 --host=${IP}
-//
-// Send a POST instead of a GET:
-// quic_client http://www.google.com --body="this is a POST body" --host=${IP}
-//
-// Append additional headers to the request:
-// quic_client http://www.google.com --host=${IP}
-// --headers="Header-A: 1234; Header-B: 5678"
-//
-// Connect to a host different to the URL being requested:
-// Get IP address of the www.google.com
-// IP=`dig www.google.com +short | head -1`
-// quic_client mail.google.com --host=${IP}
-//
-// Try to connect to a host which does not speak QUIC:
-// Get IP address of the www.example.com
-// IP=`dig www.example.com +short | head -1`
-// quic_client http://www.example.com --host=${IP}
-
-#include <iostream>
-
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/message_loop/message_loop.h"
-#include "base/task_scheduler/task_scheduler.h"
-#include "net/base/net_errors.h"
-#include "net/base/privacy_mode.h"
-#include "net/cert/cert_verifier.h"
-#include "net/cert/ct_known_logs.h"
-#include "net/cert/ct_log_verifier.h"
-#include "net/cert/multi_log_ct_verifier.h"
-#include "net/http/transport_security_state.h"
-#include "net/quic/chromium/crypto/proof_verifier_chromium.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_str_cat.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/quic/platform/api/quic_url.h"
-#include "net/spdy/core/spdy_header_block.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/quic_client.h"
-#include "net/tools/quic/synchronous_host_resolver.h"
-
-using net::CertVerifier;
-using net::CTPolicyEnforcer;
-using net::CTVerifier;
-using net::MultiLogCTVerifier;
-using net::ProofVerifier;
-using net::ProofVerifierChromium;
-using net::QuicStringPiece;
-using net::QuicTextUtils;
-using net::QuicUrl;
-using net::SpdyHeaderBlock;
-using net::TransportSecurityState;
-using std::cout;
-using std::cerr;
-using std::endl;
-using std::string;
-
-// The IP or hostname the quic client will connect to.
-string FLAGS_host = "";
-// The port to connect to.
-int32_t FLAGS_port = 0;
-// If set, send a POST with this body.
-string FLAGS_body = "";
-// If set, contents are converted from hex to ascii, before sending as body of
-// a POST. e.g. --body_hex=\"68656c6c6f\"
-string FLAGS_body_hex = "";
-// A semicolon separated list of key:value pairs to add to request headers.
-string FLAGS_headers = "";
-// Set to true for a quieter output experience.
-bool FLAGS_quiet = false;
-// QUIC version to speak, e.g. 21. If not set, then all available versions are
-// offered in the handshake.
-int32_t FLAGS_quic_version = -1;
-// If true, a version mismatch in the handshake is not considered a failure.
-// Useful for probing a server to determine if it speaks any version of QUIC.
-bool FLAGS_version_mismatch_ok = false;
-// If true, an HTTP response code of 3xx is considered to be a successful
-// response, otherwise a failure.
-bool FLAGS_redirect_is_success = true;
-// Initial MTU of the connection.
-int32_t FLAGS_initial_mtu = 0;
-
-class FakeProofVerifier : public ProofVerifier {
- public:
- net::QuicAsyncStatus VerifyProof(
- const string& /*hostname*/,
- const uint16_t /*port*/,
- const string& /*server_config*/,
- net::QuicTransportVersion /*quic_version*/,
- QuicStringPiece /*chlo_hash*/,
- const std::vector<string>& /*certs*/,
- const string& /*cert_sct*/,
- const string& /*signature*/,
- const net::ProofVerifyContext* /*context*/,
- string* /*error_details*/,
- std::unique_ptr<net::ProofVerifyDetails>* /*details*/,
- std::unique_ptr<net::ProofVerifierCallback> /*callback*/) override {
- return net::QUIC_SUCCESS;
- }
-
- net::QuicAsyncStatus VerifyCertChain(
- const std::string& /*hostname*/,
- const std::vector<std::string>& /*certs*/,
- const net::ProofVerifyContext* /*verify_context*/,
- std::string* /*error_details*/,
- std::unique_ptr<net::ProofVerifyDetails>* /*verify_details*/,
- std::unique_ptr<net::ProofVerifierCallback> /*callback*/) override {
- return net::QUIC_SUCCESS;
- }
-};
-
-int main(int argc, char* argv[]) {
- base::TaskScheduler::CreateAndStartWithDefaultParams("quic_client");
- base::CommandLine::Init(argc, argv);
- base::CommandLine* line = base::CommandLine::ForCurrentProcess();
- const base::CommandLine::StringVector& urls = line->GetArgs();
-
- logging::LoggingSettings settings;
- settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
- CHECK(logging::InitLogging(settings));
-
- if (line->HasSwitch("h") || line->HasSwitch("help") || urls.empty()) {
- const char* help_str =
- "Usage: quic_client [options] <url>\n"
- "\n"
- "<url> with scheme must be provided (e.g. http://www.google.com)\n\n"
- "Options:\n"
- "-h, --help show this help message and exit\n"
- "--host=<host> specify the IP address of the hostname to "
- "connect to\n"
- "--port=<port> specify the port to connect to\n"
- "--body=<body> specify the body to post\n"
- "--body_hex=<body_hex> specify the body_hex to be printed out\n"
- "--headers=<headers> specify a semicolon separated list of "
- "key:value pairs to add to request headers\n"
- "--quiet specify for a quieter output experience\n"
- "--quic-version=<quic version> specify QUIC version to speak\n"
- "--version_mismatch_ok if specified a version mismatch in the "
- "handshake is not considered a failure\n"
- "--redirect_is_success if specified an HTTP response code of 3xx "
- "is considered to be a successful response, otherwise a failure\n"
- "--initial_mtu=<initial_mtu> specify the initial MTU of the connection"
- "\n"
- "--disable-certificate-verification do not verify certificates\n";
- cout << help_str;
- exit(0);
- }
- if (line->HasSwitch("host")) {
- FLAGS_host = line->GetSwitchValueASCII("host");
- }
- if (line->HasSwitch("port")) {
- if (!base::StringToInt(line->GetSwitchValueASCII("port"), &FLAGS_port)) {
- std::cerr << "--port must be an integer\n";
- return 1;
- }
- }
- if (line->HasSwitch("body")) {
- FLAGS_body = line->GetSwitchValueASCII("body");
- }
- if (line->HasSwitch("body_hex")) {
- FLAGS_body_hex = line->GetSwitchValueASCII("body_hex");
- }
- if (line->HasSwitch("headers")) {
- FLAGS_headers = line->GetSwitchValueASCII("headers");
- }
- if (line->HasSwitch("quiet")) {
- FLAGS_quiet = true;
- }
- if (line->HasSwitch("quic-version")) {
- int quic_version;
- if (base::StringToInt(line->GetSwitchValueASCII("quic-version"),
- &quic_version)) {
- FLAGS_quic_version = quic_version;
- }
- }
- if (line->HasSwitch("version_mismatch_ok")) {
- FLAGS_version_mismatch_ok = true;
- }
- if (line->HasSwitch("redirect_is_success")) {
- FLAGS_redirect_is_success = true;
- }
- if (line->HasSwitch("initial_mtu")) {
- if (!base::StringToInt(line->GetSwitchValueASCII("initial_mtu"),
- &FLAGS_initial_mtu)) {
- std::cerr << "--initial_mtu must be an integer\n";
- return 1;
- }
- }
-
- VLOG(1) << "server host: " << FLAGS_host << " port: " << FLAGS_port
- << " body: " << FLAGS_body << " headers: " << FLAGS_headers
- << " quiet: " << FLAGS_quiet
- << " quic-version: " << FLAGS_quic_version
- << " version_mismatch_ok: " << FLAGS_version_mismatch_ok
- << " redirect_is_success: " << FLAGS_redirect_is_success
- << " initial_mtu: " << FLAGS_initial_mtu;
-
- base::AtExitManager exit_manager;
- base::MessageLoopForIO message_loop;
-
- // Determine IP address to connect to from supplied hostname.
- net::QuicIpAddress ip_addr;
-
- QuicUrl url(urls[0], "https");
- string host = FLAGS_host;
- if (host.empty()) {
- host = url.host();
- }
- int port = FLAGS_port;
- if (port == 0) {
- port = url.port();
- }
- if (!ip_addr.FromString(host)) {
- net::AddressList addresses;
- int rv = net::SynchronousHostResolver::Resolve(host, &addresses);
- if (rv != net::OK) {
- LOG(ERROR) << "Unable to resolve '" << host
- << "' : " << net::ErrorToShortString(rv);
- return 1;
- }
- ip_addr =
- net::QuicIpAddress(net::QuicIpAddressImpl(addresses[0].address()));
- }
-
- string host_port = net::QuicStrCat(ip_addr.ToString(), ":", port);
- VLOG(1) << "Resolved " << host << " to " << host_port << endl;
-
- // Build the client, and try to connect.
- net::EpollServer epoll_server;
- net::QuicServerId server_id(url.host(), url.port(),
- net::PRIVACY_MODE_DISABLED);
- net::ParsedQuicVersionVector versions = net::AllSupportedVersions();
- if (FLAGS_quic_version != -1) {
- versions.clear();
- versions.push_back(net::ParsedQuicVersion(
- net::PROTOCOL_QUIC_CRYPTO,
- static_cast<net::QuicTransportVersion>(FLAGS_quic_version)));
- }
- // For secure QUIC we need to verify the cert chain.
- std::unique_ptr<CertVerifier> cert_verifier(CertVerifier::CreateDefault());
- std::unique_ptr<TransportSecurityState> transport_security_state(
- new TransportSecurityState);
- std::unique_ptr<MultiLogCTVerifier> ct_verifier(new MultiLogCTVerifier());
- ct_verifier->AddLogs(net::ct::CreateLogVerifiersForKnownLogs());
- std::unique_ptr<CTPolicyEnforcer> ct_policy_enforcer(new CTPolicyEnforcer());
- std::unique_ptr<ProofVerifier> proof_verifier;
- if (line->HasSwitch("disable-certificate-verification")) {
- proof_verifier = net::QuicMakeUnique<FakeProofVerifier>();
- } else {
- proof_verifier = net::QuicMakeUnique<ProofVerifierChromium>(
- cert_verifier.get(), ct_policy_enforcer.get(),
- transport_security_state.get(), ct_verifier.get());
- }
- net::QuicClient client(net::QuicSocketAddress(ip_addr, port), server_id,
- versions, &epoll_server, std::move(proof_verifier));
- client.set_initial_max_packet_length(
- FLAGS_initial_mtu != 0 ? FLAGS_initial_mtu : net::kDefaultMaxPacketSize);
- if (!client.Initialize()) {
- cerr << "Failed to initialize client." << endl;
- return 1;
- }
- if (!client.Connect()) {
- net::QuicErrorCode error = client.session()->error();
- if (FLAGS_version_mismatch_ok && error == net::QUIC_INVALID_VERSION) {
- cout << "Server talks QUIC, but none of the versions supported by "
- << "this client: " << ParsedQuicVersionVectorToString(versions)
- << endl;
- // Version mismatch is not deemed a failure.
- return 0;
- }
- cerr << "Failed to connect to " << host_port
- << ". Error: " << net::QuicErrorCodeToString(error) << endl;
- return 1;
- }
- cout << "Connected to " << host_port << endl;
-
- // Construct the string body from flags, if provided.
- string body = FLAGS_body;
- if (!FLAGS_body_hex.empty()) {
- DCHECK(FLAGS_body.empty()) << "Only set one of --body and --body_hex.";
- body = QuicTextUtils::HexDecode(FLAGS_body_hex);
- }
-
- // Construct a GET or POST request for supplied URL.
- SpdyHeaderBlock header_block;
- header_block[":method"] = body.empty() ? "GET" : "POST";
- header_block[":scheme"] = url.scheme();
- header_block[":authority"] = url.HostPort();
- header_block[":path"] = url.PathParamsQuery();
-
- // Append any additional headers supplied on the command line.
- for (QuicStringPiece sp : QuicTextUtils::Split(FLAGS_headers, ';')) {
- QuicTextUtils::RemoveLeadingAndTrailingWhitespace(&sp);
- if (sp.empty()) {
- continue;
- }
- std::vector<QuicStringPiece> kv = QuicTextUtils::Split(sp, ':');
- QuicTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[0]);
- QuicTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[1]);
- header_block[kv[0]] = kv[1];
- }
-
- // Make sure to store the response, for later output.
- client.set_store_response(true);
-
- // Send the request.
- client.SendRequestAndWaitForResponse(header_block, body, /*fin=*/true);
-
- // Print request and response details.
- if (!FLAGS_quiet) {
- cout << "Request:" << endl;
- cout << "headers:" << header_block.DebugString();
- if (!FLAGS_body_hex.empty()) {
- // Print the user provided hex, rather than binary body.
- cout << "body:\n"
- << QuicTextUtils::HexDump(QuicTextUtils::HexDecode(FLAGS_body_hex))
- << endl;
- } else {
- cout << "body: " << body << endl;
- }
- cout << endl;
-
- if (!client.preliminary_response_headers().empty()) {
- cout << "Preliminary response headers: "
- << client.preliminary_response_headers() << endl;
- cout << endl;
- }
-
- cout << "Response:" << endl;
- cout << "headers: " << client.latest_response_headers() << endl;
- string response_body = client.latest_response_body();
- if (!FLAGS_body_hex.empty()) {
- // Assume response is binary data.
- cout << "body:\n" << QuicTextUtils::HexDump(response_body) << endl;
- } else {
- cout << "body: " << response_body << endl;
- }
- cout << "trailers: " << client.latest_response_trailers() << endl;
- }
-
- size_t response_code = client.latest_response_code();
- if (response_code >= 200 && response_code < 300) {
- cout << "Request succeeded (" << response_code << ")." << endl;
- return 0;
- } else if (response_code >= 300 && response_code < 400) {
- if (FLAGS_redirect_is_success) {
- cout << "Request succeeded (redirect " << response_code << ")." << endl;
- return 0;
- } else {
- cout << "Request failed (redirect " << response_code << ")." << endl;
- return 1;
- }
- } else {
- cerr << "Request failed (" << response_code << ")." << endl;
- return 1;
- }
-}
diff --git a/chromium/net/tools/quic/quic_client_epoll_network_helper.cc b/chromium/net/tools/quic/quic_client_epoll_network_helper.cc
deleted file mode 100644
index fefaae4c654..00000000000
--- a/chromium/net/tools/quic/quic_client_epoll_network_helper.cc
+++ /dev/null
@@ -1,204 +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/tools/quic/quic_client_epoll_network_helper.h"
-
-#include <errno.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "base/run_loop.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_data_reader.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-#include "net/tools/quic/quic_epoll_alarm_factory.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-
-#ifndef SO_RXQ_OVFL
-#define SO_RXQ_OVFL 40
-#endif
-
-// TODO(rtenneti): Add support for MMSG_MORE.
-#define MMSG_MORE 0
-using std::string;
-
-namespace net {
-
-namespace {
-const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
-} // namespace
-
-QuicClientEpollNetworkHelper::QuicClientEpollNetworkHelper(
- EpollServer* epoll_server,
- QuicClientBase* client)
- : epoll_server_(epoll_server),
- packets_dropped_(0),
- overflow_supported_(false),
- packet_reader_(new QuicPacketReader()),
- client_(client),
- max_reads_per_epoll_loop_(std::numeric_limits<int>::max()) {}
-
-QuicClientEpollNetworkHelper::~QuicClientEpollNetworkHelper() {
- if (client_->connected()) {
- client_->session()->connection()->CloseConnection(
- QUIC_PEER_GOING_AWAY, "Client being torn down",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- }
-
- CleanUpAllUDPSockets();
-}
-
-bool QuicClientEpollNetworkHelper::CreateUDPSocketAndBind(
- QuicSocketAddress server_address,
- QuicIpAddress bind_to_address,
- int bind_to_port) {
- epoll_server_->set_timeout_in_us(50 * 1000);
-
- int fd = CreateUDPSocket(server_address, &overflow_supported_);
- if (fd < 0) {
- return false;
- }
-
- QuicSocketAddress client_address;
- if (bind_to_address.IsInitialized()) {
- client_address = QuicSocketAddress(bind_to_address, client_->local_port());
- } else if (server_address.host().address_family() == IpAddressFamily::IP_V4) {
- client_address = QuicSocketAddress(QuicIpAddress::Any4(), bind_to_port);
- } else {
- client_address = QuicSocketAddress(QuicIpAddress::Any6(), bind_to_port);
- }
-
- sockaddr_storage addr = client_address.generic_address();
- int rc = bind(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
- if (rc < 0) {
- QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
- return false;
- }
-
- if (client_address.FromSocket(fd) != 0) {
- QUIC_LOG(ERROR) << "Unable to get self address. Error: "
- << strerror(errno);
- }
-
- fd_address_map_[fd] = client_address;
-
- epoll_server_->RegisterFD(fd, this, kEpollFlags);
- return true;
-}
-
-void QuicClientEpollNetworkHelper::CleanUpUDPSocket(int fd) {
- CleanUpUDPSocketImpl(fd);
- fd_address_map_.erase(fd);
-}
-
-void QuicClientEpollNetworkHelper::CleanUpAllUDPSockets() {
- for (std::pair<int, QuicSocketAddress> fd_address : fd_address_map_) {
- CleanUpUDPSocketImpl(fd_address.first);
- }
- fd_address_map_.clear();
-}
-
-void QuicClientEpollNetworkHelper::CleanUpUDPSocketImpl(int fd) {
- if (fd > -1) {
- epoll_server_->UnregisterFD(fd);
- int rc = close(fd);
- DCHECK_EQ(0, rc);
- }
-}
-
-void QuicClientEpollNetworkHelper::RunEventLoop() {
- base::RunLoop().RunUntilIdle();
- epoll_server_->WaitForEventsAndExecuteCallbacks();
-}
-
-void QuicClientEpollNetworkHelper::OnRegistration(EpollServer* eps,
- int fd,
- int event_mask) {}
-void QuicClientEpollNetworkHelper::OnModification(int fd, int event_mask) {}
-void QuicClientEpollNetworkHelper::OnUnregistration(int fd, bool replaced) {}
-void QuicClientEpollNetworkHelper::OnShutdown(EpollServer* eps, int fd) {}
-
-void QuicClientEpollNetworkHelper::OnEvent(int fd, EpollEvent* event) {
- DCHECK_EQ(fd, GetLatestFD());
-
- if (event->in_events & EPOLLIN) {
- DVLOG(1) << "Read packets on EPOLLIN";
- int times_to_read = max_reads_per_epoll_loop_;
- bool more_to_read = true;
- while (client_->connected() && more_to_read && times_to_read > 0) {
- more_to_read = packet_reader_->ReadAndDispatchPackets(
- GetLatestFD(), GetLatestClientAddress().port(),
- *client_->helper()->GetClock(), this,
- overflow_supported_ ? &packets_dropped_ : nullptr);
- --times_to_read;
- }
- if (packets_dropped_ > 100) {
- QUIC_LOG_FIRST_N(ERROR, 50)
- << packets_dropped_
- << " packets droped in the socket receive buffer.";
- }
- if (client_->connected() && more_to_read) {
- event->out_ready_mask |= EPOLLIN;
- }
- }
- if (client_->connected() && (event->in_events & EPOLLOUT)) {
- client_->writer()->SetWritable();
- client_->session()->connection()->OnCanWrite();
- }
- if (event->in_events & EPOLLERR) {
- QUIC_DLOG(INFO) << "Epollerr";
- }
-}
-
-QuicPacketWriter* QuicClientEpollNetworkHelper::CreateQuicPacketWriter() {
- return new QuicDefaultPacketWriter(GetLatestFD());
-}
-
-void QuicClientEpollNetworkHelper::SetClientPort(int port) {
- fd_address_map_.back().second =
- QuicSocketAddress(GetLatestClientAddress().host(), port);
-}
-
-QuicSocketAddress QuicClientEpollNetworkHelper::GetLatestClientAddress() const {
- if (fd_address_map_.empty()) {
- return QuicSocketAddress();
- }
-
- return fd_address_map_.back().second;
-}
-
-int QuicClientEpollNetworkHelper::GetLatestFD() const {
- if (fd_address_map_.empty()) {
- return -1;
- }
-
- return fd_address_map_.back().first;
-}
-
-void QuicClientEpollNetworkHelper::ProcessPacket(
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) {
- client_->session()->ProcessUdpPacket(self_address, peer_address, packet);
-}
-
-int QuicClientEpollNetworkHelper::CreateUDPSocket(
- QuicSocketAddress server_address,
- bool* overflow_supported) {
- return QuicSocketUtils::CreateUDPSocket(
- server_address,
- /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer, overflow_supported);
-}
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_client_epoll_network_helper.h b/chromium/net/tools/quic/quic_client_epoll_network_helper.h
deleted file mode 100644
index a5117fd6a20..00000000000
--- a/chromium/net/tools/quic/quic_client_epoll_network_helper.h
+++ /dev/null
@@ -1,136 +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.
-//
-// An implementation of the QuicClientBase::NetworkHelper
-// that is based off the epoll server.
-
-#ifndef NET_TOOLS_QUIC_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
-#define NET_TOOLS_QUIC_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "base/command_line.h"
-#include "base/macros.h"
-#include "net/quic/core/quic_client_push_promise_index.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/core/quic_spdy_stream.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/quic_client_base.h"
-#include "net/tools/quic/quic_packet_reader.h"
-#include "net/tools/quic/quic_process_packet_interface.h"
-#include "net/tools/quic/quic_spdy_client_base.h"
-#include "net/tools/quic/quic_spdy_client_session.h"
-
-namespace net {
-
-namespace test {
-class QuicClientPeer;
-} // namespace test
-
-// An implementation of the QuicClientBase::NetworkHelper based off
-// the epoll server.
-class QuicClientEpollNetworkHelper : public QuicClientBase::NetworkHelper,
- public EpollCallbackInterface,
- public ProcessPacketInterface {
- public:
- // Create a quic client, which will have events managed by an externally owned
- // EpollServer.
- QuicClientEpollNetworkHelper(EpollServer* epoll_server,
- QuicClientBase* client);
-
- ~QuicClientEpollNetworkHelper() override;
-
- // From EpollCallbackInterface
- void OnRegistration(EpollServer* eps, int fd, int event_mask) override;
- void OnModification(int fd, int event_mask) override;
- void OnEvent(int fd, EpollEvent* event) override;
- // |fd_| can be unregistered without the client being disconnected. This
- // happens in b3m QuicProber where we unregister |fd_| to feed in events to
- // the client from the SelectServer.
- void OnUnregistration(int fd, bool replaced) override;
- void OnShutdown(EpollServer* eps, int fd) override;
-
- // From ProcessPacketInterface. This will be called for each received
- // packet.
- void ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) override;
-
- // From NetworkHelper.
- void RunEventLoop() override;
- bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
- QuicIpAddress bind_to_address,
- int bind_to_port) override;
- void CleanUpAllUDPSockets() override;
- QuicSocketAddress GetLatestClientAddress() const override;
- QuicPacketWriter* CreateQuicPacketWriter() override;
-
- // Accessors provided for convenience, not part of any interface.
-
- EpollServer* epoll_server() { return epoll_server_; }
-
- const QuicLinkedHashMap<int, QuicSocketAddress>& fd_address_map() const {
- return fd_address_map_;
- }
-
- // If the client has at least one UDP socket, return the latest created one.
- // Otherwise, return -1.
- int GetLatestFD() const;
-
- // Create socket for connection to |server_address| with default socket
- // options.
- // Return fd index.
- virtual int CreateUDPSocket(QuicSocketAddress server_address,
- bool* overflow_supported);
-
- QuicClientBase* client() { return client_; }
-
- void set_max_reads_per_epoll_loop(int num_reads) {
- max_reads_per_epoll_loop_ = num_reads;
- }
- // If |fd| is an open UDP socket, unregister and close it. Otherwise, do
- // nothing.
- void CleanUpUDPSocket(int fd);
-
- private:
- friend class test::QuicClientPeer;
-
- // Used for testing.
- void SetClientPort(int port);
-
- // Actually clean up |fd|.
- void CleanUpUDPSocketImpl(int fd);
-
- // Listens for events on the client socket.
- EpollServer* epoll_server_;
-
- // Map mapping created UDP sockets to their addresses. By using linked hash
- // map, the order of socket creation can be recorded.
- QuicLinkedHashMap<int, QuicSocketAddress> fd_address_map_;
-
- // If overflow_supported_ is true, this will be the number of packets dropped
- // during the lifetime of the server.
- QuicPacketCount packets_dropped_;
-
- // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
- // because the socket would otherwise overflow.
- bool overflow_supported_;
-
- // Point to a QuicPacketReader object on the heap. The reader allocates more
- // space than allowed on the stack.
- std::unique_ptr<QuicPacketReader> packet_reader_;
-
- QuicClientBase* client_;
-
- int max_reads_per_epoll_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicClientEpollNetworkHelper);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
diff --git a/chromium/net/tools/quic/quic_client_message_loop_network_helper.cc b/chromium/net/tools/quic/quic_client_message_loop_network_helper.cc
index b60ba04d575..0075af6293a 100644
--- a/chromium/net/tools/quic/quic_client_message_loop_network_helper.cc
+++ b/chromium/net/tools/quic/quic_client_message_loop_network_helper.cc
@@ -18,16 +18,16 @@
#include "net/quic/chromium/quic_chromium_connection_helper.h"
#include "net/quic/chromium/quic_chromium_packet_reader.h"
#include "net/quic/chromium/quic_chromium_packet_writer.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/socket/udp_client_socket.h"
-#include "net/spdy/chromium/spdy_http_utils.h"
-#include "net/spdy/core/spdy_header_block.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/third_party/quic/core/crypto/quic_random.h"
+#include "net/third_party/quic/core/quic_connection.h"
+#include "net/third_party/quic/core/quic_packets.h"
+#include "net/third_party/quic/core/quic_server_id.h"
+#include "net/third_party/quic/core/spdy_utils.h"
+#include "net/third_party/quic/platform/api/quic_flags.h"
+#include "net/third_party/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/spdy/core/spdy_header_block.h"
using std::string;
diff --git a/chromium/net/tools/quic/quic_client_message_loop_network_helper.h b/chromium/net/tools/quic/quic_client_message_loop_network_helper.h
index 891f19f78f6..2a75444145d 100644
--- a/chromium/net/tools/quic/quic_client_message_loop_network_helper.h
+++ b/chromium/net/tools/quic/quic_client_message_loop_network_helper.h
@@ -20,10 +20,10 @@
#include "net/http/http_response_headers.h"
#include "net/log/net_log.h"
#include "net/quic/chromium/quic_chromium_packet_reader.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/core/quic_spdy_stream.h"
-#include "net/quic/platform/impl/quic_chromium_clock.h"
-#include "net/tools/quic/quic_spdy_client_base.h"
+#include "net/third_party/quic/core/quic_config.h"
+#include "net/third_party/quic/core/quic_spdy_stream.h"
+#include "net/third_party/quic/platform/impl/quic_chromium_clock.h"
+#include "net/third_party/quic/tools/quic_spdy_client_base.h"
namespace net {
diff --git a/chromium/net/tools/quic/quic_client_test.cc b/chromium/net/tools/quic/quic_client_test.cc
deleted file mode 100644
index e9b7e5d6d21..00000000000
--- a/chromium/net/tools/quic/quic_client_test.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2014 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/tools/quic/quic_client.h"
-
-#include <dirent.h>
-#include <stdio.h>
-
-#include <memory>
-
-#include "base/files/file_enumerator.h"
-#include "base/files/file_util.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/platform/api/quic_test_loopback.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/test_tools/quic_client_peer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace test {
-namespace {
-
-const char* kPathToFds = "/proc/self/fd";
-
-// Counts the number of open sockets for the current process.
-size_t NumOpenSocketFDs() {
- base::FileEnumerator fd_entries(
- base::FilePath(kPathToFds), false,
- base::FileEnumerator::FILES | base::FileEnumerator::SHOW_SYM_LINKS);
-
- size_t socket_count = 0;
- for (base::FilePath entry = fd_entries.Next(); !entry.empty();
- entry = fd_entries.Next()) {
- base::FilePath fd_path;
- if (!base::ReadSymbolicLink(entry, &fd_path)) {
- continue;
- }
- if (QuicTextUtils::StartsWith(fd_path.value(), "socket:")) {
- socket_count++;
- }
- }
-
- return socket_count;
-}
-
-// Creates a new QuicClient and Initializes it. Caller is responsible for
-// deletion.
-QuicClient* CreateAndInitializeQuicClient(EpollServer* eps, uint16_t port) {
- QuicSocketAddress server_address(QuicSocketAddress(TestLoopback(), port));
- QuicServerId server_id("hostname", server_address.port(),
- PRIVACY_MODE_DISABLED);
- ParsedQuicVersionVector versions = AllSupportedVersions();
- QuicClient* client =
- new QuicClient(server_address, server_id, versions, eps,
- crypto_test_utils::ProofVerifierForTesting());
- EXPECT_TRUE(client->Initialize());
- return client;
-}
-
-class QuicClientTest : public QuicTest {};
-
-TEST_F(QuicClientTest, DoNotLeakSocketFDs) {
- // Make sure that the QuicClient doesn't leak socket FDs. Doing so could cause
- // port exhaustion in long running processes which repeatedly create clients.
-
- // Create a ProofVerifier before counting the number of open FDs to work
- // around some ASAN weirdness.
- crypto_test_utils::ProofVerifierForTesting().reset();
-
- // Record initial number of FDs, after creation of EpollServer.
- EpollServer eps;
- size_t number_of_open_fds = NumOpenSocketFDs();
-
- // Create a number of clients, initialize them, and verify this has resulted
- // in additional FDs being opened.
- const int kNumClients = 50;
- for (int i = 0; i < kNumClients; ++i) {
- std::unique_ptr<QuicClient> client(
- CreateAndInitializeQuicClient(&eps, net::test::kTestPort + i));
-
- // Initializing the client will create a new FD.
- EXPECT_LT(number_of_open_fds, NumOpenSocketFDs());
- }
-
- // The FDs created by the QuicClients should now be closed.
- EXPECT_EQ(number_of_open_fds, NumOpenSocketFDs());
-}
-
-TEST_F(QuicClientTest, CreateAndCleanUpUDPSockets) {
- // Create a ProofVerifier before counting the number of open FDs to work
- // around some ASAN weirdness.
- crypto_test_utils::ProofVerifierForTesting().reset();
-
- EpollServer eps;
- size_t number_of_open_fds = NumOpenSocketFDs();
-
- std::unique_ptr<QuicClient> client(
- CreateAndInitializeQuicClient(&eps, net::test::kTestPort));
- EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
- // Create more UDP sockets.
- EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
- EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
- EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
- EXPECT_EQ(number_of_open_fds + 3, NumOpenSocketFDs());
-
- // Clean up UDP sockets.
- QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
- EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
- QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
- EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_default_packet_writer.cc b/chromium/net/tools/quic/quic_default_packet_writer.cc
deleted file mode 100644
index 34c1bab4fb6..00000000000
--- a/chromium/net/tools/quic/quic_default_packet_writer.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 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/tools/quic/quic_default_packet_writer.h"
-
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-
-namespace net {
-
-QuicDefaultPacketWriter::QuicDefaultPacketWriter(int fd)
- : fd_(fd), write_blocked_(false) {}
-
-QuicDefaultPacketWriter::~QuicDefaultPacketWriter() = default;
-
-WriteResult QuicDefaultPacketWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- DCHECK(!write_blocked_);
- DCHECK(nullptr == options)
- << "QuicDefaultPacketWriter does not accept any options.";
- WriteResult result = QuicSocketUtils::WritePacket(fd_, buffer, buf_len,
- self_address, peer_address);
- if (result.status == WRITE_STATUS_BLOCKED) {
- write_blocked_ = true;
- }
- return result;
-}
-
-bool QuicDefaultPacketWriter::IsWriteBlockedDataBuffered() const {
- return false;
-}
-
-bool QuicDefaultPacketWriter::IsWriteBlocked() const {
- return write_blocked_;
-}
-
-void QuicDefaultPacketWriter::SetWritable() {
- write_blocked_ = false;
-}
-
-QuicByteCount QuicDefaultPacketWriter::GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const {
- return kMaxPacketSize;
-}
-
-void QuicDefaultPacketWriter::set_write_blocked(bool is_blocked) {
- write_blocked_ = is_blocked;
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_default_packet_writer.h b/chromium/net/tools/quic/quic_default_packet_writer.h
deleted file mode 100644
index 19d75d4b30d..00000000000
--- a/chromium/net/tools/quic/quic_default_packet_writer.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 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_TOOLS_QUIC_QUIC_DEFAULT_PACKET_WRITER_H_
-#define NET_TOOLS_QUIC_QUIC_DEFAULT_PACKET_WRITER_H_
-
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_packet_writer.h"
-#include "net/quic/platform/api/quic_export.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-
-namespace net {
-
-struct WriteResult;
-
-
-// Default packet writer which wraps QuicSocketUtils WritePacket.
-class QUIC_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
- public:
- explicit QuicDefaultPacketWriter(int fd);
- ~QuicDefaultPacketWriter() override;
-
- // QuicPacketWriter
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
- bool IsWriteBlockedDataBuffered() const override;
- bool IsWriteBlocked() const override;
- void SetWritable() override;
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override;
-
- void set_fd(int fd) { fd_ = fd; }
-
- protected:
- void set_write_blocked(bool is_blocked);
- int fd() { return fd_; }
-
- private:
- int fd_;
- bool write_blocked_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicDefaultPacketWriter);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_DEFAULT_PACKET_WRITER_H_
diff --git a/chromium/net/tools/quic/quic_dispatcher.cc b/chromium/net/tools/quic/quic_dispatcher.cc
deleted file mode 100644
index 591c45869a7..00000000000
--- a/chromium/net/tools/quic/quic_dispatcher.cc
+++ /dev/null
@@ -1,1107 +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/tools/quic/quic_dispatcher.h"
-
-#include <utility>
-
-#include "base/macros.h"
-#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_flag_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_stack_trace.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/tools/quic/chlo_extractor.h"
-#include "net/tools/quic/quic_per_connection_packet_writer.h"
-#include "net/tools/quic/quic_simple_server_session.h"
-#include "net/tools/quic/quic_time_wait_list_manager.h"
-#include "net/tools/quic/stateless_rejector.h"
-
-
-namespace net {
-
-typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket;
-typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList;
-typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult;
-
-namespace {
-
-// An alarm that informs the QuicDispatcher to delete old sessions.
-class DeleteSessionsAlarm : public QuicAlarm::Delegate {
- public:
- explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
- : dispatcher_(dispatcher) {}
-
- void OnAlarm() override { dispatcher_->DeleteSessions(); }
-
- private:
- // Not owned.
- QuicDispatcher* dispatcher_;
-
- DISALLOW_COPY_AND_ASSIGN(DeleteSessionsAlarm);
-};
-
-// Collects packets serialized by a QuicPacketCreator in order
-// to be handed off to the time wait list manager.
-class PacketCollector : public QuicPacketCreator::DelegateInterface,
- public QuicStreamFrameDataProducer {
- public:
- explicit PacketCollector(QuicBufferAllocator* allocator)
- : send_buffer_(allocator) {}
- ~PacketCollector() override = default;
-
- // QuicPacketCreator::DelegateInterface methods:
- void OnSerializedPacket(SerializedPacket* serialized_packet) override {
- // Make a copy of the serialized packet to send later.
- packets_.emplace_back(
- new QuicEncryptedPacket(CopyBuffer(*serialized_packet),
- serialized_packet->encrypted_length, true));
- serialized_packet->encrypted_buffer = nullptr;
- DeleteFrames(&(serialized_packet->retransmittable_frames));
- serialized_packet->retransmittable_frames.clear();
- }
-
- void OnUnrecoverableError(QuicErrorCode error,
- const QuicString& error_details,
- ConnectionCloseSource source) override {}
-
- void SaveStatelessRejectFrameData(QuicStringPiece reject) {
- struct iovec iovec;
- iovec.iov_base = const_cast<char*>(reject.data());
- iovec.iov_len = reject.length();
- send_buffer_.SaveStreamData(&iovec, 1, 0, iovec.iov_len);
- }
-
- // QuicStreamFrameDataProducer
- bool WriteStreamData(QuicStreamId id,
- QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) override {
- DCHECK_EQ(kCryptoStreamId, id);
- return send_buffer_.WriteStreamData(offset, data_length, writer);
- }
-
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
- return &packets_;
- }
-
- private:
- std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
- // This is only needed until the packets are encrypted. Once packets are
- // encrypted, the stream data is no longer required.
- QuicStreamSendBuffer send_buffer_;
-};
-
-// Helper for statelessly closing connections by generating the
-// correct termination packets and adding the connection to the time wait
-// list manager.
-class StatelessConnectionTerminator {
- public:
- StatelessConnectionTerminator(QuicConnectionId connection_id,
- QuicFramer* framer,
- QuicConnectionHelperInterface* helper,
- QuicTimeWaitListManager* time_wait_list_manager)
- : connection_id_(connection_id),
- framer_(framer),
- collector_(helper->GetStreamSendBufferAllocator()),
- creator_(connection_id, framer, &collector_),
- time_wait_list_manager_(time_wait_list_manager) {
- framer_->set_data_producer(&collector_);
- }
-
- ~StatelessConnectionTerminator() {
- // Clear framer's producer.
- framer_->set_data_producer(nullptr);
- }
-
- // Generates a packet containing a CONNECTION_CLOSE frame specifying
- // |error_code| and |error_details| and add the connection to time wait.
- void CloseConnection(QuicErrorCode error_code,
- const std::string& error_details) {
- QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame;
- frame->error_code = error_code;
- frame->error_details = error_details;
- if (!creator_.AddSavedFrame(QuicFrame(frame))) {
- QUIC_BUG << "Unable to add frame to an empty packet";
- delete frame;
- return;
- }
- creator_.Flush();
- DCHECK_EQ(1u, collector_.packets()->size());
- time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id_, framer_->version(), framer_->last_packet_is_ietf_quic(),
- /*connection_rejected_statelessly=*/false, collector_.packets());
- }
-
- // Generates a series of termination packets containing the crypto handshake
- // message |reject|. Adds the connection to time wait list with the
- // generated packets.
- void RejectConnection(QuicStringPiece reject) {
- QuicStreamOffset offset = 0;
- collector_.SaveStatelessRejectFrameData(reject);
- while (offset < reject.length()) {
- QuicFrame frame;
- if (!creator_.ConsumeData(kCryptoStreamId, reject.length(), offset,
- offset,
- /*fin=*/false,
- /*needs_full_padding=*/true, &frame)) {
- QUIC_BUG << "Unable to consume data into an empty packet.";
- return;
- }
- offset += frame.stream_frame->data_length;
- if (offset < reject.length()) {
- DCHECK(!creator_.HasRoomForStreamFrame(kCryptoStreamId, offset));
- }
- creator_.Flush();
- }
- time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id_, framer_->version(), framer_->last_packet_is_ietf_quic(),
- /*connection_rejected_statelessly=*/true, collector_.packets());
- DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id_));
- }
-
- private:
- QuicConnectionId connection_id_;
- QuicFramer* framer_; // Unowned.
- // Set as the visitor of |creator_| to collect any generated packets.
- PacketCollector collector_;
- QuicPacketCreator creator_;
- QuicTimeWaitListManager* time_wait_list_manager_;
-};
-
-// Class which extracts the ALPN from a CHLO packet.
-class ChloAlpnExtractor : public ChloExtractor::Delegate {
- public:
- void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
- const CryptoHandshakeMessage& chlo) override {
- QuicStringPiece alpn_value;
- if (chlo.GetStringPiece(kALPN, &alpn_value)) {
- alpn_ = QuicString(alpn_value);
- }
- }
-
- QuicString&& ConsumeAlpn() { return std::move(alpn_); }
-
- private:
- QuicString alpn_;
-};
-
-// Class which sits between the ChloExtractor and the StatelessRejector
-// to give the QuicDispatcher a chance to apply policy checks to the CHLO.
-class ChloValidator : public ChloAlpnExtractor {
- public:
- ChloValidator(QuicCryptoServerStream::Helper* helper,
- QuicSocketAddress self_address,
- StatelessRejector* rejector)
- : helper_(helper),
- self_address_(self_address),
- rejector_(rejector),
- can_accept_(false),
- error_details_("CHLO not processed") {}
-
- // ChloExtractor::Delegate implementation.
- void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
- const CryptoHandshakeMessage& chlo) override {
- // Extract the ALPN
- ChloAlpnExtractor::OnChlo(version, connection_id, chlo);
- if (helper_->CanAcceptClientHello(chlo, self_address_, &error_details_)) {
- can_accept_ = true;
- rejector_->OnChlo(version, connection_id,
- helper_->GenerateConnectionIdForReject(connection_id),
- chlo);
- }
- }
-
- bool can_accept() const { return can_accept_; }
-
- const QuicString& error_details() const { return error_details_; }
-
- private:
- QuicCryptoServerStream::Helper* helper_; // Unowned.
- QuicSocketAddress self_address_;
- StatelessRejector* rejector_; // Unowned.
- bool can_accept_;
- QuicString error_details_;
-};
-
-} // namespace
-
-QuicDispatcher::QuicDispatcher(
- const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory)
- : config_(config),
- crypto_config_(crypto_config),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- helper_(std::move(helper)),
- session_helper_(std::move(session_helper)),
- alarm_factory_(std::move(alarm_factory)),
- delete_sessions_alarm_(
- alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))),
- buffered_packets_(this, helper_->GetClock(), alarm_factory_.get()),
- current_packet_(nullptr),
- version_manager_(version_manager),
- framer_(GetSupportedVersions(),
- /*unused*/ QuicTime::Zero(),
- Perspective::IS_SERVER),
- last_error_(QUIC_NO_ERROR),
- new_sessions_allowed_per_event_loop_(0u),
- accept_new_connections_(true) {
- framer_.set_visitor(this);
-}
-
-QuicDispatcher::~QuicDispatcher() {
- session_map_.clear();
- closed_session_list_.clear();
-}
-
-void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) {
- DCHECK(writer_ == nullptr);
- writer_.reset(writer);
- time_wait_list_manager_.reset(CreateQuicTimeWaitListManager());
-}
-
-void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) {
- current_self_address_ = self_address;
- current_peer_address_ = peer_address;
- // GetClientAddress must be called after current_peer_address_ is set.
- current_client_address_ = GetClientAddress();
- current_packet_ = &packet;
- // ProcessPacket will cause the packet to be dispatched in
- // OnUnauthenticatedPublicHeader, or sent to the time wait list manager
- // in OnUnauthenticatedHeader.
- framer_.ProcessPacket(packet);
- // TODO(rjshade): Return a status describing if/why a packet was dropped,
- // and log somehow. Maybe expose as a varz.
- // TODO(wub): Consider invalidate the current_* variables so processing of the
- // next packet does not use them incorrectly.
-}
-
-bool QuicDispatcher::OnUnauthenticatedPublicHeader(
- const QuicPacketHeader& header) {
- current_connection_id_ = header.connection_id;
-
- // Port zero is only allowed for unidirectional UDP, so is disallowed by QUIC.
- // Given that we can't even send a reply rejecting the packet, just drop the
- // packet.
- if (current_peer_address_.port() == 0) {
- return false;
- }
-
- // Stopgap test: The code does not construct full-length connection IDs
- // correctly from truncated connection ID fields. Prevent this from causing
- // the connection ID lookup to error by dropping any packet with a short
- // connection ID.
- if (header.connection_id_length != PACKET_8BYTE_CONNECTION_ID) {
- return false;
- }
-
- // Packets with connection IDs for active connections are processed
- // immediately.
- QuicConnectionId connection_id = header.connection_id;
- SessionMap::iterator it = session_map_.find(connection_id);
- if (it != session_map_.end()) {
- DCHECK(!buffered_packets_.HasBufferedPackets(connection_id));
- it->second->ProcessUdpPacket(current_self_address_, current_peer_address_,
- *current_packet_);
- return false;
- }
-
- if (buffered_packets_.HasChloForConnection(connection_id)) {
- BufferEarlyPacket(connection_id, framer_.last_packet_is_ietf_quic());
- return false;
- }
-
- // Check if we are buffering packets for this connection ID
- if (temporarily_buffered_connections_.find(connection_id) !=
- temporarily_buffered_connections_.end()) {
- // This packet was received while the a CHLO for the same connection ID was
- // being processed. Buffer it.
- BufferEarlyPacket(connection_id, framer_.last_packet_is_ietf_quic());
- return false;
- }
-
- if (!OnUnauthenticatedUnknownPublicHeader(header)) {
- return false;
- }
-
- // If the packet is a public reset for a connection ID that is not active,
- // there is nothing we must do or can do.
- if (header.reset_flag) {
- return false;
- }
-
- if (time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) {
- // Set the framer's version based on the recorded version for this
- // connection and continue processing for non-public-reset packets.
- return HandlePacketForTimeWait(header);
- }
-
- // The packet has an unknown connection ID.
-
- // Unless the packet provides a version, assume that we can continue
- // processing using our preferred version.
- ParsedQuicVersion version = GetSupportedVersions().front();
- if (header.version_flag) {
- ParsedQuicVersion packet_version = header.version;
- if (framer_.supported_versions() != GetSupportedVersions()) {
- // Reset framer's version if version flags change in flight.
- framer_.SetSupportedVersions(GetSupportedVersions());
- }
- if (!framer_.IsSupportedVersion(packet_version)) {
- if (ShouldCreateSessionForUnknownVersion(framer_.last_version_label())) {
- return true;
- }
- // Since the version is not supported, send a version negotiation
- // packet and stop processing the current packet.
- time_wait_list_manager()->SendVersionNegotiationPacket(
- connection_id, framer_.last_packet_is_ietf_quic(),
- GetSupportedVersions(), current_self_address_, current_peer_address_);
- return false;
- }
- version = packet_version;
- }
- // Set the framer's version and continue processing.
- framer_.set_version(version);
- return true;
-}
-
-bool QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
- QuicConnectionId connection_id = header.connection_id;
-
- if (time_wait_list_manager_->IsConnectionIdInTimeWait(header.connection_id)) {
- // This connection ID is already in time-wait state.
- time_wait_list_manager_->ProcessPacket(
- current_self_address_, current_peer_address_, header.connection_id);
- return false;
- }
-
- // Packet's connection ID is unknown. Apply the validity checks.
- QuicPacketFate fate = ValidityChecks(header);
- if (fate == kFateProcess) {
- // Execute stateless rejection logic to determine the packet fate, then
- // invoke ProcessUnauthenticatedHeaderFate.
- MaybeRejectStatelessly(connection_id, header.version);
- } else {
- // If the fate is already known, process it without executing stateless
- // rejection logic.
- ProcessUnauthenticatedHeaderFate(fate, connection_id);
- }
-
- return false;
-}
-
-void QuicDispatcher::ProcessUnauthenticatedHeaderFate(
- QuicPacketFate fate,
- QuicConnectionId connection_id) {
- switch (fate) {
- case kFateProcess: {
- ProcessChlo();
- break;
- }
- case kFateTimeWait:
- // MaybeRejectStatelessly or OnExpiredPackets might have already added the
- // connection to time wait, in which case it should not be added again.
- if (!GetQuicReloadableFlag(quic_use_cheap_stateless_rejects) ||
- !time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) {
- // Add this connection_id to the time-wait state, to safely reject
- // future packets.
- QUIC_DLOG(INFO) << "Adding connection ID " << connection_id
- << "to time-wait list.";
- time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id, framer_.version(),
- framer_.last_packet_is_ietf_quic(),
- /*connection_rejected_statelessly=*/false, nullptr);
- }
- DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
- time_wait_list_manager_->ProcessPacket(
- current_self_address_, current_peer_address_, connection_id);
-
- // Any packets which were buffered while the stateless rejector logic was
- // running should be discarded. Do not inform the time wait list manager,
- // which should already have a made a decision about sending a reject
- // based on the CHLO alone.
- buffered_packets_.DiscardPackets(connection_id);
- break;
- case kFateBuffer:
- // This packet is a non-CHLO packet which has arrived before the
- // corresponding CHLO, *or* this packet was received while the
- // corresponding CHLO was being processed. Buffer it.
- BufferEarlyPacket(connection_id, framer_.last_packet_is_ietf_quic());
- break;
- case kFateDrop:
- // Do nothing with the packet.
- break;
- }
-}
-
-QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
- const QuicPacketHeader& header) {
- // To have all the checks work properly without tears, insert any new check
- // into the framework of this method in the section for checks that return the
- // check's fate value. The sections for checks must be ordered with the
- // highest priority fate first.
-
- // Checks that return kFateDrop.
-
- // Checks that return kFateTimeWait.
-
- // All packets within a connection sent by a client before receiving a
- // response from the server are required to have the version negotiation flag
- // set. Since this may be a client continuing a connection we lost track of
- // via server restart, send a rejection to fast-fail the connection.
- if (!header.version_flag) {
- QUIC_DLOG(INFO)
- << "Packet without version arrived for unknown connection ID "
- << header.connection_id;
- return kFateTimeWait;
- }
-
- // initial packet number of 0 is always invalid.
- const int kInvalidPacketNumber = 0;
- if (header.packet_number == kInvalidPacketNumber) {
- return kFateTimeWait;
- }
- if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
- QUIC_FLAG_COUNT_N(quic_restart_flag_quic_enable_accept_random_ipn, 1, 2);
- // Accepting Initial Packet Numbers in 1...((2^31)-1) range... check
- // maximum accordingly.
- if (header.packet_number > kMaxRandomInitialPacketNumber) {
- return kFateTimeWait;
- }
- } else {
- // Count those that would have been accepted if FLAGS..random_ipn
- // were true -- to detect/diagnose potential issues prior to
- // enabling the flag.
- if ((header.packet_number > kMaxReasonableInitialPacketNumber) &&
- (header.packet_number <= kMaxRandomInitialPacketNumber)) {
- QUIC_CODE_COUNT_N(had_possibly_random_ipn, 1, 2);
- }
- // Check that the sequence number is within the range that the client is
- // expected to send before receiving a response from the server.
- if (header.packet_number > kMaxReasonableInitialPacketNumber) {
- return kFateTimeWait;
- }
- }
- return kFateProcess;
-}
-
-void QuicDispatcher::CleanUpSession(SessionMap::iterator it,
- QuicConnection* connection,
- bool should_close_statelessly) {
- write_blocked_list_.erase(connection);
- if (should_close_statelessly) {
- DCHECK(connection->termination_packets() != nullptr &&
- !connection->termination_packets()->empty());
- }
- time_wait_list_manager_->AddConnectionIdToTimeWait(
- it->first, connection->version(), false, should_close_statelessly,
- connection->termination_packets());
- session_map_.erase(it);
-}
-
-void QuicDispatcher::StopAcceptingNewConnections() {
- accept_new_connections_ = false;
-}
-
-bool QuicDispatcher::ShouldAddToBlockedList() {
- return writer_->IsWriteBlocked();
-}
-
-void QuicDispatcher::DeleteSessions() {
- closed_session_list_.clear();
-}
-
-void QuicDispatcher::OnCanWrite() {
- // The socket is now writable.
- writer_->SetWritable();
-
- // Give all the blocked writers one chance to write, until we're blocked again
- // or there's no work left.
- while (!write_blocked_list_.empty() && !writer_->IsWriteBlocked()) {
- QuicBlockedWriterInterface* blocked_writer =
- write_blocked_list_.begin()->first;
- write_blocked_list_.erase(write_blocked_list_.begin());
- blocked_writer->OnBlockedWriterCanWrite();
- }
-}
-
-bool QuicDispatcher::HasPendingWrites() const {
- return !write_blocked_list_.empty();
-}
-
-void QuicDispatcher::Shutdown() {
- while (!session_map_.empty()) {
- QuicSession* session = session_map_.begin()->second.get();
- session->connection()->CloseConnection(
- QUIC_PEER_GOING_AWAY, "Server shutdown imminent",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- // Validate that the session removes itself from the session map on close.
- DCHECK(session_map_.empty() ||
- session_map_.begin()->second.get() != session);
- }
- DeleteSessions();
-}
-
-void QuicDispatcher::OnConnectionClosed(QuicConnectionId connection_id,
- QuicErrorCode error,
- const QuicString& error_details) {
- SessionMap::iterator it = session_map_.find(connection_id);
- if (it == session_map_.end()) {
- QUIC_BUG << "ConnectionId " << connection_id
- << " does not exist in the session map. Error: "
- << QuicErrorCodeToString(error);
- QUIC_BUG << QuicStackTrace();
- return;
- }
-
- QUIC_DLOG_IF(INFO, error != QUIC_NO_ERROR)
- << "Closing connection (" << connection_id
- << ") due to error: " << QuicErrorCodeToString(error)
- << ", with details: " << error_details;
-
- QuicConnection* connection = it->second->connection();
- if (ShouldDestroySessionAsynchronously()) {
- // Set up alarm to fire immediately to bring destruction of this session
- // out of current call stack.
- if (closed_session_list_.empty()) {
- delete_sessions_alarm_->Update(helper()->GetClock()->ApproximateNow(),
- QuicTime::Delta::Zero());
- }
- closed_session_list_.push_back(std::move(it->second));
- }
- const bool should_close_statelessly =
- (error == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT);
- CleanUpSession(it, connection, should_close_statelessly);
-}
-
-void QuicDispatcher::OnWriteBlocked(
- QuicBlockedWriterInterface* blocked_writer) {
- if (!ShouldAddToBlockedList()) {
- QUIC_BUG
- << "Tried to add writer into blocked list when it shouldn't be added";
- // Return without adding the connection to the blocked list, to avoid
- // infinite loops in OnCanWrite.
- return;
- }
- write_blocked_list_.insert(std::make_pair(blocked_writer, true));
-}
-
-void QuicDispatcher::OnRstStreamReceived(const QuicRstStreamFrame& frame) {}
-
-void QuicDispatcher::OnConnectionAddedToTimeWaitList(
- QuicConnectionId connection_id) {
- QUIC_DLOG(INFO) << "Connection " << connection_id
- << " added to time wait list.";
-}
-
-void QuicDispatcher::OnPacket() {}
-
-void QuicDispatcher::OnError(QuicFramer* framer) {
- QuicErrorCode error = framer->error();
- SetLastError(error);
- QUIC_DLOG(INFO) << QuicErrorCodeToString(error);
-}
-
-bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(
- QuicVersionLabel /*version_label*/) {
- return false;
-}
-
-bool QuicDispatcher::OnProtocolVersionMismatch(
- ParsedQuicVersion /*received_version*/) {
- QUIC_BUG_IF(
- !time_wait_list_manager_->IsConnectionIdInTimeWait(
- current_connection_id_) &&
- !ShouldCreateSessionForUnknownVersion(framer_.last_version_label()))
- << "Unexpected version mismatch: "
- << QuicVersionLabelToString(framer_.last_version_label());
-
- // Keep processing after protocol mismatch - this will be dealt with by the
- // time wait list or connection that we will create.
- return true;
-}
-
-void QuicDispatcher::OnPublicResetPacket(
- const QuicPublicResetPacket& /*packet*/) {
- DCHECK(false);
-}
-
-void QuicDispatcher::OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& /*packet*/) {
- DCHECK(false);
-}
-
-void QuicDispatcher::OnDecryptedPacket(EncryptionLevel level) {
- DCHECK(false);
-}
-
-bool QuicDispatcher::OnPacketHeader(const QuicPacketHeader& /*header*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnStreamFrame(const QuicStreamFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnAckFrame(const QuicAckFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
- QuicTime::Delta /*ack_delay_time*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnAckRange(QuicPacketNumber /*start*/,
- QuicPacketNumber /*end*/,
- bool /*last_range*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnPingFrame(const QuicPingFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnConnectionCloseFrame(
- const QuicConnectionCloseFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnWindowUpdateFrame(
- const QuicWindowUpdateFrame& /*frame*/) {
- DCHECK(false);
- return false;
-}
-
-bool QuicDispatcher::OnBlockedFrame(const QuicBlockedFrame& frame) {
- DCHECK(false);
- return false;
-}
-
-void QuicDispatcher::OnPacketComplete() {
- DCHECK(false);
-}
-
-bool QuicDispatcher::IsValidStatelessResetToken(uint128 token) const {
- DCHECK(false);
- return false;
-}
-
-void QuicDispatcher::OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) {
- DCHECK(false);
-}
-
-void QuicDispatcher::OnExpiredPackets(
- QuicConnectionId connection_id,
- BufferedPacketList early_arrived_packets) {
- time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id, framer_.version(), early_arrived_packets.ietf_quic, false,
- nullptr);
-}
-
-void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) {
- // Reset the counter before starting creating connections.
- new_sessions_allowed_per_event_loop_ = max_connections_to_create;
- for (; new_sessions_allowed_per_event_loop_ > 0;
- --new_sessions_allowed_per_event_loop_) {
- QuicConnectionId connection_id;
- BufferedPacketList packet_list =
- buffered_packets_.DeliverPacketsForNextConnection(&connection_id);
- const std::list<BufferedPacket>& packets = packet_list.buffered_packets;
- if (packets.empty()) {
- return;
- }
- QuicSession* session = CreateQuicSession(
- connection_id, packets.front().client_address, packet_list.alpn);
- QUIC_DLOG(INFO) << "Created new session for " << connection_id;
- session_map_.insert(std::make_pair(connection_id, QuicWrapUnique(session)));
- DeliverPacketsToSession(packets, session);
- }
-}
-
-bool QuicDispatcher::HasChlosBuffered() const {
- return buffered_packets_.HasChlosBuffered();
-}
-
-bool QuicDispatcher::ShouldCreateOrBufferPacketForConnection(
- QuicConnectionId connection_id) {
- VLOG(1) << "Received packet from new connection " << connection_id;
- return true;
-}
-
-// Return true if there is any packet buffered in the store.
-bool QuicDispatcher::HasBufferedPackets(QuicConnectionId connection_id) {
- return buffered_packets_.HasBufferedPackets(connection_id);
-}
-
-void QuicDispatcher::OnBufferPacketFailure(EnqueuePacketResult result,
- QuicConnectionId connection_id) {
- QUIC_DLOG(INFO) << "Fail to buffer packet on connection " << connection_id
- << " because of " << result;
-}
-
-void QuicDispatcher::OnConnectionRejectedStatelessly() {}
-
-void QuicDispatcher::OnConnectionClosedStatelessly(QuicErrorCode error) {}
-
-bool QuicDispatcher::ShouldAttemptCheapStatelessRejection() {
- return true;
-}
-
-QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
- return new QuicTimeWaitListManager(writer_.get(), this, helper_.get(),
- alarm_factory_.get());
-}
-
-void QuicDispatcher::BufferEarlyPacket(QuicConnectionId connection_id,
- bool ietf_quic) {
- bool is_new_connection = !buffered_packets_.HasBufferedPackets(connection_id);
- if (is_new_connection &&
- !ShouldCreateOrBufferPacketForConnection(connection_id)) {
- return;
- }
- EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
- connection_id, ietf_quic, *current_packet_, current_self_address_,
- current_peer_address_, /*is_chlo=*/false, /*alpn=*/"");
- if (rs != EnqueuePacketResult::SUCCESS) {
- OnBufferPacketFailure(rs, connection_id);
- }
-}
-
-void QuicDispatcher::ProcessChlo() {
- if (!accept_new_connections_) {
- // Don't any create new connection.
- time_wait_list_manager()->AddConnectionIdToTimeWait(
- current_connection_id(), framer()->version(),
- framer()->last_packet_is_ietf_quic(),
- /*connection_rejected_statelessly=*/false,
- /*termination_packets=*/nullptr);
- // This will trigger sending Public Reset packet.
- time_wait_list_manager()->ProcessPacket(current_self_address(),
- current_peer_address(),
- current_connection_id());
- return;
- }
- if (!buffered_packets_.HasBufferedPackets(current_connection_id_) &&
- !ShouldCreateOrBufferPacketForConnection(current_connection_id_)) {
- return;
- }
- if (FLAGS_quic_allow_chlo_buffering &&
- new_sessions_allowed_per_event_loop_ <= 0) {
- // Can't create new session any more. Wait till next event loop.
- QUIC_BUG_IF(buffered_packets_.HasChloForConnection(current_connection_id_));
- EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
- current_connection_id_, framer_.last_packet_is_ietf_quic(),
- *current_packet_, current_self_address_, current_peer_address_,
- /*is_chlo=*/true, current_alpn_);
- if (rs != EnqueuePacketResult::SUCCESS) {
- OnBufferPacketFailure(rs, current_connection_id_);
- }
- return;
- }
- // Creates a new session and process all buffered packets for this connection.
- QuicSession* session = CreateQuicSession(
- current_connection_id_, current_peer_address_, current_alpn_);
- QUIC_DLOG(INFO) << "Created new session for " << current_connection_id_;
- session_map_.insert(
- std::make_pair(current_connection_id_, QuicWrapUnique(session)));
- std::list<BufferedPacket> packets =
- buffered_packets_.DeliverPackets(current_connection_id_).buffered_packets;
-
- // Process CHLO at first.
- session->ProcessUdpPacket(current_self_address_, current_peer_address_,
- *current_packet_);
- // Deliver queued-up packets in the same order as they arrived.
- // Do this even when flag is off because there might be still some packets
- // buffered in the store before flag is turned off.
- DeliverPacketsToSession(packets, session);
- --new_sessions_allowed_per_event_loop_;
-}
-
-const QuicSocketAddress QuicDispatcher::GetClientAddress() const {
- return current_peer_address_;
-}
-
-bool QuicDispatcher::ShouldDestroySessionAsynchronously() {
- return true;
-}
-
-bool QuicDispatcher::HandlePacketForTimeWait(const QuicPacketHeader& header) {
- if (header.reset_flag) {
- // Public reset packets do not have packet numbers, so ignore the packet.
- return false;
- }
-
- // Switch the framer to the correct version, so that the packet number can
- // be parsed correctly.
- framer_.set_version(time_wait_list_manager_->GetQuicVersionFromConnectionId(
- header.connection_id));
-
- // Continue parsing the packet to extract the packet number. Then
- // send it to the time wait manager in OnUnathenticatedHeader.
- return true;
-}
-
-QuicPacketWriter* QuicDispatcher::CreatePerConnectionWriter() {
- return new QuicPerConnectionPacketWriter(writer_.get());
-}
-
-void QuicDispatcher::SetLastError(QuicErrorCode error) {
- last_error_ = error;
-}
-
-bool QuicDispatcher::OnUnauthenticatedUnknownPublicHeader(
- const QuicPacketHeader& header) {
- return true;
-}
-
-class StatelessRejectorProcessDoneCallback
- : public StatelessRejector::ProcessDoneCallback {
- public:
- StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher,
- ParsedQuicVersion first_version)
- : dispatcher_(dispatcher),
- current_client_address_(dispatcher->current_client_address_),
- current_peer_address_(dispatcher->current_peer_address_),
- current_self_address_(dispatcher->current_self_address_),
- current_packet_(
- dispatcher->current_packet_->Clone()), // Note: copies the packet
- first_version_(first_version) {}
-
- void Run(std::unique_ptr<StatelessRejector> rejector) override {
- dispatcher_->OnStatelessRejectorProcessDone(
- std::move(rejector), current_client_address_, current_peer_address_,
- current_self_address_, std::move(current_packet_), first_version_);
- }
-
- private:
- QuicDispatcher* dispatcher_;
- QuicSocketAddress current_client_address_;
- QuicSocketAddress current_peer_address_;
- QuicSocketAddress current_self_address_;
- std::unique_ptr<QuicReceivedPacket> current_packet_;
- ParsedQuicVersion first_version_;
-};
-
-void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
- ParsedQuicVersion version) {
- if (version.handshake_protocol == PROTOCOL_TLS1_3) {
- ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id);
- return;
- // TODO(nharper): Support buffering non-ClientHello packets when using TLS.
- }
- // TODO(rch): This logic should probably live completely inside the rejector.
- if (!FLAGS_quic_allow_chlo_buffering ||
- !GetQuicReloadableFlag(quic_use_cheap_stateless_rejects) ||
- !GetQuicReloadableFlag(enable_quic_stateless_reject_support) ||
- !ShouldAttemptCheapStatelessRejection()) {
- // Not use cheap stateless reject.
- ChloAlpnExtractor alpn_extractor;
- if (FLAGS_quic_allow_chlo_buffering &&
- !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
- config_.create_session_tag_indicators(),
- &alpn_extractor)) {
- // Buffer non-CHLO packets.
- ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id);
- return;
- }
- current_alpn_ = alpn_extractor.ConsumeAlpn();
- ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id);
- return;
- }
-
- std::unique_ptr<StatelessRejector> rejector(new StatelessRejector(
- version.transport_version, GetSupportedTransportVersions(),
- crypto_config_, &compressed_certs_cache_, helper()->GetClock(),
- helper()->GetRandomGenerator(), current_packet_->length(),
- current_client_address_, current_self_address_));
- ChloValidator validator(session_helper_.get(), current_self_address_,
- rejector.get());
- if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
- config_.create_session_tag_indicators(),
- &validator)) {
- ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id);
- return;
- }
- current_alpn_ = validator.ConsumeAlpn();
-
- if (!validator.can_accept()) {
- // This CHLO is prohibited by policy.
- StatelessConnectionTerminator terminator(connection_id, &framer_, helper(),
- time_wait_list_manager_.get());
- terminator.CloseConnection(QUIC_HANDSHAKE_FAILED,
- validator.error_details());
- OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED);
- ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id);
- return;
- }
-
- // If we were able to make a decision about this CHLO based purely on the
- // information available in OnChlo, just invoke the done callback immediately.
- if (rejector->state() != StatelessRejector::UNKNOWN) {
- ProcessStatelessRejectorState(std::move(rejector),
- version.transport_version);
- return;
- }
-
- // Insert into set of connection IDs to buffer
- const bool ok =
- temporarily_buffered_connections_.insert(connection_id).second;
- QUIC_BUG_IF(!ok)
- << "Processing multiple stateless rejections for connection ID "
- << connection_id;
-
- // Continue stateless rejector processing
- std::unique_ptr<StatelessRejectorProcessDoneCallback> cb(
- new StatelessRejectorProcessDoneCallback(this, version));
- StatelessRejector::Process(std::move(rejector), std::move(cb));
-}
-
-void QuicDispatcher::OnStatelessRejectorProcessDone(
- std::unique_ptr<StatelessRejector> rejector,
- const QuicSocketAddress& current_client_address,
- const QuicSocketAddress& current_peer_address,
- const QuicSocketAddress& current_self_address,
- std::unique_ptr<QuicReceivedPacket> current_packet,
- ParsedQuicVersion first_version) {
- // Stop buffering packets on this connection
- const auto num_erased =
- temporarily_buffered_connections_.erase(rejector->connection_id());
- QUIC_BUG_IF(num_erased != 1) << "Completing stateless rejection logic for "
- "non-buffered connection ID "
- << rejector->connection_id();
-
- // If this connection has gone into time-wait during the async processing,
- // don't proceed.
- if (time_wait_list_manager_->IsConnectionIdInTimeWait(
- rejector->connection_id())) {
- time_wait_list_manager_->ProcessPacket(
- current_self_address, current_peer_address, rejector->connection_id());
- return;
- }
-
- // Reset current_* to correspond to the packet which initiated the stateless
- // reject logic.
- current_client_address_ = current_client_address;
- current_peer_address_ = current_peer_address;
- current_self_address_ = current_self_address;
- current_packet_ = current_packet.get();
- current_connection_id_ = rejector->connection_id();
- framer_.set_version(first_version);
-
- ProcessStatelessRejectorState(std::move(rejector),
- first_version.transport_version);
-}
-
-void QuicDispatcher::ProcessStatelessRejectorState(
- std::unique_ptr<StatelessRejector> rejector,
- QuicTransportVersion first_version) {
- QuicPacketFate fate;
- switch (rejector->state()) {
- case StatelessRejector::FAILED: {
- // There was an error processing the client hello.
- StatelessConnectionTerminator terminator(rejector->connection_id(),
- &framer_, helper(),
- time_wait_list_manager_.get());
- terminator.CloseConnection(rejector->error(), rejector->error_details());
- fate = kFateTimeWait;
- break;
- }
-
- case StatelessRejector::UNSUPPORTED:
- // Cheap stateless rejects are not supported so process the packet.
- fate = kFateProcess;
- break;
-
- case StatelessRejector::ACCEPTED:
- // Contains a valid CHLO, so process the packet and create a connection.
- fate = kFateProcess;
- break;
-
- case StatelessRejector::REJECTED: {
- QUIC_BUG_IF(first_version != framer_.transport_version())
- << "SREJ: Client's version: " << QuicVersionToString(first_version)
- << " is different from current dispatcher framer's version: "
- << QuicVersionToString(framer_.transport_version());
- StatelessConnectionTerminator terminator(rejector->connection_id(),
- &framer_, helper(),
- time_wait_list_manager_.get());
- terminator.RejectConnection(rejector->reply()
- .GetSerialized(Perspective::IS_SERVER)
- .AsStringPiece());
- OnConnectionRejectedStatelessly();
- fate = kFateTimeWait;
- break;
- }
-
- default:
- QUIC_BUG << "Rejector has invalid state " << rejector->state();
- fate = kFateDrop;
- break;
- }
- ProcessUnauthenticatedHeaderFate(fate, rejector->connection_id());
-}
-
-const QuicTransportVersionVector&
-QuicDispatcher::GetSupportedTransportVersions() {
- return version_manager_->GetSupportedTransportVersions();
-}
-
-const ParsedQuicVersionVector& QuicDispatcher::GetSupportedVersions() {
- return version_manager_->GetSupportedVersions();
-}
-
-void QuicDispatcher::DeliverPacketsToSession(
- const std::list<BufferedPacket>& packets,
- QuicSession* session) {
- for (const BufferedPacket& packet : packets) {
- session->ProcessUdpPacket(packet.server_address, packet.client_address,
- *(packet.packet));
- }
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_dispatcher.h b/chromium/net/tools/quic/quic_dispatcher.h
deleted file mode 100644
index 27c7c8cad6e..00000000000
--- a/chromium/net/tools/quic/quic_dispatcher.h
+++ /dev/null
@@ -1,438 +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.
-//
-// A server side dispatcher which dispatches a given client's data to their
-// stream.
-
-#ifndef NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
-#define NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "net/quic/core/crypto/quic_compressed_certs_cache.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_blocked_writer_interface.h"
-#include "net/quic/core/quic_buffered_packet_store.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_crypto_server_stream.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_session.h"
-#include "net/quic/core/quic_version_manager.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_string.h"
-
-#include "net/tools/quic/quic_process_packet_interface.h"
-#include "net/tools/quic/quic_time_wait_list_manager.h"
-#include "net/tools/quic/stateless_rejector.h"
-
-namespace net {
-namespace test {
-class QuicDispatcherPeer;
-} // namespace test
-
-class QuicConfig;
-class QuicCryptoServerConfig;
-
-class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
- public ProcessPacketInterface,
- public QuicFramerVisitorInterface,
- public QuicBufferedPacketStore::VisitorInterface {
- public:
- // Ideally we'd have a linked_hash_set: the boolean is unused.
- typedef QuicLinkedHashMap<QuicBlockedWriterInterface*, bool> WriteBlockedList;
-
- QuicDispatcher(const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory);
-
- ~QuicDispatcher() override;
-
- // Takes ownership of |writer|.
- void InitializeWithWriter(QuicPacketWriter* writer);
-
- // Process the incoming packet by creating a new session, passing it to
- // an existing session, or passing it to the time wait list.
- void ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) override;
-
- // Called when the socket becomes writable to allow queued writes to happen.
- virtual void OnCanWrite();
-
- // Returns true if there's anything in the blocked writer list.
- virtual bool HasPendingWrites() const;
-
- // Sends ConnectionClose frames to all connected clients.
- void Shutdown();
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Ensure that the closed connection is cleaned up asynchronously.
- void OnConnectionClosed(QuicConnectionId connection_id,
- QuicErrorCode error,
- const QuicString& error_details) override;
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Queues the blocked writer for later resumption.
- void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) override;
-
- // QuicSession::Visitor interface implementation (via inheritance of
- // QuicTimeWaitListManager::Visitor):
- // Collects reset error code received on streams.
- void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
-
- // QuicTimeWaitListManager::Visitor interface implementation
- // Called whenever the time wait list manager adds a new connection to the
- // time-wait list.
- void OnConnectionAddedToTimeWaitList(QuicConnectionId connection_id) override;
-
- using SessionMap =
- QuicUnorderedMap<QuicConnectionId, std::unique_ptr<QuicSession>>;
-
- const SessionMap& session_map() const { return session_map_; }
-
- // Deletes all sessions on the closed session list and clears the list.
- virtual void DeleteSessions();
-
- // The largest packet number we expect to receive with a connection
- // ID for a connection that is not established yet. The current design will
- // send a handshake and then up to 50 or so data packets, and then it may
- // resend the handshake packet up to 10 times. (Retransmitted packets are
- // sent with unique packet numbers.)
- static const QuicPacketNumber kMaxReasonableInitialPacketNumber = 100;
- static_assert(kMaxReasonableInitialPacketNumber >=
- kInitialCongestionWindow + 10,
- "kMaxReasonableInitialPacketNumber is unreasonably small "
- "relative to kInitialCongestionWindow.");
-
- // QuicFramerVisitorInterface implementation. Not expected to be called
- // outside of this class.
- void OnPacket() override;
- // Called when the public header has been parsed.
- bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
- // Called when the private header has been parsed of a data packet that is
- // destined for the time wait manager.
- bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
- void OnError(QuicFramer* framer) override;
- bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override;
-
- // The following methods should never get called because
- // OnUnauthenticatedPublicHeader() or OnUnauthenticatedHeader() (whichever
- // was called last), will return false and prevent a subsequent invocation
- // of these methods. Thus, the payload of the packet is never processed in
- // the dispatcher.
- void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& packet) override;
- void OnDecryptedPacket(EncryptionLevel level) override;
- bool OnPacketHeader(const QuicPacketHeader& header) override;
- bool OnStreamFrame(const QuicStreamFrame& frame) override;
- bool OnAckFrame(const QuicAckFrame& frame) override;
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) override;
- bool OnAckRange(QuicPacketNumber start,
- QuicPacketNumber end,
- bool last_range) override;
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
- bool OnPingFrame(const QuicPingFrame& frame) override;
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
- void OnPacketComplete() override;
- bool IsValidStatelessResetToken(uint128 token) const override;
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) override;
-
- // QuicBufferedPacketStore::VisitorInterface implementation.
- void OnExpiredPackets(QuicConnectionId connection_id,
- QuicBufferedPacketStore::BufferedPacketList
- early_arrived_packets) override;
-
- // Create connections for previously buffered CHLOs as many as allowed.
- virtual void ProcessBufferedChlos(size_t max_connections_to_create);
-
- // Return true if there is CHLO buffered.
- virtual bool HasChlosBuffered() const;
-
- protected:
- virtual QuicSession* CreateQuicSession(QuicConnectionId connection_id,
- const QuicSocketAddress& peer_address,
- QuicStringPiece alpn) = 0;
-
- // Called when a connection is rejected statelessly.
- virtual void OnConnectionRejectedStatelessly();
-
- // Called when a connection is closed statelessly.
- virtual void OnConnectionClosedStatelessly(QuicErrorCode error);
-
- // Returns true if cheap stateless rejection should be attempted.
- virtual bool ShouldAttemptCheapStatelessRejection();
-
- // Values to be returned by ValidityChecks() to indicate what should be done
- // with a packet. Fates with greater values are considered to be higher
- // priority, in that if one validity check indicates a lower-valued fate and
- // another validity check indicates a higher-valued fate, the higher-valued
- // fate should be obeyed.
- enum QuicPacketFate {
- // Process the packet normally, which is usually to establish a connection.
- kFateProcess,
- // Put the connection ID into time-wait state and send a public reset.
- kFateTimeWait,
- // Buffer the packet.
- kFateBuffer,
- // Drop the packet (ignore and give no response).
- kFateDrop,
- };
-
- // This method is called by OnUnauthenticatedHeader on packets not associated
- // with a known connection ID. It applies validity checks and returns a
- // QuicPacketFate to tell what should be done with the packet.
- virtual QuicPacketFate ValidityChecks(const QuicPacketHeader& header);
-
- // Create and return the time wait list manager for this dispatcher, which
- // will be owned by the dispatcher as time_wait_list_manager_
- virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
-
- // Called when |connection_id| doesn't have an open connection yet, to buffer
- // |current_packet_| until it can be delivered to the connection.
- void BufferEarlyPacket(QuicConnectionId connection_id, bool ietf_quic);
-
- // Called when |current_packet_| is a CHLO packet. Creates a new connection
- // and delivers any buffered packets for that connection id.
- void ProcessChlo();
-
- // Returns the actual client address of the current packet.
- // This function should only be called once per packet at the very beginning
- // of ProcessPacket(), its result is saved to |current_client_address_|, which
- // is guaranteed to be valid even in the stateless rejector's callback(i.e.
- // OnStatelessRejectorProcessDone).
- // By default, this function returns |current_peer_address_|, subclasses have
- // the option to override this function to return a different address.
- virtual const QuicSocketAddress GetClientAddress() const;
-
- // Return true if dispatcher wants to destroy session outside of
- // OnConnectionClosed() call stack.
- virtual bool ShouldDestroySessionAsynchronously();
-
- QuicTimeWaitListManager* time_wait_list_manager() {
- return time_wait_list_manager_.get();
- }
-
- const QuicTransportVersionVector& GetSupportedTransportVersions();
-
- const ParsedQuicVersionVector& GetSupportedVersions();
-
- QuicConnectionId current_connection_id() const {
- return current_connection_id_;
- }
- const QuicSocketAddress& current_self_address() const {
- return current_self_address_;
- }
- const QuicSocketAddress& current_peer_address() const {
- return current_peer_address_;
- }
- const QuicSocketAddress& current_client_address() const {
- return current_client_address_;
- }
- const QuicReceivedPacket& current_packet() const { return *current_packet_; }
-
- const QuicConfig& config() const { return config_; }
-
- const QuicCryptoServerConfig* crypto_config() const { return crypto_config_; }
-
- QuicCompressedCertsCache* compressed_certs_cache() {
- return &compressed_certs_cache_;
- }
-
- QuicFramer* framer() { return &framer_; }
-
- QuicConnectionHelperInterface* helper() { return helper_.get(); }
-
- QuicCryptoServerStream::Helper* session_helper() {
- return session_helper_.get();
- }
-
- QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
-
- QuicPacketWriter* writer() { return writer_.get(); }
-
- // Creates per-connection packet writers out of the QuicDispatcher's shared
- // QuicPacketWriter. The per-connection writers' IsWriteBlocked() state must
- // always be the same as the shared writer's IsWriteBlocked(), or else the
- // QuicDispatcher::OnCanWrite logic will not work. (This will hopefully be
- // cleaned up for bug 16950226.)
- virtual QuicPacketWriter* CreatePerConnectionWriter();
-
- // Returns true if a session should be created for a connection with an
- // unknown version identified by |version_label|.
- virtual bool ShouldCreateSessionForUnknownVersion(
- QuicVersionLabel version_label);
-
- void SetLastError(QuicErrorCode error);
-
- // Called when the public header has been parsed and the session has been
- // looked up, and the session was not found in the active list of sessions.
- // Returns false if processing should stop after this call.
- virtual bool OnUnauthenticatedUnknownPublicHeader(
- const QuicPacketHeader& header);
-
- // Called when a new connection starts to be handled by this dispatcher.
- // Either this connection is created or its packets is buffered while waiting
- // for CHLO. Returns true if a new connection should be created or its packets
- // should be buffered, false otherwise.
- virtual bool ShouldCreateOrBufferPacketForConnection(
- QuicConnectionId connection_id);
-
- bool HasBufferedPackets(QuicConnectionId connection_id);
-
- // Called when BufferEarlyPacket() fail to buffer the packet.
- virtual void OnBufferPacketFailure(
- QuicBufferedPacketStore::EnqueuePacketResult result,
- QuicConnectionId connection_id);
-
- // Removes the session from the session map and write blocked list, and adds
- // the ConnectionId to the time-wait list. If |session_closed_statelessly| is
- // true, any future packets for the ConnectionId will be black-holed.
- virtual void CleanUpSession(SessionMap::iterator it,
- QuicConnection* connection,
- bool session_closed_statelessly);
-
- void StopAcceptingNewConnections();
-
- // Return true if the blocked writer should be added to blocked list.
- virtual bool ShouldAddToBlockedList();
-
- private:
- friend class test::QuicDispatcherPeer;
- friend class StatelessRejectorProcessDoneCallback;
-
- typedef QuicUnorderedSet<QuicConnectionId> QuicConnectionIdSet;
-
- bool HandlePacketForTimeWait(const QuicPacketHeader& header);
-
- // Attempts to reject the connection statelessly, if stateless rejects are
- // possible and if the current packet contains a CHLO message. Determines a
- // fate which describes what subsequent processing should be performed on the
- // packets, like ValidityChecks, and invokes ProcessUnauthenticatedHeaderFate.
- void MaybeRejectStatelessly(QuicConnectionId connection_id,
- ParsedQuicVersion version);
-
- // Deliver |packets| to |session| for further processing.
- void DeliverPacketsToSession(
- const std::list<QuicBufferedPacketStore::BufferedPacket>& packets,
- QuicSession* session);
-
- // Perform the appropriate actions on the current packet based on |fate| -
- // either process, buffer, or drop it.
- void ProcessUnauthenticatedHeaderFate(QuicPacketFate fate,
- QuicConnectionId connection_id);
-
- // Invoked when StatelessRejector::Process completes. |first_version| is the
- // version of the packet which initiated the stateless reject.
- // WARNING: This function can be called when a async proof returns, i.e. not
- // from a stack traceable to ProcessPacket().
- void OnStatelessRejectorProcessDone(
- std::unique_ptr<StatelessRejector> rejector,
- const QuicSocketAddress& current_client_address,
- const QuicSocketAddress& current_peer_address,
- const QuicSocketAddress& current_self_address,
- std::unique_ptr<QuicReceivedPacket> current_packet,
- ParsedQuicVersion first_version);
-
- // Examine the state of the rejector and decide what to do with the current
- // packet.
- void ProcessStatelessRejectorState(
- std::unique_ptr<StatelessRejector> rejector,
- QuicTransportVersion first_version);
-
- void set_new_sessions_allowed_per_event_loop(
- int16_t new_sessions_allowed_per_event_loop) {
- new_sessions_allowed_per_event_loop_ = new_sessions_allowed_per_event_loop;
- }
-
- const QuicConfig& config_;
-
- const QuicCryptoServerConfig* crypto_config_;
-
- // The cache for most recently compressed certs.
- QuicCompressedCertsCache compressed_certs_cache_;
-
- // The list of connections waiting to write.
- WriteBlockedList write_blocked_list_;
-
- SessionMap session_map_;
-
- // Entity that manages connection_ids in time wait state.
- std::unique_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
-
- // The list of closed but not-yet-deleted sessions.
- std::vector<std::unique_ptr<QuicSession>> closed_session_list_;
-
- // The helper used for all connections.
- std::unique_ptr<QuicConnectionHelperInterface> helper_;
-
- // The helper used for all sessions.
- std::unique_ptr<QuicCryptoServerStream::Helper> session_helper_;
-
- // Creates alarms.
- std::unique_ptr<QuicAlarmFactory> alarm_factory_;
-
- // An alarm which deletes closed sessions.
- std::unique_ptr<QuicAlarm> delete_sessions_alarm_;
-
- // The writer to write to the socket with.
- std::unique_ptr<QuicPacketWriter> writer_;
-
- // Packets which are buffered until a connection can be created to handle
- // them.
- QuicBufferedPacketStore buffered_packets_;
-
- // Set of connection IDs for which asynchronous CHLO processing is in
- // progress, making it necessary to buffer any other packets which arrive on
- // that connection until CHLO processing is complete.
- QuicConnectionIdSet temporarily_buffered_connections_;
-
- // Information about the packet currently being handled.
-
- // Used for stateless rejector to generate and validate source address token.
- QuicSocketAddress current_client_address_;
- QuicSocketAddress current_peer_address_;
- QuicSocketAddress current_self_address_;
- const QuicReceivedPacket* current_packet_;
- // If |current_packet_| is a CHLO packet, the extracted alpn.
- QuicString current_alpn_;
- QuicConnectionId current_connection_id_;
-
- // Used to get the supported versions based on flag. Does not own.
- QuicVersionManager* version_manager_;
-
- QuicFramer framer_;
-
- // The last error set by SetLastError(), which is called by
- // framer_visitor_->OnError().
- QuicErrorCode last_error_;
-
- // A backward counter of how many new sessions can be create within current
- // event loop. When reaches 0, it means can't create sessions for now.
- int16_t new_sessions_allowed_per_event_loop_;
-
- // True if this dispatcher is not draining.
- bool accept_new_connections_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicDispatcher);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
diff --git a/chromium/net/tools/quic/quic_dispatcher_test.cc b/chromium/net/tools/quic/quic_dispatcher_test.cc
deleted file mode 100644
index 1f118e14f62..00000000000
--- a/chromium/net/tools/quic/quic_dispatcher_test.cc
+++ /dev/null
@@ -1,2421 +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/tools/quic/quic_dispatcher.h"
-
-#include <memory>
-#include <ostream>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "net/quic/core/crypto/crypto_handshake.h"
-#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/crypto/quic_crypto_server_config.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_crypto_stream.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/core/tls_server_handshaker.h"
-#include "net/quic/platform/api/quic_arraysize.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_str_cat.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/fake_proof_source.h"
-#include "net/quic/test_tools/quic_buffered_packet_store_peer.h"
-#include "net/quic/test_tools/quic_crypto_server_config_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/quic/test_tools/quic_time_wait_list_manager_peer.h"
-#include "net/test/gtest_util.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/chlo_extractor.h"
-#include "net/tools/quic/quic_epoll_alarm_factory.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-#include "net/tools/quic/quic_packet_writer_wrapper.h"
-#include "net/tools/quic/quic_simple_crypto_server_stream_helper.h"
-#include "net/tools/quic/quic_time_wait_list_manager.h"
-#include "net/tools/quic/stateless_rejector.h"
-#include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h"
-#include "net/tools/quic/test_tools/quic_dispatcher_peer.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gmock_mutant.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using std::string;
-using testing::_;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::WithArg;
-using testing::WithoutArgs;
-
-static const size_t kDefaultMaxConnectionsInStore = 100;
-static const size_t kMaxConnectionsWithoutCHLO =
- kDefaultMaxConnectionsInStore / 2;
-static const int16_t kMaxNumSessionsToCreate = 16;
-
-namespace net {
-namespace test {
-namespace {
-
-class TestQuicSpdyServerSession : public QuicServerSessionBase {
- public:
- TestQuicSpdyServerSession(const QuicConfig& config,
- QuicConnection* connection,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache)
- : QuicServerSessionBase(config,
- connection,
- nullptr,
- nullptr,
- crypto_config,
- compressed_certs_cache),
- crypto_stream_(QuicServerSessionBase::GetMutableCryptoStream()) {}
-
- ~TestQuicSpdyServerSession() override { delete connection(); };
-
- MOCK_METHOD3(OnConnectionClosed,
- void(QuicErrorCode error,
- const QuicString& error_details,
- ConnectionCloseSource source));
- MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
- MOCK_METHOD0(CreateOutgoingDynamicStream, QuicSpdyStream*());
-
- QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) override {
- return new QuicCryptoServerStream(
- crypto_config, compressed_certs_cache,
- GetQuicReloadableFlag(enable_quic_stateless_reject_support), this,
- stream_helper());
- }
-
- void SetCryptoStream(QuicCryptoServerStream* crypto_stream) {
- crypto_stream_ = crypto_stream;
- }
-
- QuicCryptoServerStreamBase* GetMutableCryptoStream() override {
- return crypto_stream_;
- }
-
- const QuicCryptoServerStreamBase* GetCryptoStream() const override {
- return crypto_stream_;
- }
-
- QuicCryptoServerStream::Helper* stream_helper() {
- return QuicServerSessionBase::stream_helper();
- }
-
- private:
- QuicCryptoServerStreamBase* crypto_stream_;
-
- DISALLOW_COPY_AND_ASSIGN(TestQuicSpdyServerSession);
-};
-
-class TestDispatcher : public QuicDispatcher {
- public:
- TestDispatcher(const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- EpollServer* eps)
- : QuicDispatcher(
- config,
- crypto_config,
- version_manager,
- std::unique_ptr<QuicEpollConnectionHelper>(
- new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)),
- std::unique_ptr<QuicCryptoServerStream::Helper>(
- new QuicSimpleCryptoServerStreamHelper(
- QuicRandom::GetInstance())),
- std::unique_ptr<QuicEpollAlarmFactory>(
- new QuicEpollAlarmFactory(eps))) {}
-
- MOCK_METHOD3(CreateQuicSession,
- QuicServerSessionBase*(QuicConnectionId connection_id,
- const QuicSocketAddress& peer_address,
- QuicStringPiece alpn));
-
- MOCK_METHOD1(ShouldCreateOrBufferPacketForConnection,
- bool(QuicConnectionId connection_id));
-
- using QuicDispatcher::current_client_address;
- using QuicDispatcher::current_peer_address;
- using QuicDispatcher::current_self_address;
-};
-
-// A Connection class which unregisters the session from the dispatcher when
-// sending connection close.
-// It'd be slightly more realistic to do this from the Session but it would
-// involve a lot more mocking.
-class MockServerConnection : public MockQuicConnection {
- public:
- MockServerConnection(QuicConnectionId connection_id,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- QuicDispatcher* dispatcher)
- : MockQuicConnection(connection_id,
- helper,
- alarm_factory,
- Perspective::IS_SERVER),
- dispatcher_(dispatcher) {}
-
- void UnregisterOnConnectionClosed() {
- QUIC_LOG(ERROR) << "Unregistering " << connection_id();
- dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
- "Unregistering.");
- }
-
- private:
- QuicDispatcher* dispatcher_;
-};
-
-class QuicDispatcherTest : public QuicTest {
- public:
- QuicDispatcherTest()
- : QuicDispatcherTest(crypto_test_utils::ProofSourceForTesting()) {}
-
- ParsedQuicVersionVector AllSupportedVersionsIncludingTls() {
- SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
- return AllSupportedVersions();
- }
-
- explicit QuicDispatcherTest(std::unique_ptr<ProofSource> proof_source)
- : helper_(&eps_, QuicAllocator::BUFFER_POOL),
- alarm_factory_(&eps_),
- version_manager_(AllSupportedVersionsIncludingTls()),
- crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- std::move(proof_source),
- TlsServerHandshaker::CreateSslCtx()),
- dispatcher_(new TestDispatcher(config_,
- &crypto_config_,
- &version_manager_,
- &eps_)),
- time_wait_list_manager_(nullptr),
- session1_(nullptr),
- session2_(nullptr),
- store_(nullptr) {}
-
- void SetUp() override {
- dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1));
- // Set the counter to some value to start with.
- QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
- dispatcher_.get(), kMaxNumSessionsToCreate);
- ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_))
- .WillByDefault(Return(true));
- }
-
- ~QuicDispatcherTest() override = default;
-
- MockQuicConnection* connection1() {
- return reinterpret_cast<MockQuicConnection*>(session1_->connection());
- }
-
- MockQuicConnection* connection2() {
- return reinterpret_cast<MockQuicConnection*>(session2_->connection());
- }
-
- // Process a packet with an 8 byte connection id,
- // 6 byte packet number, default path id, and packet number 1,
- // using the first supported version.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId connection_id,
- bool has_version_flag,
- const QuicString& data) {
- ProcessPacket(peer_address, connection_id, has_version_flag, data,
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER);
- }
-
- // Process a packet with a default path id, and packet number 1,
- // using the first supported version.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId connection_id,
- bool has_version_flag,
- const QuicString& data,
- QuicConnectionIdLength connection_id_length,
- QuicPacketNumberLength packet_number_length) {
- ProcessPacket(peer_address, connection_id, has_version_flag, data,
- connection_id_length, packet_number_length, 1);
- }
-
- // Process a packet using the first supported version.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId connection_id,
- bool has_version_flag,
- const QuicString& data,
- QuicConnectionIdLength connection_id_length,
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_number) {
- ProcessPacket(peer_address, connection_id, has_version_flag,
- CurrentSupportedVersions().front(), data,
- connection_id_length, packet_number_length, packet_number);
- }
-
- // Processes a packet.
- void ProcessPacket(QuicSocketAddress peer_address,
- QuicConnectionId connection_id,
- bool has_version_flag,
- ParsedQuicVersion version,
- const QuicString& data,
- QuicConnectionIdLength connection_id_length,
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_number) {
- ParsedQuicVersionVector versions(SupportedVersions(version));
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- connection_id, has_version_flag, false, packet_number, data,
- connection_id_length, packet_number_length, &versions));
- std::unique_ptr<QuicReceivedPacket> received_packet(
- ConstructReceivedPacket(*packet, helper_.GetClock()->Now()));
-
- if (ChloExtractor::Extract(*packet, versions, {}, nullptr)) {
- // Add CHLO packet to the beginning to be verified first, because it is
- // also processed first by new session.
- data_connection_map_[connection_id].push_front(
- QuicString(packet->data(), packet->length()));
- } else {
- // For non-CHLO, always append to last.
- data_connection_map_[connection_id].push_back(
- QuicString(packet->data(), packet->length()));
- }
- dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
- }
-
- void ValidatePacket(QuicConnectionId conn_id,
- const QuicEncryptedPacket& packet) {
- EXPECT_EQ(data_connection_map_[conn_id].front().length(),
- packet.AsStringPiece().length());
- EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
- data_connection_map_[conn_id].pop_front();
- }
-
- QuicServerSessionBase* CreateSession(
- QuicDispatcher* dispatcher,
- const QuicConfig& config,
- QuicConnectionId connection_id,
- const QuicSocketAddress& peer_address,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- TestQuicSpdyServerSession** session) {
- MockServerConnection* connection = new MockServerConnection(
- connection_id, helper, alarm_factory, dispatcher);
- *session = new TestQuicSpdyServerSession(config, connection, crypto_config,
- compressed_certs_cache);
- connection->set_visitor(*session);
- ON_CALL(*connection, CloseConnection(_, _, _))
- .WillByDefault(WithoutArgs(Invoke(
- connection, &MockServerConnection::UnregisterOnConnectionClosed)));
- return *session;
- }
-
- void CreateTimeWaitListManager() {
- time_wait_list_manager_ = new MockTimeWaitListManager(
- QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
- &helper_, &alarm_factory_);
- // dispatcher_ takes the ownership of time_wait_list_manager_.
- QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
- time_wait_list_manager_);
- }
-
- QuicString SerializeCHLO() {
- CryptoHandshakeMessage client_hello;
- client_hello.set_tag(kCHLO);
- client_hello.SetStringPiece(kALPN, "hq");
- return string(
- client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
- }
-
- QuicString SerializeTlsClientHello() { return ""; }
-
- EpollServer eps_;
- QuicEpollConnectionHelper helper_;
- MockQuicConnectionHelper mock_helper_;
- QuicEpollAlarmFactory alarm_factory_;
- MockAlarmFactory mock_alarm_factory_;
- QuicConfig config_;
- QuicVersionManager version_manager_;
- QuicCryptoServerConfig crypto_config_;
- QuicSocketAddress server_address_;
- std::unique_ptr<TestDispatcher> dispatcher_;
- MockTimeWaitListManager* time_wait_list_manager_;
- TestQuicSpdyServerSession* session1_;
- TestQuicSpdyServerSession* session2_;
- std::map<QuicConnectionId, std::list<QuicString>> data_connection_map_;
- QuicBufferedPacketStore* store_;
-};
-
-TEST_F(QuicDispatcherTest, TlsClientHelloCreatesSession) {
- FLAGS_quic_supports_tls_handshake = true;
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(1, client_address, QuicStringPiece("")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, 1, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(1, packet);
- })));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(1));
- ProcessPacket(
- client_address, 1, true,
- ParsedQuicVersion(PROTOCOL_TLS1_3,
- CurrentSupportedVersions().front().transport_version),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
- 1);
- EXPECT_EQ(client_address, dispatcher_->current_peer_address());
- EXPECT_EQ(server_address_, dispatcher_->current_self_address());
-}
-
-TEST_F(QuicDispatcherTest, ProcessPackets) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(1, client_address, QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, 1, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(1, packet);
- })));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(1));
- ProcessPacket(client_address, 1, true, SerializeCHLO());
- EXPECT_EQ(client_address, dispatcher_->current_peer_address());
- EXPECT_EQ(server_address_, dispatcher_->current_self_address());
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(2, client_address, QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, 2, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(2, packet);
- })));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(2));
- ProcessPacket(client_address, 2, true, SerializeCHLO());
-
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(1)
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(1, packet);
- })));
- ProcessPacket(client_address, 1, false, "data");
-}
-
-TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(1, client_address, QuicStringPiece("hq")))
- .Times(0);
- QuicTransportVersion version =
- static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
- ParsedQuicVersion parsed_version(PROTOCOL_QUIC_CRYPTO, version);
- ProcessPacket(client_address, 1, true, parsed_version, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER, 1);
-}
-
-TEST_F(QuicDispatcherTest, Shutdown) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(_, client_address, QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, 1, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(1, packet);
- })));
-
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(1));
- ProcessPacket(client_address, 1, true, SerializeCHLO());
-
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-
- dispatcher_->Shutdown();
-}
-
-TEST_F(QuicDispatcherTest, TimeWaitListManager) {
- CreateTimeWaitListManager();
-
- // Create a new session.
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = 1;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(1, packet);
- })));
-
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(1));
- ProcessPacket(client_address, connection_id, true, SerializeCHLO());
-
- // Close the connection by sending public reset packet.
- QuicPublicResetPacket packet;
- packet.connection_id = connection_id;
- packet.nonce_proof = 132232;
- std::unique_ptr<QuicEncryptedPacket> encrypted(
- QuicFramer::BuildPublicResetPacket(packet));
- std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
- *encrypted, session1_->connection()->clock()->Now()));
- EXPECT_CALL(*session1_, OnConnectionClosed(QUIC_PUBLIC_RESET, _,
- ConnectionCloseSource::FROM_PEER))
- .Times(1)
- .WillOnce(WithoutArgs(Invoke(
- reinterpret_cast<MockServerConnection*>(session1_->connection()),
- &MockServerConnection::UnregisterOnConnectionClosed)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(
- Invoke(reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- &MockQuicConnection::ReallyProcessUdpPacket));
- dispatcher_->ProcessPacket(QuicSocketAddress(), client_address, *received);
- EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
-
- // Dispatcher forwards subsequent packets for this connection_id to the time
- // wait list manager.
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id))
- .Times(1);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(_, _, _, _, _))
- .Times(0);
- ProcessPacket(client_address, connection_id, true, "data");
-}
-
-TEST_F(QuicDispatcherTest, NoVersionPacketToTimeWaitListManager) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = 1;
- // Dispatcher forwards all packets for this connection_id to the time wait
- // list manager.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq")))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id))
- .Times(1);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(_, _, _, _, _))
- .Times(1);
- ProcessPacket(client_address, connection_id, false, SerializeCHLO());
-}
-
-TEST_F(QuicDispatcherTest, ProcessPacketWithZeroPort) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
-
- // dispatcher_ should drop this packet.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(1, client_address, QuicStringPiece("hq")))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(_, _, _, _, _))
- .Times(0);
- ProcessPacket(client_address, 1, true, SerializeCHLO());
-}
-
-TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = 1;
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(1, client_address, QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, 1, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(1, packet);
- })));
-
- // A packet whose packet number is the largest that is allowed to start a
- // connection.
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
- QuicDispatcher::kMaxReasonableInitialPacketNumber);
- EXPECT_EQ(client_address, dispatcher_->current_peer_address());
- EXPECT_EQ(server_address_, dispatcher_->current_self_address());
-}
-
-TEST_F(QuicDispatcherTest, TooBigSeqNoPacketToTimeWaitListManager) {
- CreateTimeWaitListManager();
- SetQuicRestartFlag(quic_enable_accept_random_ipn, false);
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = 1;
-
- // Dispatcher forwards this packet for this connection_id to the time wait
- // list manager.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq")))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, 1)).Times(1);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, 2)).Times(1);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(_, _, _, _, _))
- .Times(2);
- // A packet whose packet number is one to large to be allowed to start a
- // connection.
- ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
- QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
- connection_id = 2;
- SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
- ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
- kMaxRandomInitialPacketNumber +
- QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
-}
-
-TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
- static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 8u,
- "Supported versions out of sync");
- SetQuicReloadableFlag(quic_disable_version_37, false);
- SetQuicReloadableFlag(quic_disable_version_38, false);
- SetQuicReloadableFlag(quic_disable_version_41, false);
- SetQuicReloadableFlag(quic_enable_version_42_2, true);
- SetQuicReloadableFlag(quic_enable_version_43, true);
- SetQuicFlag(&FLAGS_quic_enable_version_99, true);
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
- QuicConnectionId connection_id = 1;
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .Times(0);
- ParsedQuicVersion version(
- PROTOCOL_QUIC_CRYPTO,
- static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1));
- ProcessPacket(client_address, connection_id, true, version, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER, 1);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
- QuicVersionMin().transport_version),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true, QuicVersionMax(),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn off version 43.
- SetQuicReloadableFlag(quic_enable_version_43, false);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .Times(0);
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn on version 43.
- SetQuicReloadableFlag(quic_enable_version_43, true);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn off version 42.
- SetQuicReloadableFlag(quic_enable_version_42_2, false);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .Times(0);
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_42),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn on version 42.
- SetQuicReloadableFlag(quic_enable_version_42_2, true);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_42),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn off version 41.
- SetQuicReloadableFlag(quic_disable_version_41, true);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .Times(0);
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_41),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn on version 41.
- SetQuicReloadableFlag(quic_disable_version_41, false);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_41),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn off version 38.
- SetQuicReloadableFlag(quic_disable_version_38, true);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .Times(0);
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_38),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn on version 38.
- SetQuicReloadableFlag(quic_disable_version_38, false);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_38),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn off version 37.
- SetQuicReloadableFlag(quic_disable_version_37, true);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .Times(0);
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Turn on version 37.
- SetQuicReloadableFlag(quic_disable_version_37, false);
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-}
-
-// Enables mocking of the handshake-confirmation for stateless rejects.
-class MockQuicCryptoServerStream : public QuicCryptoServerStream {
- public:
- MockQuicCryptoServerStream(const QuicCryptoServerConfig& crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicServerSessionBase* session,
- QuicCryptoServerStream::Helper* helper)
- : QuicCryptoServerStream(
- &crypto_config,
- compressed_certs_cache,
- GetQuicReloadableFlag(enable_quic_stateless_reject_support),
- session,
- helper),
- handshake_confirmed_(false) {}
-
- void set_handshake_confirmed_for_testing(bool handshake_confirmed) {
- handshake_confirmed_ = handshake_confirmed;
- }
-
- bool handshake_confirmed() const override { return handshake_confirmed_; }
-
- private:
- bool handshake_confirmed_;
- DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream);
-};
-
-struct StatelessRejectTestParams {
- StatelessRejectTestParams(bool enable_stateless_rejects_via_flag,
- bool client_supports_statelesss_rejects,
- bool crypto_handshake_successful)
- : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag),
- client_supports_statelesss_rejects(client_supports_statelesss_rejects),
- crypto_handshake_successful(crypto_handshake_successful) {}
-
- friend std::ostream& operator<<(std::ostream& os,
- const StatelessRejectTestParams& p) {
- os << "{ enable_stateless_rejects_via_flag: "
- << p.enable_stateless_rejects_via_flag << std::endl;
- os << " client_supports_statelesss_rejects: "
- << p.client_supports_statelesss_rejects << std::endl;
- os << " crypto_handshake_successful: " << p.crypto_handshake_successful
- << " }";
- return os;
- }
-
- // This only enables the stateless reject feature via the feature-flag.
- // This should be a no-op if the peer does not support them.
- bool enable_stateless_rejects_via_flag;
- // Whether or not the client supports stateless rejects.
- bool client_supports_statelesss_rejects;
- // Should the initial crypto handshake succeed or not.
- bool crypto_handshake_successful;
-};
-
-// Constructs various test permutations for stateless rejects.
-std::vector<StatelessRejectTestParams> GetStatelessRejectTestParams() {
- std::vector<StatelessRejectTestParams> params;
- for (bool enable_stateless_rejects_via_flag : {true, false}) {
- for (bool client_supports_statelesss_rejects : {true, false}) {
- for (bool crypto_handshake_successful : {true, false}) {
- params.push_back(StatelessRejectTestParams(
- enable_stateless_rejects_via_flag,
- client_supports_statelesss_rejects, crypto_handshake_successful));
- }
- }
- }
- return params;
-}
-
-class QuicDispatcherStatelessRejectTest
- : public QuicDispatcherTest,
- public testing::WithParamInterface<StatelessRejectTestParams> {
- public:
- QuicDispatcherStatelessRejectTest()
- : QuicDispatcherTest(), crypto_stream1_(nullptr) {}
-
- ~QuicDispatcherStatelessRejectTest() override {
- if (crypto_stream1_) {
- delete crypto_stream1_;
- }
- }
-
- // This test setup assumes that all testing will be done using
- // crypto_stream1_.
- void SetUp() override {
- QuicDispatcherTest::SetUp();
- SetQuicReloadableFlag(enable_quic_stateless_reject_support,
- GetParam().enable_stateless_rejects_via_flag);
- }
-
- // Returns true or false, depending on whether the server will emit
- // a stateless reject, depending upon the parameters of the test.
- bool ExpectStatelessReject() {
- return GetParam().enable_stateless_rejects_via_flag &&
- !GetParam().crypto_handshake_successful &&
- GetParam().client_supports_statelesss_rejects;
- }
-
- // Sets up dispatcher_, session1_, and crypto_stream1_ based on
- // the test parameters.
- QuicServerSessionBase* CreateSessionBasedOnTestParams(
- QuicConnectionId connection_id,
- const QuicSocketAddress& client_address) {
- CreateSession(dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_);
-
- crypto_stream1_ = new MockQuicCryptoServerStream(
- crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- session1_, session1_->stream_helper());
- session1_->SetCryptoStream(crypto_stream1_);
- crypto_stream1_->set_handshake_confirmed_for_testing(
- GetParam().crypto_handshake_successful);
- crypto_stream1_->SetPeerSupportsStatelessRejects(
- GetParam().client_supports_statelesss_rejects);
- return session1_;
- }
-
- MockQuicCryptoServerStream* crypto_stream1_;
-};
-
-// Parameterized test for stateless rejects. Should test all
-// combinations of enabling/disabling, reject/no-reject for stateless
-// rejects.
-INSTANTIATE_TEST_CASE_P(QuicDispatcherStatelessRejectTests,
- QuicDispatcherStatelessRejectTest,
- ::testing::ValuesIn(GetStatelessRejectTestParams()));
-
-TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = 1;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(
- CreateSessionBasedOnTestParams(connection_id, client_address)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id))
- .Times(1);
-
- // Process the first packet for the connection.
- ProcessPacket(client_address, connection_id, true, SerializeCHLO());
- if (ExpectStatelessReject()) {
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
- // If this is a stateless reject, the crypto stream will close the
- // connection.
- session1_->connection()->CloseConnection(
- QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject",
- ConnectionCloseBehavior::SILENT_CLOSE);
- }
-
- // Send a second packet and check the results. If this is a stateless reject,
- // the existing connection_id will go on the time-wait list.
- EXPECT_EQ(ExpectStatelessReject(),
- time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
- if (ExpectStatelessReject()) {
- // The second packet will be processed on the time-wait list.
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id))
- .Times(1);
- } else {
- // The second packet will trigger a packet-validation
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(1)
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- }
- ProcessPacket(client_address, connection_id, true, "data");
-}
-
-TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) {
- SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = 1;
- if (GetParam().enable_stateless_rejects_via_flag) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(connection_id, client_address, _))
- .Times(0);
- } else {
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("h2")))
- .WillOnce(testing::Return(
- CreateSessionBasedOnTestParams(connection_id, client_address)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(1, packet);
- })));
- }
-
- QUIC_LOG(INFO) << "ExpectStatelessReject: " << ExpectStatelessReject();
- QUIC_LOG(INFO) << "Params: " << GetParam();
- // Process the first packet for the connection.
- CryptoHandshakeMessage client_hello =
- crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"COPT", "SREJ"},
- {"NONC", "1234567890123456789012"},
- {"ALPN", "h2"},
- {"VER\0", "Q025"}},
- kClientHelloMinimumSize);
-
- if (GetParam().enable_stateless_rejects_via_flag) {
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id))
- .Times(1);
- } else {
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id))
- .Times(1);
- }
- ProcessPacket(
- client_address, connection_id, true,
- string(
- client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece()));
-
- if (GetParam().enable_stateless_rejects_via_flag) {
- EXPECT_EQ(true,
- time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
- }
-}
-
-TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) {
- SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
- CreateTimeWaitListManager();
-
- const QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- const QuicConnectionId connection_id = 1;
-
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id))
- .Times(1);
- ProcessPacket(client_address, connection_id, true, "NOT DATA FOR A CHLO");
-
- // Process the first packet for the connection.
- CryptoHandshakeMessage client_hello =
- crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"NONC", "1234567890123456789012"},
- {"ALPN", "h3"},
- {"VER\0", "Q025"}},
- kClientHelloMinimumSize);
-
- // If stateless rejects are enabled then a connection will be created now
- // and the buffered packet will be processed
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("h3")))
- .WillOnce(testing::Return(
- CreateSessionBasedOnTestParams(connection_id, client_address)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, client_address, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- // Expect both packets to be passed to ProcessUdpPacket(). And one of them
- // is already expected in CreateSessionBasedOnTestParams().
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, client_address, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })))
- .RetiresOnSaturation();
- ProcessPacket(
- client_address, connection_id, true,
- string(
- client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece()));
- EXPECT_FALSE(
- time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
-}
-
-// Verify the stopgap test: Packets with truncated connection IDs should be
-// dropped.
-class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {};
-
-// Packets with truncated connection IDs should be dropped.
-TEST_F(QuicDispatcherTestStrayPacketConnectionId,
- StrayPacketTruncatedConnectionId) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = 1;
- // Dispatcher drops this packet.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq")))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(_, _, _, _, _))
- .Times(0);
- ProcessPacket(client_address, connection_id, true, "data",
- PACKET_0BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER);
-}
-
-class BlockingWriter : public QuicPacketWriterWrapper {
- public:
- BlockingWriter() : write_blocked_(false) {}
-
- bool IsWriteBlocked() const override { return write_blocked_; }
- void SetWritable() override { write_blocked_ = false; }
-
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_client_address,
- const QuicSocketAddress& peer_client_address,
- PerPacketOptions* options) override {
- // It would be quite possible to actually implement this method here with
- // the fake blocked status, but it would be significantly more work in
- // Chromium, and since it's not called anyway, don't bother.
- QUIC_LOG(DFATAL) << "Not supported";
- return WriteResult();
- }
-
- bool write_blocked_;
-};
-
-class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest {
- public:
- void SetUp() override {
- QuicDispatcherTest::SetUp();
- writer_ = new BlockingWriter;
- QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(_, client_address, QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, 1, client_address, &helper_,
- &alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(1, packet);
- })));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(1));
- ProcessPacket(client_address, 1, true, SerializeCHLO());
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(_, client_address, QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, 2, client_address, &helper_,
- &alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(2, packet);
- })));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(2));
- ProcessPacket(client_address, 2, true, SerializeCHLO());
-
- blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
- }
-
- void TearDown() override {
- EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
- dispatcher_->Shutdown();
- }
-
- void SetBlocked() { writer_->write_blocked_ = true; }
-
- void BlockConnection2() {
- writer_->write_blocked_ = true;
- dispatcher_->OnWriteBlocked(connection2());
- }
-
- protected:
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- BlockingWriter* writer_;
- QuicDispatcher::WriteBlockedList* blocked_list_;
-};
-
-TEST_F(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
- // No OnCanWrite calls because no connections are blocked.
- dispatcher_->OnCanWrite();
-
- // Register connection 1 for events, and make sure it's notified.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite());
- dispatcher_->OnCanWrite();
-
- // It should get only one notification.
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
- EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
- // Make sure we handle events in order.
- InSequence s;
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite());
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
-
- // Check the other ordering.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection2());
- dispatcher_->OnWriteBlocked(connection1());
- EXPECT_CALL(*connection2(), OnCanWrite());
- EXPECT_CALL(*connection1(), OnCanWrite());
- dispatcher_->OnCanWrite();
-}
-
-TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
- // Add and remove one connction.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- blocked_list_->erase(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
-
- // Add and remove one connction and make sure it doesn't affect others.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- blocked_list_->erase(connection1());
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
-
- // Add it, remove it, and add it back and make sure things are OK.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- blocked_list_->erase(connection1());
- dispatcher_->OnWriteBlocked(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
- dispatcher_->OnCanWrite();
-}
-
-TEST_F(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
- // Make sure a double add does not necessitate a double remove.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection1());
- blocked_list_->erase(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
-
- // Make sure a double add does not result in two OnCanWrite calls.
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection1());
- EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
- dispatcher_->OnCanWrite();
-}
-
-TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlock) {
- // Finally make sure if we write block on a write call, we stop calling.
- InSequence s;
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite())
- .WillOnce(Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked));
- EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
-
- // And we'll resume where we left off when we get another call.
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
-}
-
-TEST_F(QuicDispatcherWriteBlockedListTest, LimitedWrites) {
- // Make sure we call both writers. The first will register for more writing
- // but should not be immediately called due to limits.
- InSequence s;
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite());
- EXPECT_CALL(*connection2(), OnCanWrite())
- .WillOnce(
- Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
- dispatcher_->OnCanWrite();
- EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
- // Now call OnCanWrite again, and connection1 should get its second chance
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
- EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_F(QuicDispatcherWriteBlockedListTest, TestWriteLimits) {
- // Finally make sure if we write block on a write call, we stop calling.
- InSequence s;
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- dispatcher_->OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite())
- .WillOnce(Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked));
- EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
- dispatcher_->OnCanWrite();
- EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
- // And we'll resume where we left off when we get another call.
- EXPECT_CALL(*connection2(), OnCanWrite());
- dispatcher_->OnCanWrite();
- EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-// Tests that bufferring packets works in stateful reject, expensive stateless
-// reject and cheap stateless reject.
-struct BufferedPacketStoreTestParams {
- BufferedPacketStoreTestParams(bool enable_stateless_rejects_via_flag,
- bool support_cheap_stateless_reject)
- : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag),
- support_cheap_stateless_reject(support_cheap_stateless_reject) {}
-
- friend std::ostream& operator<<(std::ostream& os,
- const BufferedPacketStoreTestParams& p) {
- os << "{ enable_stateless_rejects_via_flag: "
- << p.enable_stateless_rejects_via_flag << std::endl;
- os << " support_cheap_stateless_reject: "
- << p.support_cheap_stateless_reject << " }";
- return os;
- }
-
- // This only enables the stateless reject feature via the feature-flag.
- // This should be a no-op if the peer does not support them.
- bool enable_stateless_rejects_via_flag;
- // Whether to do cheap stateless or not.
- bool support_cheap_stateless_reject;
-};
-
-std::vector<BufferedPacketStoreTestParams> GetBufferedPacketStoreTestParams() {
- std::vector<BufferedPacketStoreTestParams> params;
- for (bool enable_stateless_rejects_via_flag : {true, false}) {
- for (bool support_cheap_stateless_reject : {true, false}) {
- params.push_back(BufferedPacketStoreTestParams(
- enable_stateless_rejects_via_flag, support_cheap_stateless_reject));
- }
- }
- return params;
-}
-
-// A dispatcher whose stateless rejector will always ACCEPTs CHLO.
-class BufferedPacketStoreTest
- : public QuicDispatcherTest,
- public testing::WithParamInterface<BufferedPacketStoreTestParams> {
- public:
- BufferedPacketStoreTest()
- : QuicDispatcherTest(),
- client_addr_(QuicIpAddress::Loopback4(), 1234),
- signed_config_(new QuicSignedServerConfig) {
- SetQuicReloadableFlag(quic_use_cheap_stateless_rejects,
- GetParam().support_cheap_stateless_reject);
- SetQuicReloadableFlag(enable_quic_stateless_reject_support,
- GetParam().enable_stateless_rejects_via_flag);
- }
-
- void SetUp() override {
- QuicDispatcherTest::SetUp();
- clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock();
-
- QuicTransportVersion version = AllSupportedTransportVersions().front();
- CryptoHandshakeMessage chlo =
- crypto_test_utils::GenerateDefaultInchoateCHLO(clock_, version,
- &crypto_config_);
- chlo.SetVector(net::kCOPT, net::QuicTagVector{net::kSREJ});
- // Pass an inchoate CHLO.
- crypto_test_utils::GenerateFullCHLO(
- chlo, &crypto_config_, server_addr_, client_addr_, version, clock_,
- signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &full_chlo_);
- }
-
- QuicString SerializeFullCHLO() {
- return string(
- full_chlo_.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
- }
-
- protected:
- QuicSocketAddress server_addr_;
- QuicSocketAddress client_addr_;
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
- const QuicClock* clock_;
- CryptoHandshakeMessage full_chlo_;
-};
-
-INSTANTIATE_TEST_CASE_P(
- BufferedPacketStoreTests,
- BufferedPacketStoreTest,
- ::testing::ValuesIn(GetBufferedPacketStoreTestParams()));
-
-TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
- InSequence s;
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
- QuicConnectionId conn_id = 1;
- // A bunch of non-CHLO should be buffered upon arrival, and the first one
- // should trigger ShouldCreateOrBufferPacketForConnection().
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id))
- .Times(1);
- for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
- ProcessPacket(client_address, conn_id, true,
- QuicStrCat("data packet ", i + 1), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, /*packet_number=*/i + 1);
- }
- EXPECT_EQ(0u, dispatcher_->session_map().size())
- << "No session should be created before CHLO arrives.";
-
- // Pop out the last packet as it is also be dropped by the store.
- data_connection_map_[conn_id].pop_back();
- // When CHLO arrives, a new session should be created, and all packets
- // buffered should be delivered to the session.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_address, QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
-
- // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
- // should be delivered in arrival order.
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
- .WillOnce(
- WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
-}
-
-TEST_P(BufferedPacketStoreTest,
- ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
- InSequence s;
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
- // A bunch of non-CHLO should be buffered upon arrival.
- size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
- for (size_t i = 1; i <= kNumConnections; ++i) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
- QuicConnectionId conn_id = i;
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
- ProcessPacket(client_address, conn_id, true,
- QuicStrCat("data packet on connection ", i),
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
- /*packet_number=*/2);
- }
-
- // Pop out the packet on last connection as it shouldn't be enqueued in store
- // as well.
- data_connection_map_[kNumConnections].pop_front();
-
- // Reset session creation counter to ensure processing CHLO can always
- // create session.
- QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
- kNumConnections);
- // Process CHLOs to create session for these connections.
- for (size_t i = 1; i <= kNumConnections; ++i) {
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
- QuicConnectionId conn_id = i;
- if (conn_id == kNumConnections) {
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id));
- }
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_address, QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- // First |kNumConnections| - 1 connections should have buffered
- // a packet in store. The rest should have been dropped.
- size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, client_address, _))
- .Times(num_packet_to_process)
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
-
- ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
- }
-}
-
-// Tests that store delivers empty packet list if CHLO arrives firstly.
-TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
- QuicConnectionId conn_id = 1;
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_address, QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
-}
-
-// Tests that a retransmitted CHLO arrives after a connection for the
-// CHLO has been created.
-TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
- InSequence s;
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
- QuicConnectionId conn_id = 1;
- ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
- /*packet_number=*/2);
-
- // When CHLO arrives, a new session should be created, and all packets
- // buffered should be delivered to the session.
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_address, QuicStringPiece()))
- .Times(1) // Only triggered by 1st CHLO.
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(3) // Triggered by 1 data packet and 2 CHLOs.
- .WillOnce(
- WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
-
- ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
-}
-
-// Tests that expiration of a connection add connection id to time wait list.
-TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
- InSequence s;
- CreateTimeWaitListManager();
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
- QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
- QuicConnectionId conn_id = 1;
- ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
- /*packet_number=*/2);
-
- mock_helper_.AdvanceTime(
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
- QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
- // Cancel alarm as if it had been fired.
- alarm->Cancel();
- store->OnExpirationTimeout();
- // New arrived CHLO will be dropped because this connection is in time wait
- // list.
- ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
- EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id));
- ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
-}
-
-TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
- // Process more than (|kMaxNumSessionsToCreate| +
- // |kDefaultMaxConnectionsInStore|) CHLOs,
- // the first |kMaxNumSessionsToCreate| should create connections immediately,
- // the next |kDefaultMaxConnectionsInStore| should be buffered,
- // the rest should be dropped.
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
- const size_t kNumCHLOs =
- kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
- for (size_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
- if (conn_id <= kMaxNumSessionsToCreate) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_addr_, QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
- conn_id > kMaxNumSessionsToCreate) {
- EXPECT_TRUE(store->HasChloForConnection(conn_id));
- } else {
- // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
- // connections immediately, and the last CHLO should be dropped as the
- // store is full.
- EXPECT_FALSE(store->HasChloForConnection(conn_id));
- }
- }
-
- // Graduately consume buffered CHLOs. The buffered connections should be
- // created but the dropped one shouldn't.
- for (size_t conn_id = kMaxNumSessionsToCreate + 1;
- conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
- ++conn_id) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_addr_, QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(kNumCHLOs, client_addr_, QuicStringPiece()))
- .Times(0);
-
- while (store->HasChlosBuffered()) {
- dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
- }
-
- EXPECT_EQ(static_cast<size_t>(kMaxNumSessionsToCreate) +
- kDefaultMaxConnectionsInStore,
- session1_->connection_id());
-}
-
-// Duplicated CHLO shouldn't be buffered.
-TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
- for (QuicConnectionId conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
- ++conn_id) {
- // Last CHLO will be buffered. Others will create connection right away.
- if (conn_id <= kMaxNumSessionsToCreate) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_addr_, QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- }
- // Retransmit CHLO on last connection should be dropped.
- QuicConnectionId last_connection = kMaxNumSessionsToCreate + 1;
- ProcessPacket(client_addr_, last_connection, true, SerializeFullCHLO());
-
- size_t packets_buffered = 2;
-
- // Reset counter and process buffered CHLO.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_,
- QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, last_connection, client_addr_,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- // Only one packet(CHLO) should be process.
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(packets_buffered)
- .WillOnce(WithArg<2>(
- Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
- ValidatePacket(last_connection, packet);
- })));
- dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-}
-
-TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
- QuicConnectionId last_connection_id = kMaxNumSessionsToCreate + 1;
- for (QuicConnectionId conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
- // Last CHLO will be buffered. Others will create connection right away.
- if (conn_id <= kMaxNumSessionsToCreate) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_addr_, QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- }
-
- // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
- // last one should be dropped.
- for (QuicPacketNumber packet_number = 2;
- packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
- ProcessPacket(client_addr_, last_connection_id, true, "data packet");
- }
-
- // Reset counter and process buffered CHLO.
- EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_,
- QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, last_connection_id, client_addr_,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
- // should be process.
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(kDefaultMaxUndecryptablePackets + 1)
- .WillOnce(WithArg<2>(
- Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(last_connection_id, packet);
- })));
- dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-}
-
-// Tests that when dispatcher's packet buffer is full, a CHLO on connection
-// which doesn't have buffered CHLO should be buffered.
-TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
- QuicConnectionId conn_id = 1;
- ProcessPacket(client_addr_, conn_id, true, "data packet",
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
- /*packet_number=*/1);
- // Fill packet buffer to full with CHLOs on other connections. Need to feed
- // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
- // session directly.
- for (conn_id = 2;
- conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
- ++conn_id) {
- if (conn_id <= kMaxNumSessionsToCreate + 1) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_addr_, QuicStringPiece()))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
- &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- }
- EXPECT_FALSE(store->HasChloForConnection(/*connection_id=*/1));
-
- // CHLO on connection 1 should still be buffered.
- ProcessPacket(client_addr_, /*connection_id=*/1, true, SerializeFullCHLO());
- EXPECT_TRUE(store->HasChloForConnection(/*connection_id=*/1));
-}
-
-// Test which exercises the async GetProof codepaths, especially in the context
-// of stateless rejection.
-class AsyncGetProofTest : public QuicDispatcherTest {
- public:
- AsyncGetProofTest()
- : QuicDispatcherTest(
- std::unique_ptr<FakeProofSource>(new FakeProofSource())),
- client_addr_(QuicIpAddress::Loopback4(), 1234),
- client_addr_2_(QuicIpAddress::Loopback4(), 1357),
- crypto_config_peer_(&crypto_config_),
- signed_config_(new QuicSignedServerConfig) {
- SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
- SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
- }
-
- void SetUp() override {
- QuicDispatcherTest::SetUp();
-
- clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock();
- QuicTransportVersion version = AllSupportedTransportVersions().front();
- chlo_ = crypto_test_utils::GenerateDefaultInchoateCHLO(clock_, version,
- &crypto_config_);
- chlo_.SetVector(net::kCOPT, net::QuicTagVector{net::kSREJ});
- chlo_.SetStringPiece(kALPN, "HTTP/1");
- // Pass an inchoate CHLO.
- crypto_test_utils::GenerateFullCHLO(
- chlo_, &crypto_config_, server_addr_, client_addr_, version, clock_,
- signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &full_chlo_);
-
- crypto_test_utils::GenerateFullCHLO(
- chlo_, &crypto_config_, server_addr_, client_addr_2_, version, clock_,
- signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &full_chlo_2_);
-
- GetFakeProofSource()->Activate();
- }
-
- FakeProofSource* GetFakeProofSource() const {
- return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
- }
-
- QuicString SerializeFullCHLO() {
- return QuicString(
- full_chlo_.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
- }
-
- QuicString SerializeFullCHLOForClient2() {
- return QuicString(
- full_chlo_2_.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
- }
-
- QuicString SerializeCHLO() {
- return string(chlo_.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
- }
-
- // Sets up a session, and crypto stream based on the test parameters.
- QuicServerSessionBase* GetSession(QuicConnectionId connection_id,
- QuicSocketAddress client_address) {
- auto it = sessions_.find(connection_id);
- if (it != sessions_.end()) {
- return it->second.session;
- }
-
- TestQuicSpdyServerSession* session;
- CreateSession(dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session);
-
- std::unique_ptr<MockQuicCryptoServerStream> crypto_stream(
- new MockQuicCryptoServerStream(
- crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- session, session->stream_helper()));
- session->SetCryptoStream(crypto_stream.get());
- crypto_stream->SetPeerSupportsStatelessRejects(true);
- const bool ok =
- sessions_
- .insert(std::make_pair(
- connection_id, SessionInfo{session, std::move(crypto_stream)}))
- .second;
- CHECK(ok);
- return session;
- }
-
- protected:
- const QuicSocketAddress client_addr_;
- const QuicSocketAddress client_addr_2_;
-
- private:
- QuicCryptoServerConfigPeer crypto_config_peer_;
- QuicSocketAddress server_addr_;
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
- const QuicClock* clock_;
- CryptoHandshakeMessage chlo_;
- CryptoHandshakeMessage full_chlo_; // CHLO for client_addr_
- CryptoHandshakeMessage full_chlo_2_; // CHLO for client_addr_2_
-
- struct SessionInfo {
- TestQuicSpdyServerSession* session;
- std::unique_ptr<MockQuicCryptoServerStream> crypto_stream;
- };
- std::map<QuicConnectionId, SessionInfo> sessions_;
-};
-
-// Test a simple situation of connections which the StatelessRejector will
-// accept.
-TEST_F(AsyncGetProofTest, BasicAccept) {
- QuicConnectionId conn_id = 1;
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
-
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
- QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- check.Call(1);
- // Complete the ProofSource::GetProof call and verify that a session is
- // created.
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-
- check.Call(2);
- // Verify that a data packet gets processed immediately.
- ProcessPacket(client_addr_, conn_id, true, "My name is Data");
-}
-
-TEST_F(AsyncGetProofTest, RestorePacketContext) {
- QuicConnectionId conn_id_1 = 1;
- QuicConnectionId conn_id_2 = 2;
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_1));
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
- QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_1, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillRepeatedly(WithArg<2>(
- Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_1, packet);
- })));
-
- EXPECT_CALL(check, Call(2));
-
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_2));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_2_,
- QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_2_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_2, client_addr_2_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_2, packet);
- })));
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Send another CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_2_, conn_id_2, true, SerializeFullCHLOForClient2());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the first ProofSource::GetProof call and verify that a session is
- // created.
- check.Call(1);
-
- EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
- EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
-
- // Runs the async proof callback for conn_id_1 from client_addr_.
- GetFakeProofSource()->InvokePendingCallback(0);
-
- EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
- EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
-
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Complete the second ProofSource::GetProof call and verify that a session is
- // created.
- check.Call(2);
-
- EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
- EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
-
- // Runs the async proof callback for conn_id_2 from client_addr_2_.
- GetFakeProofSource()->InvokePendingCallback(0);
-
- EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
- EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
-
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-}
-
-// Test a simple situation of connections which the StatelessRejector will
-// reject.
-TEST_F(AsyncGetProofTest, BasicReject) {
- CreateTimeWaitListManager();
-
- QuicConnectionId conn_id = 1;
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id, _, _, true, _));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_addr_, QuicStringPiece("hq")))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id));
- }
-
- // Send a CHLO that the StatelessRejector will reject.
- ProcessPacket(client_addr_, conn_id, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Complete the ProofSource::GetProof call and verify that the connection and
- // packet are processed by the time wait list manager.
- check.Call(1);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-
- // Verify that a data packet is passed to the time wait list manager.
- check.Call(2);
- ProcessPacket(client_addr_, conn_id, true, "My name is Data");
-}
-
-// Test a situation with multiple interleaved connections which the
-// StatelessRejector will accept.
-TEST_F(AsyncGetProofTest, MultipleAccept) {
- QuicConnectionId conn_id_1 = 1;
- QuicConnectionId conn_id_2 = 2;
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_2));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_,
- QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_2, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_2, packet);
- })));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_2, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_2, packet);
- })));
-
- EXPECT_CALL(check, Call(3));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_1));
-
- EXPECT_CALL(check, Call(4));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
- QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_1, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillRepeatedly(WithArg<2>(
- Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_1, packet);
- })));
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Send another CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id_2, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the second ProofSource::GetProof call and verify that a session is
- // created.
- check.Call(1);
- GetFakeProofSource()->InvokePendingCallback(1);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Verify that a data packet on that connection gets processed immediately.
- check.Call(2);
- ProcessPacket(client_addr_, conn_id_2, true, "My name is Data");
-
- // Verify that a data packet on the other connection does not get processed
- // yet.
- check.Call(3);
- ProcessPacket(client_addr_, conn_id_1, true, "My name is Data");
- EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
-
- // Complete the first ProofSource::GetProof call and verify that a session is
- // created and the buffered packet is processed.
- check.Call(4);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-}
-
-// Test a situation with multiple interleaved connections which the
-// StatelessRejector will reject.
-TEST_F(AsyncGetProofTest, MultipleReject) {
- CreateTimeWaitListManager();
-
- QuicConnectionId conn_id_1 = 1;
- QuicConnectionId conn_id_2 = 2;
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
-
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_2, _, _, true, _));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id_2));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id_2));
-
- EXPECT_CALL(check, Call(3));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_1));
-
- EXPECT_CALL(check, Call(4));
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_1, _, _, true, _));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id_1));
- }
-
- // Send a CHLO that the StatelessRejector will reject.
- ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Send another CHLO that the StatelessRejector will reject.
- ProcessPacket(client_addr_, conn_id_2, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the second ProofSource::GetProof call and verify that the
- // connection and packet are processed by the time wait manager.
- check.Call(1);
- GetFakeProofSource()->InvokePendingCallback(1);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Verify that a data packet on that connection gets processed immediately by
- // the time wait manager.
- check.Call(2);
- ProcessPacket(client_addr_, conn_id_2, true, "My name is Data");
-
- // Verify that a data packet on the first connection gets buffered.
- check.Call(3);
- ProcessPacket(client_addr_, conn_id_1, true, "My name is Data");
- EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
-
- // Complete the first ProofSource::GetProof call and verify that the CHLO is
- // processed by the time wait manager and the remaining packets are discarded.
- check.Call(4);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
-}
-
-// Test a situation with multiple identical CHLOs which the StatelessRejector
-// will reject.
-TEST_F(AsyncGetProofTest, MultipleIdenticalReject) {
- CreateTimeWaitListManager();
-
- QuicConnectionId conn_id_1 = 1;
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_1));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id_1, client_addr_, QuicStringPiece()))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_1, _, _, true, _));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id_1));
- }
-
- // Send a CHLO that the StatelessRejector will reject.
- ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
-
- // Send an identical CHLO which should get buffered.
- check.Call(1);
- ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
- EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
-
- // Complete the ProofSource::GetProof call and verify that the CHLO is
- // rejected and the copy is discarded.
- check.Call(2);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
-}
-
-// Test dispatcher behavior when packets time out of the buffer while CHLO
-// validation is still pending.
-TEST_F(AsyncGetProofTest, BufferTimeout) {
- CreateTimeWaitListManager();
-
- QuicConnectionId conn_id = 1;
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
- QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id));
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_addr_, QuicStringPiece()))
- .Times(0);
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
-
- // Send a data packet that will get buffered
- check.Call(1);
- ProcessPacket(client_addr_, conn_id, true, "My name is Data");
- EXPECT_TRUE(store->HasBufferedPackets(conn_id));
-
- // Pretend that enough time has gone by for the packets to get expired out of
- // the buffer
- mock_helper_.AdvanceTime(
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
- QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel();
- store->OnExpirationTimeout();
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
- EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-
- // Now allow the CHLO validation to complete, and verify that no connection
- // gets created.
- check.Call(2);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
- EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-}
-
-// Test behavior when packets time out of the buffer *and* the connection times
-// out of the time wait manager while CHLO validation is still pending. This
-// *should* be impossible, but anything can happen with timing conditions.
-TEST_F(AsyncGetProofTest, TimeWaitTimeout) {
- QuicConnectionId conn_id = 1;
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
- QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
- CreateTimeWaitListManager();
- QuicTimeWaitListManagerPeer::set_clock(time_wait_list_manager_,
- mock_helper_.GetClock());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
- QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
-
- // Send a data packet that will get buffered
- check.Call(1);
- ProcessPacket(client_addr_, conn_id, true, "My name is Data");
- EXPECT_TRUE(store->HasBufferedPackets(conn_id));
-
- // Pretend that enough time has gone by for the packets to get expired out of
- // the buffer
- mock_helper_.AdvanceTime(
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
- QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel();
- store->OnExpirationTimeout();
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
- EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-
- // Pretend that enough time has gone by for the connection ID to be removed
- // from the time wait manager
- mock_helper_.AdvanceTime(
- QuicTimeWaitListManagerPeer::time_wait_period(time_wait_list_manager_));
- QuicTimeWaitListManagerPeer::expiration_alarm(time_wait_list_manager_)
- ->Cancel();
- time_wait_list_manager_->CleanUpOldConnectionIds();
- EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-
- // Now allow the CHLO validation to complete. Expect that a connection is
- // indeed created, since QUIC has forgotten that this connection ever existed.
- // This is a miniscule corner case which should never happen in the wild, so
- // really we are just verifying that the dispatcher does not explode in this
- // situation.
- check.Call(2);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
- EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-}
-
-// Regression test for
-// https://bugs.chromium.org/p/chromium/issues/detail?id=748289
-TEST_F(AsyncGetProofTest, DispatcherFailedToPickUpVersionForAsyncProof) {
- // This test mimics the scenario that dispatcher's framer can have different
- // version when async proof returns.
- // When dispatcher sends SREJ, the SREJ frame can be serialized in
- // different endianness which causes the client to close the connection
- // because of QUIC_INVALID_STREAM_DATA.
-
- // Send a CHLO with v39. Dispatcher framer's version is set to v39.
- ProcessPacket(client_addr_, 1, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Send another CHLO with v35. Dispatcher framer's version is set to v35.
- ProcessPacket(client_addr_, 2, true,
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_35),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, 1);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the ProofSource::GetProof call for v39. This would cause the
- // version mismatch between the CHLO packet and the dispatcher.
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_epoll_alarm_factory.cc b/chromium/net/tools/quic/quic_epoll_alarm_factory.cc
deleted file mode 100644
index deb95597459..00000000000
--- a/chromium/net/tools/quic/quic_epoll_alarm_factory.cc
+++ /dev/null
@@ -1,76 +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/tools/quic/quic_epoll_alarm_factory.h"
-
-#include "net/tools/epoll_server/epoll_server.h"
-
-namespace net {
-
-namespace {
-
-class QuicEpollAlarm : public QuicAlarm {
- public:
- QuicEpollAlarm(EpollServer* epoll_server,
- QuicArenaScopedPtr<Delegate> delegate)
- : QuicAlarm(std::move(delegate)),
- epoll_server_(epoll_server),
- epoll_alarm_impl_(this) {}
-
- protected:
- void SetImpl() override {
- DCHECK(deadline().IsInitialized());
- epoll_server_->RegisterAlarm(
- (deadline() - QuicTime::Zero()).ToMicroseconds(), &epoll_alarm_impl_);
- }
-
- void CancelImpl() override {
- DCHECK(!deadline().IsInitialized());
- epoll_alarm_impl_.UnregisterIfRegistered();
- }
-
- private:
- class EpollAlarmImpl : public EpollAlarm {
- public:
- explicit EpollAlarmImpl(QuicEpollAlarm* alarm) : alarm_(alarm) {}
-
- int64_t OnAlarm() override {
- EpollAlarm::OnAlarm();
- alarm_->Fire();
- // Fire will take care of registering the alarm, if needed.
- return 0;
- }
-
- private:
- QuicEpollAlarm* alarm_;
- };
-
- EpollServer* epoll_server_;
- EpollAlarmImpl epoll_alarm_impl_;
-};
-
-} // namespace
-
-QuicEpollAlarmFactory::QuicEpollAlarmFactory(EpollServer* epoll_server)
- : epoll_server_(epoll_server) {}
-
-QuicEpollAlarmFactory::~QuicEpollAlarmFactory() = default;
-
-QuicAlarm* QuicEpollAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
- return new QuicEpollAlarm(epoll_server_,
- QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-}
-
-QuicArenaScopedPtr<QuicAlarm> QuicEpollAlarmFactory::CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) {
- if (arena != nullptr) {
- return arena->New<QuicEpollAlarm>(epoll_server_, std::move(delegate));
- } else {
- return QuicArenaScopedPtr<QuicAlarm>(
- new QuicEpollAlarm(epoll_server_, std::move(delegate)));
- }
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_epoll_alarm_factory.h b/chromium/net/tools/quic/quic_epoll_alarm_factory.h
deleted file mode 100644
index 9c47f56dc7b..00000000000
--- a/chromium/net/tools/quic/quic_epoll_alarm_factory.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2015 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_TOOLS_QUIC_QUIC_EPOLL_ALARM_FACTORY_H_
-#define NET_TOOLS_QUIC_QUIC_EPOLL_ALARM_FACTORY_H_
-
-#include "net/quic/core/quic_alarm.h"
-#include "net/quic/core/quic_alarm_factory.h"
-
-namespace net {
-
-class EpollServer;
-
-// Creates alarms that use the supplied EpollServer for timing and firing.
-class QuicEpollAlarmFactory : public QuicAlarmFactory {
- public:
- explicit QuicEpollAlarmFactory(EpollServer* epoll_server);
- ~QuicEpollAlarmFactory() override;
-
- // QuicAlarmFactory interface.
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override;
-
- private:
- EpollServer* epoll_server_; // Not owned.
-
- DISALLOW_COPY_AND_ASSIGN(QuicEpollAlarmFactory);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_EPOLL_ALARM_FACTORY_H_
diff --git a/chromium/net/tools/quic/quic_epoll_alarm_factory_test.cc b/chromium/net/tools/quic/quic_epoll_alarm_factory_test.cc
deleted file mode 100644
index 2e0f743a4a6..00000000000
--- a/chromium/net/tools/quic/quic_epoll_alarm_factory_test.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2015 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/tools/quic/quic_epoll_alarm_factory.h"
-
-#include "net/quic/platform/api/quic_test.h"
-#include "net/tools/quic/platform/impl/quic_epoll_clock.h"
-#include "net/tools/quic/test_tools/mock_epoll_server.h"
-
-namespace net {
-namespace test {
-namespace {
-
-class TestDelegate : public QuicAlarm::Delegate {
- public:
- TestDelegate() : fired_(false) {}
-
- void OnAlarm() override { fired_ = true; }
-
- bool fired() const { return fired_; }
-
- private:
- bool fired_;
-};
-
-// The boolean parameter denotes whether or not to use an arena.
-class QuicEpollAlarmFactoryTest : public QuicTestWithParam<bool> {
- protected:
- QuicEpollAlarmFactoryTest()
- : clock_(&epoll_server_), alarm_factory_(&epoll_server_) {}
-
- QuicConnectionArena* GetArenaParam() {
- return GetParam() ? &arena_ : nullptr;
- }
-
- const QuicEpollClock clock_;
- QuicEpollAlarmFactory alarm_factory_;
- test::MockEpollServer epoll_server_;
- QuicConnectionArena arena_;
-};
-
-INSTANTIATE_TEST_CASE_P(UseArena,
- QuicEpollAlarmFactoryTest,
- ::testing::ValuesIn({true, false}));
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarm) {
- QuicArenaScopedPtr<TestDelegate> delegate =
- QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
- QuicArenaScopedPtr<QuicAlarm> alarm(
- alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
- QuicTime start = clock_.Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(start + delta);
-
- epoll_server_.AdvanceByAndWaitForEventsAndExecuteCallbacks(
- delta.ToMicroseconds());
- EXPECT_EQ(start + delta, clock_.Now());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndCancel) {
- QuicArenaScopedPtr<TestDelegate> delegate =
- QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
- TestDelegate* unowned_delegate = delegate.get();
- QuicArenaScopedPtr<QuicAlarm> alarm(
- alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
- QuicTime start = clock_.Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(start + delta);
- alarm->Cancel();
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
- EXPECT_EQ(start + delta, clock_.Now());
- EXPECT_FALSE(unowned_delegate->fired());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndReset) {
- QuicArenaScopedPtr<TestDelegate> delegate =
- QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
- TestDelegate* unowned_delegate = delegate.get();
- QuicArenaScopedPtr<QuicAlarm> alarm(
- alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
- QuicTime start = clock_.Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock_.Now() + delta);
- alarm->Cancel();
- QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
- alarm->Set(clock_.Now() + new_delta);
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
- EXPECT_EQ(start + delta, clock_.Now());
- EXPECT_FALSE(unowned_delegate->fired());
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(
- (new_delta - delta).ToMicroseconds());
- EXPECT_EQ(start + new_delta, clock_.Now());
- EXPECT_TRUE(unowned_delegate->fired());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndUpdate) {
- QuicArenaScopedPtr<TestDelegate> delegate =
- QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
- TestDelegate* unowned_delegate = delegate.get();
- QuicArenaScopedPtr<QuicAlarm> alarm(
- alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
- QuicTime start = clock_.Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock_.Now() + delta);
- QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
- alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
- EXPECT_EQ(start + delta, clock_.Now());
- EXPECT_FALSE(unowned_delegate->fired());
-
- // Move the alarm forward 1us and ensure it doesn't move forward.
- alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(2));
-
- epoll_server_.AdvanceByExactlyAndCallCallbacks(
- (new_delta - delta).ToMicroseconds());
- EXPECT_EQ(start + new_delta, clock_.Now());
- EXPECT_TRUE(unowned_delegate->fired());
-
- // Set the alarm via an update call.
- new_delta = QuicTime::Delta::FromMicroseconds(5);
- alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
- EXPECT_TRUE(alarm->IsSet());
-
- // Update it with an uninitialized time and ensure it's cancelled.
- alarm->Update(QuicTime::Zero(), QuicTime::Delta::FromMicroseconds(1));
- EXPECT_FALSE(alarm->IsSet());
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_epoll_connection_helper.cc b/chromium/net/tools/quic/quic_epoll_connection_helper.cc
deleted file mode 100644
index 2c7f9537b77..00000000000
--- a/chromium/net/tools/quic/quic_epoll_connection_helper.cc
+++ /dev/null
@@ -1,41 +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/tools/quic/quic_epoll_connection_helper.h"
-
-#include <errno.h>
-#include <sys/socket.h>
-
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-
-namespace net {
-
-QuicEpollConnectionHelper::QuicEpollConnectionHelper(EpollServer* epoll_server,
- QuicAllocator type)
- : clock_(epoll_server),
- random_generator_(QuicRandom::GetInstance()),
- allocator_type_(type) {}
-
-QuicEpollConnectionHelper::~QuicEpollConnectionHelper() = default;
-
-const QuicClock* QuicEpollConnectionHelper::GetClock() const {
- return &clock_;
-}
-
-QuicRandom* QuicEpollConnectionHelper::GetRandomGenerator() {
- return random_generator_;
-}
-
-QuicBufferAllocator* QuicEpollConnectionHelper::GetStreamSendBufferAllocator() {
- if (allocator_type_ == QuicAllocator::BUFFER_POOL) {
- return &stream_buffer_allocator_;
- } else {
- DCHECK(allocator_type_ == QuicAllocator::SIMPLE);
- return &simple_buffer_allocator_;
- }
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_epoll_connection_helper.h b/chromium/net/tools/quic/quic_epoll_connection_helper.h
deleted file mode 100644
index 90545689f22..00000000000
--- a/chromium/net/tools/quic/quic_epoll_connection_helper.h
+++ /dev/null
@@ -1,58 +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.
-//
-// The Google-specific helper for QuicConnection which uses
-// EpollAlarm for alarms, and used an int fd_ for writing data.
-
-#ifndef NET_TOOLS_QUIC_QUIC_EPOLL_CONNECTION_HELPER_H_
-#define NET_TOOLS_QUIC_QUIC_EPOLL_CONNECTION_HELPER_H_
-
-#include <sys/types.h>
-#include <set>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_packet_writer.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_simple_buffer_allocator.h"
-#include "net/quic/core/quic_time.h"
-#include "net/tools/quic/platform/impl/quic_epoll_clock.h"
-#include "net/tools/quic/quic_default_packet_writer.h"
-
-namespace net {
-
-class EpollServer;
-class QuicRandom;
-
-using QuicStreamBufferAllocator = SimpleBufferAllocator;
-
-enum class QuicAllocator { SIMPLE, BUFFER_POOL };
-
-class QuicEpollConnectionHelper : public QuicConnectionHelperInterface {
- public:
- QuicEpollConnectionHelper(EpollServer* eps, QuicAllocator allocator);
- ~QuicEpollConnectionHelper() override;
-
- // QuicEpollConnectionHelperInterface
- const QuicClock* GetClock() const override;
- QuicRandom* GetRandomGenerator() override;
- QuicBufferAllocator* GetStreamSendBufferAllocator() override;
-
- private:
- friend class QuicConnectionPeer;
-
- const QuicEpollClock clock_;
- QuicRandom* random_generator_;
- // Set up allocators. They take up minimal memory before use.
- // Allocator for stream send buffers.
- QuicStreamBufferAllocator stream_buffer_allocator_;
- SimpleBufferAllocator simple_buffer_allocator_;
- QuicAllocator allocator_type_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicEpollConnectionHelper);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_EPOLL_CONNECTION_HELPER_H_
diff --git a/chromium/net/tools/quic/quic_epoll_connection_helper_test.cc b/chromium/net/tools/quic/quic_epoll_connection_helper_test.cc
deleted file mode 100644
index c31dcebcb09..00000000000
--- a/chromium/net/tools/quic/quic_epoll_connection_helper_test.cc
+++ /dev/null
@@ -1,41 +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/tools/quic/quic_epoll_connection_helper.h"
-
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/tools/quic/test_tools/mock_epoll_server.h"
-
-namespace net {
-namespace test {
-namespace {
-
-class QuicEpollConnectionHelperTest : public QuicTest {
- protected:
- QuicEpollConnectionHelperTest()
- : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL) {}
-
- MockEpollServer epoll_server_;
- QuicEpollConnectionHelper helper_;
-};
-
-TEST_F(QuicEpollConnectionHelperTest, GetClock) {
- const QuicClock* clock = helper_.GetClock();
- QuicTime start = clock->Now();
-
- QuicTime::Delta delta = QuicTime::Delta::FromMilliseconds(5);
- epoll_server_.AdvanceBy(delta.ToMicroseconds());
-
- EXPECT_EQ(start + delta, clock->Now());
-}
-
-TEST_F(QuicEpollConnectionHelperTest, GetRandomGenerator) {
- QuicRandom* random = helper_.GetRandomGenerator();
- EXPECT_EQ(QuicRandom::GetInstance(), random);
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_http_response_cache.cc b/chromium/net/tools/quic/quic_http_response_cache.cc
deleted file mode 100644
index 39ae552c513..00000000000
--- a/chromium/net/tools/quic/quic_http_response_cache.cc
+++ /dev/null
@@ -1,396 +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/tools/quic/quic_http_response_cache.h"
-
-#include <utility>
-
-#include "base/files/file_enumerator.h"
-#include "base/files/file_util.h"
-#include "net/http/http_util.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_map_util.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/spdy/chromium/spdy_http_utils.h"
-
-using base::FilePath;
-using base::IntToString;
-using std::string;
-
-namespace net {
-
-QuicHttpResponseCache::ServerPushInfo::ServerPushInfo(QuicUrl request_url,
- SpdyHeaderBlock headers,
- SpdyPriority priority,
- string body)
- : request_url(request_url),
- headers(std::move(headers)),
- priority(priority),
- body(body) {}
-
-QuicHttpResponseCache::ServerPushInfo::ServerPushInfo(
- const ServerPushInfo& other)
- : request_url(other.request_url),
- headers(other.headers.Clone()),
- priority(other.priority),
- body(other.body) {}
-
-QuicHttpResponseCache::Response::Response()
- : response_type_(REGULAR_RESPONSE) {}
-
-QuicHttpResponseCache::Response::~Response() = default;
-
-QuicHttpResponseCache::ResourceFile::ResourceFile(
- const base::FilePath& file_name)
- : file_name_(file_name), file_name_string_(file_name.AsUTF8Unsafe()) {}
-
-QuicHttpResponseCache::ResourceFile::~ResourceFile() = default;
-
-void QuicHttpResponseCache::ResourceFile::Read() {
- base::ReadFileToString(FilePath(file_name_), &file_contents_);
-
- // First read the headers.
- size_t start = 0;
- while (start < file_contents_.length()) {
- size_t pos = file_contents_.find("\n", start);
- if (pos == string::npos) {
- QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: "
- << file_name_.value();
- return;
- }
- size_t len = pos - start;
- // Support both dos and unix line endings for convenience.
- if (file_contents_[pos - 1] == '\r') {
- len -= 1;
- }
- QuicStringPiece line(file_contents_.data() + start, len);
- start = pos + 1;
- // Headers end with an empty line.
- if (line.empty()) {
- break;
- }
- // Extract the status from the HTTP first line.
- if (line.substr(0, 4) == "HTTP") {
- pos = line.find(" ");
- if (pos == string::npos) {
- QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: "
- << file_name_.value();
- return;
- }
- spdy_headers_[":status"] = line.substr(pos + 1, 3);
- continue;
- }
- // Headers are "key: value".
- pos = line.find(": ");
- if (pos == string::npos) {
- QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: "
- << file_name_.value();
- return;
- }
- spdy_headers_.AppendValueOrAddHeader(
- QuicTextUtils::ToLower(line.substr(0, pos)), line.substr(pos + 2));
- }
-
- // The connection header is prohibited in HTTP/2.
- spdy_headers_.erase("connection");
-
- // Override the URL with the X-Original-Url header, if present.
- auto it = spdy_headers_.find("x-original-url");
- if (it != spdy_headers_.end()) {
- x_original_url_ = it->second;
- HandleXOriginalUrl();
- }
-
- // X-Push-URL header is a relatively quick way to support sever push
- // in the toy server. A production server should use link=preload
- // stuff as described in https://w3c.github.io/preload/.
- it = spdy_headers_.find("x-push-url");
- if (it != spdy_headers_.end()) {
- QuicStringPiece push_urls = it->second;
- size_t start = 0;
- while (start < push_urls.length()) {
- size_t pos = push_urls.find('\0', start);
- if (pos == string::npos) {
- push_urls_.push_back(QuicStringPiece(push_urls.data() + start,
- push_urls.length() - start));
- break;
- }
- push_urls_.push_back(QuicStringPiece(push_urls.data() + start, pos));
- start += pos + 1;
- }
- }
-
- body_ = QuicStringPiece(file_contents_.data() + start,
- file_contents_.size() - start);
-}
-
-void QuicHttpResponseCache::ResourceFile::SetHostPathFromBase(
- QuicStringPiece base) {
- size_t path_start = base.find_first_of('/');
- DCHECK_LT(0UL, path_start);
- host_ = base.substr(0, path_start);
- size_t query_start = base.find_first_of(',');
- if (query_start > 0) {
- path_ = base.substr(path_start, query_start - 1);
- } else {
- path_ = base.substr(path_start);
- }
-}
-
-QuicStringPiece QuicHttpResponseCache::ResourceFile::RemoveScheme(
- QuicStringPiece url) {
- if (QuicTextUtils::StartsWith(url, "https://")) {
- url.remove_prefix(8);
- } else if (QuicTextUtils::StartsWith(url, "http://")) {
- url.remove_prefix(7);
- }
- return url;
-}
-
-void QuicHttpResponseCache::ResourceFile::HandleXOriginalUrl() {
- QuicStringPiece url(x_original_url_);
- // Remove the protocol so we can add it below.
- url = RemoveScheme(url);
- SetHostPathFromBase(url);
-}
-
-const QuicHttpResponseCache::Response* QuicHttpResponseCache::GetResponse(
- QuicStringPiece host,
- QuicStringPiece path) const {
- QuicWriterMutexLock lock(&response_mutex_);
-
- auto it = responses_.find(GetKey(host, path));
- if (it == responses_.end()) {
- DVLOG(1) << "Get response for resource failed: host " << host << " path "
- << path;
- if (default_response_) {
- return default_response_.get();
- }
- return nullptr;
- }
- return it->second.get();
-}
-
-typedef QuicHttpResponseCache::ServerPushInfo ServerPushInfo;
-
-void QuicHttpResponseCache::AddSimpleResponse(QuicStringPiece host,
- QuicStringPiece path,
- int response_code,
- QuicStringPiece body) {
- SpdyHeaderBlock response_headers;
- response_headers[":status"] = QuicTextUtils::Uint64ToString(response_code);
- response_headers["content-length"] =
- QuicTextUtils::Uint64ToString(body.length());
- AddResponse(host, path, std::move(response_headers), body);
-}
-
-void QuicHttpResponseCache::AddSimpleResponseWithServerPushResources(
- QuicStringPiece host,
- QuicStringPiece path,
- int response_code,
- QuicStringPiece body,
- std::list<ServerPushInfo> push_resources) {
- AddSimpleResponse(host, path, response_code, body);
- MaybeAddServerPushResources(host, path, push_resources);
-}
-
-void QuicHttpResponseCache::AddDefaultResponse(Response* response) {
- QuicWriterMutexLock lock(&response_mutex_);
- default_response_.reset(response);
-}
-
-void QuicHttpResponseCache::AddResponse(QuicStringPiece host,
- QuicStringPiece path,
- SpdyHeaderBlock response_headers,
- QuicStringPiece response_body) {
- AddResponseImpl(host, path, REGULAR_RESPONSE, std::move(response_headers),
- response_body, SpdyHeaderBlock());
-}
-
-void QuicHttpResponseCache::AddResponse(QuicStringPiece host,
- QuicStringPiece path,
- SpdyHeaderBlock response_headers,
- QuicStringPiece response_body,
- SpdyHeaderBlock response_trailers) {
- AddResponseImpl(host, path, REGULAR_RESPONSE, std::move(response_headers),
- response_body, std::move(response_trailers));
-}
-
-void QuicHttpResponseCache::AddSpecialResponse(
- QuicStringPiece host,
- QuicStringPiece path,
- SpecialResponseType response_type) {
- AddResponseImpl(host, path, response_type, SpdyHeaderBlock(), "",
- SpdyHeaderBlock());
-}
-
-QuicHttpResponseCache::QuicHttpResponseCache() = default;
-
-void QuicHttpResponseCache::InitializeFromDirectory(
- const string& cache_directory) {
- if (cache_directory.empty()) {
- QUIC_BUG << "cache_directory must not be empty.";
- return;
- }
- QUIC_LOG(INFO)
- << "Attempting to initialize QuicHttpResponseCache from directory: "
- << cache_directory;
- FilePath directory(FilePath::FromUTF8Unsafe(cache_directory));
- base::FileEnumerator file_list(directory, true, base::FileEnumerator::FILES);
- std::list<std::unique_ptr<ResourceFile>> resource_files;
- for (FilePath file_iter = file_list.Next(); !file_iter.empty();
- file_iter = file_list.Next()) {
- // Need to skip files in .svn directories
- if (file_iter.value().find(FILE_PATH_LITERAL("/.svn/")) != string::npos) {
- continue;
- }
-
- std::unique_ptr<ResourceFile> resource_file(new ResourceFile(file_iter));
-
- // Tease apart filename into host and path.
- QuicStringPiece base(resource_file->file_name());
- base.remove_prefix(cache_directory.length());
- if (base[0] == '/') {
- base.remove_prefix(1);
- }
-
- resource_file->SetHostPathFromBase(base);
- resource_file->Read();
-
- AddResponse(resource_file->host(), resource_file->path(),
- resource_file->spdy_headers().Clone(), resource_file->body());
-
- resource_files.push_back(std::move(resource_file));
- }
-
- for (const auto& resource_file : resource_files) {
- std::list<ServerPushInfo> push_resources;
- for (const auto& push_url : resource_file->push_urls()) {
- QuicUrl url(push_url);
- const Response* response = GetResponse(url.host(), url.path());
- if (!response) {
- QUIC_BUG << "Push URL '" << push_url << "' not found.";
- return;
- }
- push_resources.push_back(ServerPushInfo(url, response->headers().Clone(),
- kV3LowestPriority,
- (string(response->body()))));
- }
- MaybeAddServerPushResources(resource_file->host(), resource_file->path(),
- push_resources);
- }
-}
-
-std::list<ServerPushInfo> QuicHttpResponseCache::GetServerPushResources(
- string request_url) {
- QuicWriterMutexLock lock(&response_mutex_);
-
- std::list<ServerPushInfo> resources;
- auto resource_range = server_push_resources_.equal_range(request_url);
- for (auto it = resource_range.first; it != resource_range.second; ++it) {
- resources.push_back(it->second);
- }
- QUIC_DVLOG(1) << "Found " << resources.size() << " push resources for "
- << request_url;
- return resources;
-}
-
-QuicHttpResponseCache::~QuicHttpResponseCache() {
- {
- QuicWriterMutexLock lock(&response_mutex_);
- responses_.clear();
- }
-}
-
-void QuicHttpResponseCache::AddResponseImpl(QuicStringPiece host,
- QuicStringPiece path,
- SpecialResponseType response_type,
- SpdyHeaderBlock response_headers,
- QuicStringPiece response_body,
- SpdyHeaderBlock response_trailers) {
- QuicWriterMutexLock lock(&response_mutex_);
-
- DCHECK(!host.empty()) << "Host must be populated, e.g. \"www.google.com\"";
- string key = GetKey(host, path);
- if (QuicContainsKey(responses_, key)) {
- QUIC_BUG << "Response for '" << key << "' already exists!";
- return;
- }
- auto new_response = QuicMakeUnique<Response>();
- new_response->set_response_type(response_type);
- new_response->set_headers(std::move(response_headers));
- new_response->set_body(response_body);
- new_response->set_trailers(std::move(response_trailers));
- QUIC_DVLOG(1) << "Add response with key " << key;
- responses_[key] = std::move(new_response);
-}
-
-string QuicHttpResponseCache::GetKey(QuicStringPiece host,
- QuicStringPiece path) const {
- string host_string = string(host);
- size_t port = host_string.find(':');
- if (port != string::npos)
- host_string = string(host_string.c_str(), port);
- return host_string + string(path);
-}
-
-void QuicHttpResponseCache::MaybeAddServerPushResources(
- QuicStringPiece request_host,
- QuicStringPiece request_path,
- std::list<ServerPushInfo> push_resources) {
- string request_url = GetKey(request_host, request_path);
-
- for (const auto& push_resource : push_resources) {
- if (PushResourceExistsInCache(request_url, push_resource)) {
- continue;
- }
-
- QUIC_DVLOG(1) << "Add request-resource association: request url "
- << request_url << " push url "
- << push_resource.request_url.ToString()
- << " response headers "
- << push_resource.headers.DebugString();
- {
- QuicWriterMutexLock lock(&response_mutex_);
- server_push_resources_.insert(std::make_pair(request_url, push_resource));
- }
- string host = push_resource.request_url.host();
- if (host.empty()) {
- host = string(request_host);
- }
- string path = push_resource.request_url.path();
- bool found_existing_response = false;
- {
- QuicWriterMutexLock lock(&response_mutex_);
- found_existing_response = QuicContainsKey(responses_, GetKey(host, path));
- }
- if (!found_existing_response) {
- // Add a server push response to responses map, if it is not in the map.
- QuicStringPiece body = push_resource.body;
- QUIC_DVLOG(1) << "Add response for push resource: host " << host
- << " path " << path;
- AddResponse(host, path, push_resource.headers.Clone(), body);
- }
- }
-}
-
-bool QuicHttpResponseCache::PushResourceExistsInCache(
- string original_request_url,
- ServerPushInfo resource) {
- QuicWriterMutexLock lock(&response_mutex_);
- auto resource_range =
- server_push_resources_.equal_range(original_request_url);
- for (auto it = resource_range.first; it != resource_range.second; ++it) {
- ServerPushInfo push_resource = it->second;
- if (push_resource.request_url.ToString() ==
- resource.request_url.ToString()) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_http_response_cache.h b/chromium/net/tools/quic/quic_http_response_cache.h
deleted file mode 100644
index ea840feaa6e..00000000000
--- a/chromium/net/tools/quic/quic_http_response_cache.h
+++ /dev/null
@@ -1,223 +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_TOOLS_QUIC_QUIC_HTTP_RESPONSE_CACHE_H_
-#define NET_TOOLS_QUIC_QUIC_HTTP_RESPONSE_CACHE_H_
-
-#include <list>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/quic/platform/api/quic_mutex.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/quic/platform/api/quic_url.h"
-#include "net/spdy/core/spdy_framer.h"
-
-namespace net {
-
-// In-memory cache for HTTP responses.
-// Reads from disk cache generated by:
-// `wget -p --save_headers <url>`
-class QuicHttpResponseCache {
- public:
- // A ServerPushInfo contains path of the push request and everything needed in
- // comprising a response for the push request.
- struct ServerPushInfo {
- ServerPushInfo(QuicUrl request_url,
- SpdyHeaderBlock headers,
- SpdyPriority priority,
- std::string body);
- ServerPushInfo(const ServerPushInfo& other);
- QuicUrl request_url;
- SpdyHeaderBlock headers;
- SpdyPriority priority;
- std::string body;
- };
-
- enum SpecialResponseType {
- REGULAR_RESPONSE, // Send the headers and body like a server should.
- CLOSE_CONNECTION, // Close the connection (sending the close packet).
- IGNORE_REQUEST, // Do nothing, expect the client to time out.
- };
-
- // Container for response header/body pairs.
- class Response {
- public:
- Response();
- ~Response();
-
- SpecialResponseType response_type() const { return response_type_; }
- const SpdyHeaderBlock& headers() const { return headers_; }
- const SpdyHeaderBlock& trailers() const { return trailers_; }
- const QuicStringPiece body() const { return QuicStringPiece(body_); }
-
- void set_response_type(SpecialResponseType response_type) {
- response_type_ = response_type;
- }
- void set_headers(SpdyHeaderBlock headers) { headers_ = std::move(headers); }
- void set_trailers(SpdyHeaderBlock trailers) {
- trailers_ = std::move(trailers);
- }
- void set_body(QuicStringPiece body) {
- body_.assign(body.data(), body.size());
- }
-
- private:
- SpecialResponseType response_type_;
- SpdyHeaderBlock headers_;
- SpdyHeaderBlock trailers_;
- std::string body_;
-
- DISALLOW_COPY_AND_ASSIGN(Response);
- };
-
- // Class to manage loading a resource file into memory. There are
- // two uses: called by InitializeFromDirectory to load resources
- // from files, and recursively called when said resources specify
- // server push associations.
- class ResourceFile {
- public:
- explicit ResourceFile(const base::FilePath& file_name);
- virtual ~ResourceFile();
-
- void Read();
-
- // |base| is |file_name_| with |cache_directory| prefix stripped.
- void SetHostPathFromBase(QuicStringPiece base);
-
- const std::string& file_name() { return file_name_string_; }
-
- QuicStringPiece host() { return host_; }
-
- QuicStringPiece path() { return path_; }
-
- const SpdyHeaderBlock& spdy_headers() { return spdy_headers_; }
-
- QuicStringPiece body() { return body_; }
-
- const std::vector<QuicStringPiece>& push_urls() { return push_urls_; }
-
- protected:
- void HandleXOriginalUrl();
- void HandlePushUrls(const std::vector<QuicStringPiece>& push_urls);
- QuicStringPiece RemoveScheme(QuicStringPiece url);
-
- const std::string cache_directory_;
- const base::FilePath file_name_;
- const std::string file_name_string_;
- std::string file_contents_;
- QuicStringPiece body_;
- SpdyHeaderBlock spdy_headers_;
- QuicStringPiece x_original_url_;
- std::vector<QuicStringPiece> push_urls_;
-
- private:
- QuicStringPiece host_;
- QuicStringPiece path_;
- QuicHttpResponseCache* cache_;
-
- DISALLOW_COPY_AND_ASSIGN(ResourceFile);
- };
-
- QuicHttpResponseCache();
- ~QuicHttpResponseCache();
-
- // Retrieve a response from this cache for a given host and path..
- // If no appropriate response exists, nullptr is returned.
- const Response* GetResponse(QuicStringPiece host, QuicStringPiece path) const;
-
- // Adds a simple response to the cache. The response headers will
- // only contain the "content-length" header with the length of |body|.
- void AddSimpleResponse(QuicStringPiece host,
- QuicStringPiece path,
- int response_code,
- QuicStringPiece body);
-
- // Add a simple response to the cache as AddSimpleResponse() does, and add
- // some server push resources(resource path, corresponding response status and
- // path) associated with it.
- // Push resource implicitly come from the same host.
- void AddSimpleResponseWithServerPushResources(
- QuicStringPiece host,
- QuicStringPiece path,
- int response_code,
- QuicStringPiece body,
- std::list<ServerPushInfo> push_resources);
-
- // Add a response to the cache.
- void AddResponse(QuicStringPiece host,
- QuicStringPiece path,
- SpdyHeaderBlock response_headers,
- QuicStringPiece response_body);
-
- // Add a response, with trailers, to the cache.
- void AddResponse(QuicStringPiece host,
- QuicStringPiece path,
- SpdyHeaderBlock response_headers,
- QuicStringPiece response_body,
- SpdyHeaderBlock response_trailers);
-
- // Simulate a special behavior at a particular path.
- void AddSpecialResponse(QuicStringPiece host,
- QuicStringPiece path,
- SpecialResponseType response_type);
-
- // Sets a default response in case of cache misses. Takes ownership of
- // 'response'.
- void AddDefaultResponse(Response* response);
-
- // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
- void InitializeFromDirectory(const std::string& cache_directory);
-
- // Find all the server push resources associated with |request_url|.
- std::list<ServerPushInfo> GetServerPushResources(std::string request_url);
-
- private:
- void AddResponseImpl(QuicStringPiece host,
- QuicStringPiece path,
- SpecialResponseType response_type,
- SpdyHeaderBlock response_headers,
- QuicStringPiece response_body,
- SpdyHeaderBlock response_trailers);
-
- std::string GetKey(QuicStringPiece host, QuicStringPiece path) const;
-
- // Add some server push urls with given responses for specified
- // request if these push resources are not associated with this request yet.
- void MaybeAddServerPushResources(QuicStringPiece request_host,
- QuicStringPiece request_path,
- std::list<ServerPushInfo> push_resources);
-
- // Check if push resource(push_host/push_path) associated with given request
- // url already exists in server push map.
- bool PushResourceExistsInCache(std::string original_request_url,
- ServerPushInfo resource);
-
- // Cached responses.
- QuicUnorderedMap<std::string, std::unique_ptr<Response>> responses_
- GUARDED_BY(response_mutex_);
-
- // The default response for cache misses, if set.
- std::unique_ptr<Response> default_response_ GUARDED_BY(response_mutex_);
-
- // A map from request URL to associated server push responses (if any).
- std::multimap<std::string, ServerPushInfo> server_push_resources_
- GUARDED_BY(response_mutex_);
-
- // Protects against concurrent access from test threads setting responses, and
- // server threads accessing those responses.
- mutable QuicMutex response_mutex_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicHttpResponseCache);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_HTTP_RESPONSE_CACHE_H_
diff --git a/chromium/net/tools/quic/quic_http_response_cache_test.cc b/chromium/net/tools/quic/quic_http_response_cache_test.cc
deleted file mode 100644
index 60ea65fa53d..00000000000
--- a/chromium/net/tools/quic/quic_http_response_cache_test.cc
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2013 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/tools/quic/quic_http_response_cache.h"
-
-#include "base/files/file_path.h"
-#include "base/path_service.h"
-#include "net/quic/platform/api/quic_map_util.h"
-#include "net/quic/platform/api/quic_str_cat.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-
-using std::string;
-
-namespace net {
-namespace test {
-
-namespace {
-typedef QuicHttpResponseCache::Response Response;
-typedef QuicHttpResponseCache::ServerPushInfo ServerPushInfo;
-}; // namespace
-
-class QuicHttpResponseCacheTest : public QuicTest {
- protected:
- void CreateRequest(string host, string path, SpdyHeaderBlock* headers) {
- (*headers)[":method"] = "GET";
- (*headers)[":path"] = path;
- (*headers)[":authority"] = host;
- (*headers)[":scheme"] = "https";
- }
-
- string CacheDirectory() {
- base::FilePath path;
- PathService::Get(base::DIR_SOURCE_ROOT, &path);
- path = path.AppendASCII("net").AppendASCII("data").AppendASCII(
- "quic_http_response_cache_data");
- // The file path is known to be an ascii string.
- return path.MaybeAsASCII();
- }
-
- QuicHttpResponseCache cache_;
-};
-
-TEST_F(QuicHttpResponseCacheTest, GetResponseNoMatch) {
- const QuicHttpResponseCache::Response* response =
- cache_.GetResponse("mail.google.com", "/index.html");
- ASSERT_FALSE(response);
-}
-
-TEST_F(QuicHttpResponseCacheTest, AddSimpleResponseGetResponse) {
- string response_body("hello response");
- cache_.AddSimpleResponse("www.google.com", "/", 200, response_body);
-
- SpdyHeaderBlock request_headers;
- CreateRequest("www.google.com", "/", &request_headers);
- const QuicHttpResponseCache::Response* response =
- cache_.GetResponse("www.google.com", "/");
- ASSERT_TRUE(response);
- ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
- EXPECT_EQ(response_body.size(), response->body().length());
-}
-
-TEST_F(QuicHttpResponseCacheTest, AddResponse) {
- const string kRequestHost = "www.foo.com";
- const string kRequestPath = "/";
- const string kResponseBody("hello response");
-
- SpdyHeaderBlock response_headers;
- response_headers[":version"] = "HTTP/1.1";
- response_headers[":status"] = "200";
- response_headers["content-length"] =
- QuicTextUtils::Uint64ToString(kResponseBody.size());
-
- SpdyHeaderBlock response_trailers;
- response_trailers["key-1"] = "value-1";
- response_trailers["key-2"] = "value-2";
- response_trailers["key-3"] = "value-3";
-
- cache_.AddResponse(kRequestHost, "/", response_headers.Clone(), kResponseBody,
- response_trailers.Clone());
-
- const QuicHttpResponseCache::Response* response =
- cache_.GetResponse(kRequestHost, kRequestPath);
- EXPECT_EQ(response->headers(), response_headers);
- EXPECT_EQ(response->body(), kResponseBody);
- EXPECT_EQ(response->trailers(), response_trailers);
-}
-
-TEST_F(QuicHttpResponseCacheTest, ReadsCacheDir) {
- cache_.InitializeFromDirectory(CacheDirectory());
- const QuicHttpResponseCache::Response* response =
- cache_.GetResponse("test.example.com", "/index.html");
- ASSERT_TRUE(response);
- ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
- // Connection headers are not valid in HTTP/2.
- EXPECT_FALSE(QuicContainsKey(response->headers(), "connection"));
- EXPECT_LT(0U, response->body().length());
-}
-
-TEST_F(QuicHttpResponseCacheTest, ReadsCacheDirWithServerPushResource) {
- cache_.InitializeFromDirectory(CacheDirectory() + "_with_push");
- std::list<ServerPushInfo> resources =
- cache_.GetServerPushResources("test.example.com/");
- ASSERT_EQ(1UL, resources.size());
-}
-
-TEST_F(QuicHttpResponseCacheTest, ReadsCacheDirWithServerPushResources) {
- cache_.InitializeFromDirectory(CacheDirectory() + "_with_push");
- std::list<ServerPushInfo> resources =
- cache_.GetServerPushResources("test.example.com/index2.html");
- ASSERT_EQ(2UL, resources.size());
-}
-
-TEST_F(QuicHttpResponseCacheTest, UsesOriginalUrl) {
- cache_.InitializeFromDirectory(CacheDirectory());
- const QuicHttpResponseCache::Response* response =
- cache_.GetResponse("test.example.com", "/site_map.html");
- ASSERT_TRUE(response);
- ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
- // Connection headers are not valid in HTTP/2.
- EXPECT_FALSE(QuicContainsKey(response->headers(), "connection"));
- EXPECT_LT(0U, response->body().length());
-}
-
-TEST_F(QuicHttpResponseCacheTest, DefaultResponse) {
- // Verify GetResponse returns nullptr when no default is set.
- const QuicHttpResponseCache::Response* response =
- cache_.GetResponse("www.google.com", "/");
- ASSERT_FALSE(response);
-
- // Add a default response.
- SpdyHeaderBlock response_headers;
- response_headers[":version"] = "HTTP/1.1";
- response_headers[":status"] = "200";
- response_headers["content-length"] = "0";
- QuicHttpResponseCache::Response* default_response =
- new QuicHttpResponseCache::Response;
- default_response->set_headers(std::move(response_headers));
- cache_.AddDefaultResponse(default_response);
-
- // Now we should get the default response for the original request.
- response = cache_.GetResponse("www.google.com", "/");
- ASSERT_TRUE(response);
- ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
-
- // Now add a set response for / and make sure it is returned
- cache_.AddSimpleResponse("www.google.com", "/", 302, "");
- response = cache_.GetResponse("www.google.com", "/");
- ASSERT_TRUE(response);
- ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
- EXPECT_EQ("302", response->headers().find(":status")->second);
-
- // We should get the default response for other requests.
- response = cache_.GetResponse("www.google.com", "/asd");
- ASSERT_TRUE(response);
- ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200", response->headers().find(":status")->second);
-}
-
-TEST_F(QuicHttpResponseCacheTest, AddSimpleResponseWithServerPushResources) {
- string request_host = "www.foo.com";
- string response_body("hello response");
- const size_t kNumResources = 5;
- int NumResources = 5;
- std::list<QuicHttpResponseCache::ServerPushInfo> push_resources;
- string scheme = "http";
- for (int i = 0; i < NumResources; ++i) {
- string path = "/server_push_src" + QuicTextUtils::Uint64ToString(i);
- string url = scheme + "://" + request_host + path;
- QuicUrl resource_url(url);
- string body = QuicStrCat("This is server push response body for ", path);
- SpdyHeaderBlock response_headers;
- response_headers[":version"] = "HTTP/1.1";
- response_headers[":status"] = "200";
- response_headers["content-length"] =
- QuicTextUtils::Uint64ToString(body.size());
- push_resources.push_back(
- ServerPushInfo(resource_url, response_headers.Clone(), i, body));
- }
-
- cache_.AddSimpleResponseWithServerPushResources(
- request_host, "/", 200, response_body, push_resources);
-
- string request_url = request_host + "/";
- std::list<ServerPushInfo> resources =
- cache_.GetServerPushResources(request_url);
- ASSERT_EQ(kNumResources, resources.size());
- for (const auto& push_resource : push_resources) {
- ServerPushInfo resource = resources.front();
- EXPECT_EQ(resource.request_url.ToString(),
- push_resource.request_url.ToString());
- EXPECT_EQ(resource.priority, push_resource.priority);
- resources.pop_front();
- }
-}
-
-TEST_F(QuicHttpResponseCacheTest, GetServerPushResourcesAndPushResponses) {
- string request_host = "www.foo.com";
- string response_body("hello response");
- const size_t kNumResources = 4;
- int NumResources = 4;
- string scheme = "http";
- string push_response_status[kNumResources] = {"200", "200", "301", "404"};
- std::list<QuicHttpResponseCache::ServerPushInfo> push_resources;
- for (int i = 0; i < NumResources; ++i) {
- string path = "/server_push_src" + QuicTextUtils::Uint64ToString(i);
- string url = scheme + "://" + request_host + path;
- QuicUrl resource_url(url);
- string body = "This is server push response body for " + path;
- SpdyHeaderBlock response_headers;
- response_headers[":version"] = "HTTP/1.1";
- response_headers[":status"] = push_response_status[i];
- response_headers["content-length"] =
- QuicTextUtils::Uint64ToString(body.size());
- push_resources.push_back(
- ServerPushInfo(resource_url, response_headers.Clone(), i, body));
- }
- cache_.AddSimpleResponseWithServerPushResources(
- request_host, "/", 200, response_body, push_resources);
- string request_url = request_host + "/";
- std::list<ServerPushInfo> resources =
- cache_.GetServerPushResources(request_url);
- ASSERT_EQ(kNumResources, resources.size());
- int i = 0;
- for (const auto& push_resource : push_resources) {
- QuicUrl url = resources.front().request_url;
- string host = url.host();
- string path = url.path();
- const QuicHttpResponseCache::Response* response =
- cache_.GetResponse(host, path);
- ASSERT_TRUE(response);
- ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
- EXPECT_EQ(push_response_status[i++],
- response->headers().find(":status")->second);
- EXPECT_EQ(push_resource.body, response->body());
- resources.pop_front();
- }
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_packet_printer_bin.cc b/chromium/net/tools/quic/quic_packet_printer_bin.cc
deleted file mode 100644
index 59750bbfaa7..00000000000
--- a/chromium/net/tools/quic/quic_packet_printer_bin.cc
+++ /dev/null
@@ -1,215 +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.
-
-// clang-format off
-
-// Dumps out the decryptable contents of a QUIC packet in a human-readable way.
-// If the packet is null encrypted, this will dump full packet contents.
-// Otherwise it will dump the header, and fail with an error that the
-// packet is undecryptable.
-//
-// Usage: quic_packet_printer server|client <hex dump of packet>
-//
-// Example input:
-// quic_packet_printer server 0c6b810308320f24c004a939a38a2e3fd6ca589917f200400
-// 201b80b0100501c0700060003023d0000001c00556e656e637279707465642073747265616d2
-// 064617461207365656e
-//
-// Example output:
-// OnPacket
-// OnUnauthenticatedPublicHeader
-// OnUnauthenticatedHeader: { connection_id: 13845207862000976235,
-// connection_id_length:8, packet_number_length:1, multipath_flag: 0,
-// reset_flag: 0, version_flag: 0, path_id: , packet_number: 4}
-// OnDecryptedPacket
-// OnPacketHeader
-// OnAckFrame: largest_observed: 1 ack_delay_time: 3000
-// missing_packets: [ ] is_truncated: 0 received_packets: [ 1 at 466016 ]
-// OnStopWaitingFrame
-// OnConnectionCloseFrame: error_code { 61 } error_details { Unencrypted stream
-// data seen }
-
-// clang-format on
-
-#include <iostream>
-#include <string>
-
-#include "base/command_line.h"
-#include "base/strings/utf_string_conversions.h"
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-
-using std::string;
-
-// If set, specify the QUIC version to use.
-string FLAGS_quic_version = "";
-
-namespace {
-
-string ArgToString(base::CommandLine::StringType arg) {
-#if defined(OS_WIN)
- return base::UTF16ToASCII(arg);
-#else
- return arg;
-#endif
-}
-}
-
-namespace net {
-
-class QuicPacketPrinter : public QuicFramerVisitorInterface {
- public:
- explicit QuicPacketPrinter(QuicFramer* framer) : framer_(framer) {}
-
- void OnError(QuicFramer* framer) override {
- std::cerr << "OnError: " << QuicErrorCodeToString(framer->error())
- << " detail: " << framer->detailed_error() << "\n";
- }
- bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
- framer_->set_version(received_version);
- std::cerr << "OnProtocolVersionMismatch: "
- << ParsedQuicVersionToString(received_version) << "\n";
- return true;
- }
- void OnPacket() override { std::cerr << "OnPacket\n"; }
- void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
- std::cerr << "OnPublicResetPacket\n";
- }
- void OnVersionNegotiationPacket(
- const QuicVersionNegotiationPacket& packet) override {
- std::cerr << "OnVersionNegotiationPacket\n";
- }
- bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override {
- std::cerr << "OnUnauthenticatedPublicHeader\n";
- return true;
- }
- bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
- std::cerr << "OnUnauthenticatedHeader: " << header;
- return true;
- }
- void OnDecryptedPacket(EncryptionLevel level) override {
- // This only currently supports "decrypting" null encrypted packets.
- DCHECK_EQ(ENCRYPTION_NONE, level);
- std::cerr << "OnDecryptedPacket\n";
- }
- bool OnPacketHeader(const QuicPacketHeader& header) override {
- std::cerr << "OnPacketHeader\n";
- return true;
- }
- bool OnStreamFrame(const QuicStreamFrame& frame) override {
- std::cerr << "OnStreamFrame: " << frame;
- std::cerr << " data: { "
- << QuicTextUtils::HexEncode(frame.data_buffer, frame.data_length)
- << " }\n";
- return true;
- }
- bool OnAckFrame(const QuicAckFrame& frame) override {
- std::cerr << "OnAckFrame: " << frame;
- return true;
- }
- bool OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta /*ack_delay_time*/) override {
- std::cerr << "OnAckFrameStart, largest_acked: " << largest_acked;
- return true;
- }
- bool OnAckRange(QuicPacketNumber start,
- QuicPacketNumber end,
- bool last_range) override {
- std::cerr << "OnAckRange: [" << start << ", " << end
- << "), last_range: " << last_range;
- return true;
- }
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
- std::cerr << "OnStopWaitingFrame: " << frame;
- return true;
- }
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
- std::cerr << "OnPaddingFrame: " << frame;
- return true;
- }
- bool OnPingFrame(const QuicPingFrame& frame) override {
- std::cerr << "OnPingFrame\n";
- return true;
- }
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
- std::cerr << "OnRstStreamFrame: " << frame;
- return true;
- }
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
- std::cerr << "OnConnectionCloseFrame: " << frame;
- return true;
- }
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
- std::cerr << "OnGoAwayFrame: " << frame;
- return true;
- }
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
- std::cerr << "OnWindowUpdateFrame: " << frame;
- return true;
- }
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
- std::cerr << "OnBlockedFrame: " << frame;
- return true;
- }
- void OnPacketComplete() override { std::cerr << "OnPacketComplete\n"; }
- bool IsValidStatelessResetToken(uint128 token) const override {
- std::cerr << "IsValidStatelessResetToken\n";
- return false;
- }
- void OnAuthenticatedIetfStatelessResetPacket(
- const QuicIetfStatelessResetPacket& packet) override {
- std::cerr << "OnAuthenticatedIetfStatelessResetPacket\n";
- }
-
- private:
- QuicFramer* framer_; // Unowned.
-};
-
-} // namespace net
-
-int main(int argc, char* argv[]) {
- base::CommandLine::Init(argc, argv);
- base::CommandLine* line = base::CommandLine::ForCurrentProcess();
- const base::CommandLine::StringVector& args = line->GetArgs();
-
- if (args.size() != 3) {
- std::cerr << "Missing argument " << argc << ". (Usage: " << argv[0]
- << " client|server <hex>\n";
- return 1;
- }
-
- if (line->HasSwitch("quic_version")) {
- FLAGS_quic_version = line->GetSwitchValueASCII("quic_version");
- }
-
- string perspective_string = ArgToString(args[0]);
- net::Perspective perspective;
- if (perspective_string == "client") {
- perspective = net::Perspective::IS_CLIENT;
- } else if (perspective_string == "server") {
- perspective = net::Perspective::IS_SERVER;
- } else {
- std::cerr << "Invalid perspective. " << perspective_string
- << " Usage: " << args[0] << " client|server <hex>\n";
- return 1;
- }
- string hex = net::QuicTextUtils::HexDecode(argv[2]);
- net::ParsedQuicVersionVector versions = net::AllSupportedVersions();
- // Fake a time since we're not actually generating acks.
- net::QuicTime start(net::QuicTime::Zero());
- net::QuicFramer framer(versions, start, perspective);
- if (!FLAGS_quic_version.empty()) {
- for (net::ParsedQuicVersion version : versions) {
- if (net::QuicVersionToString(version.transport_version) ==
- FLAGS_quic_version) {
- framer.set_version(version);
- }
- }
- }
- net::QuicPacketPrinter visitor(&framer);
- framer.set_visitor(&visitor);
- net::QuicEncryptedPacket encrypted(hex.c_str(), hex.length());
- return framer.ProcessPacket(encrypted);
-}
diff --git a/chromium/net/tools/quic/quic_packet_reader.cc b/chromium/net/tools/quic/quic_packet_reader.cc
deleted file mode 100644
index 76de5b2956b..00000000000
--- a/chromium/net/tools/quic/quic_packet_reader.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2015 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/tools/quic/quic_packet_reader.h"
-
-#include <errno.h>
-#ifndef __APPLE__
-// This is a GNU header that is not present in /usr/include on MacOS
-#include <features.h>
-#endif
-#include <string.h>
-
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-#include "net/tools/quic/quic_dispatcher.h"
-#include "net/tools/quic/quic_process_packet_interface.h"
-
-#ifndef SO_RXQ_OVFL
-#define SO_RXQ_OVFL 40
-#endif
-
-namespace net {
-
-
-QuicPacketReader::QuicPacketReader() {
- Initialize();
-}
-
-void QuicPacketReader::Initialize() {
-#if MMSG_MORE
- // Zero initialize uninitialized memory.
- memset(mmsg_hdr_, 0, sizeof(mmsg_hdr_));
-
- for (int i = 0; i < kNumPacketsPerReadMmsgCall; ++i) {
- packets_[i].iov.iov_base = packets_[i].buf;
- packets_[i].iov.iov_len = kMaxPacketSize;
- memset(&packets_[i].raw_address, 0, sizeof(packets_[i].raw_address));
- memset(packets_[i].cbuf, 0, sizeof(packets_[i].cbuf));
- memset(packets_[i].buf, 0, sizeof(packets_[i].buf));
-
- msghdr* hdr = &mmsg_hdr_[i].msg_hdr;
- hdr->msg_name = &packets_[i].raw_address;
- hdr->msg_namelen = sizeof(sockaddr_storage);
- hdr->msg_iov = &packets_[i].iov;
- hdr->msg_iovlen = 1;
-
- hdr->msg_control = packets_[i].cbuf;
- hdr->msg_controllen = QuicSocketUtils::kSpaceForCmsg;
- }
-#endif
-}
-
-QuicPacketReader::~QuicPacketReader() = default;
-
-bool QuicPacketReader::ReadAndDispatchPackets(
- int fd,
- int port,
- const QuicClock& clock,
- ProcessPacketInterface* processor,
- QuicPacketCount* packets_dropped) {
-#if MMSG_MORE
- return ReadAndDispatchManyPackets(fd, port, clock, processor,
- packets_dropped);
-#else
- return ReadAndDispatchSinglePacket(fd, port, clock, processor,
- packets_dropped);
-#endif
-}
-
-bool QuicPacketReader::ReadAndDispatchManyPackets(
- int fd,
- int port,
- const QuicClock& clock,
- ProcessPacketInterface* processor,
- QuicPacketCount* packets_dropped) {
-#if MMSG_MORE
- // Re-set the length fields in case recvmmsg has changed them.
- for (int i = 0; i < kNumPacketsPerReadMmsgCall; ++i) {
- DCHECK_EQ(kMaxPacketSize, packets_[i].iov.iov_len);
- msghdr* hdr = &mmsg_hdr_[i].msg_hdr;
- hdr->msg_namelen = sizeof(sockaddr_storage);
- DCHECK_EQ(1, hdr->msg_iovlen);
- hdr->msg_controllen = QuicSocketUtils::kSpaceForCmsg;
- }
-
- int packets_read =
- recvmmsg(fd, mmsg_hdr_, kNumPacketsPerReadMmsgCall, 0, nullptr);
-
- if (packets_read <= 0) {
- return false; // recvmmsg failed.
- }
-
- QuicWallTime fallback_walltimestamp = QuicWallTime::Zero();
- for (int i = 0; i < packets_read; ++i) {
- if (mmsg_hdr_[i].msg_len == 0) {
- continue;
- }
-
- if (mmsg_hdr_[i].msg_hdr.msg_controllen >= QuicSocketUtils::kSpaceForCmsg) {
- QUIC_BUG << "Incorrectly set control length: "
- << mmsg_hdr_[i].msg_hdr.msg_controllen << ", expected "
- << QuicSocketUtils::kSpaceForCmsg;
- continue;
- }
-
- QuicSocketAddress client_address =
- QuicSocketAddress(packets_[i].raw_address);
- QuicIpAddress server_ip;
- QuicWallTime packet_walltimestamp = QuicWallTime::Zero();
- QuicSocketUtils::GetAddressAndTimestampFromMsghdr(
- &mmsg_hdr_[i].msg_hdr, &server_ip, &packet_walltimestamp);
- if (!server_ip.IsInitialized()) {
- QUIC_BUG << "Unable to get server address.";
- continue;
- }
-
- // This isn't particularly desirable, but not all platforms support socket
- // timestamping.
- if (packet_walltimestamp.IsZero()) {
- if (fallback_walltimestamp.IsZero()) {
- fallback_walltimestamp = clock.WallNow();
- }
- packet_walltimestamp = fallback_walltimestamp;
- }
- QuicTime timestamp = clock.ConvertWallTimeToQuicTime(packet_walltimestamp);
- int ttl = 0;
- bool has_ttl =
- QuicSocketUtils::GetTtlFromMsghdr(&mmsg_hdr_[i].msg_hdr, &ttl);
- QuicReceivedPacket packet(reinterpret_cast<char*>(packets_[i].iov.iov_base),
- mmsg_hdr_[i].msg_len, timestamp, false, ttl,
- has_ttl);
- QuicSocketAddress server_address(server_ip, port);
- processor->ProcessPacket(server_address, client_address, packet);
- }
-
- if (packets_dropped != nullptr) {
- QuicSocketUtils::GetOverflowFromMsghdr(&mmsg_hdr_[0].msg_hdr,
- packets_dropped);
- }
-
- // We may not have read all of the packets available on the socket.
- return packets_read == kNumPacketsPerReadMmsgCall;
-#else
- QUIC_LOG(FATAL) << "Unsupported";
- return false;
-#endif
-}
-
-/* static */
-bool QuicPacketReader::ReadAndDispatchSinglePacket(
- int fd,
- int port,
- const QuicClock& clock,
- ProcessPacketInterface* processor,
- QuicPacketCount* packets_dropped) {
- char buf[kMaxPacketSize];
-
- QuicSocketAddress client_address;
- QuicIpAddress server_ip;
- QuicWallTime walltimestamp = QuicWallTime::Zero();
- int bytes_read =
- QuicSocketUtils::ReadPacket(fd, buf, arraysize(buf), packets_dropped,
- &server_ip, &walltimestamp, &client_address);
- if (bytes_read < 0) {
- return false; // ReadPacket failed.
- }
-
- if (!server_ip.IsInitialized()) {
- QUIC_BUG << "Unable to get server address.";
- return false;
- }
- // This isn't particularly desirable, but not all platforms support socket
- // timestamping.
- if (walltimestamp.IsZero()) {
- walltimestamp = clock.WallNow();
- }
- QuicTime timestamp = clock.ConvertWallTimeToQuicTime(walltimestamp);
-
- QuicReceivedPacket packet(buf, bytes_read, timestamp, false);
- QuicSocketAddress server_address(server_ip, port);
- processor->ProcessPacket(server_address, client_address, packet);
-
- // The socket read was successful, so return true even if packet dispatch
- // failed.
- return true;
-}
-
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_packet_reader.h b/chromium/net/tools/quic/quic_packet_reader.h
deleted file mode 100644
index 13a8ccc89a0..00000000000
--- a/chromium/net/tools/quic/quic_packet_reader.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2015 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.
-
-// A class to read incoming QUIC packets from the UDP socket.
-
-#ifndef NET_TOOLS_QUIC_QUIC_PACKET_READER_H_
-#define NET_TOOLS_QUIC_QUIC_PACKET_READER_H_
-
-#include <netinet/in.h>
-// Include here to guarantee this header gets included (for MSG_WAITFORONE)
-// regardless of how the below transitive header include set may change.
-#include <sys/socket.h>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/platform/api/quic_clock.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-#include "net/tools/quic/quic_process_packet_interface.h"
-
-#define MMSG_MORE 0
-
-namespace net {
-
-#if MMSG_MORE
-// Read in larger batches to minimize recvmmsg overhead.
-const int kNumPacketsPerReadMmsgCall = 16;
-#endif
-
-class QuicPacketReader {
- public:
- QuicPacketReader();
-
- virtual ~QuicPacketReader();
-
- // Reads a number of packets from the given fd, and then passes them off to
- // the PacketProcessInterface. Returns true if there may be additional
- // packets available on the socket.
- // Populates |packets_dropped| if it is non-null and the socket is configured
- // to track dropped packets and some packets are read.
- // If the socket has timestamping enabled, the per packet timestamps will be
- // passed to the processor. Otherwise, |clock| will be used.
- virtual bool ReadAndDispatchPackets(int fd,
- int port,
- const QuicClock& clock,
- ProcessPacketInterface* processor,
- QuicPacketCount* packets_dropped);
-
- private:
- // Initialize the internal state of the reader.
- void Initialize();
-
- // Reads and dispatches many packets using recvmmsg.
- bool ReadAndDispatchManyPackets(int fd,
- int port,
- const QuicClock& clock,
- ProcessPacketInterface* processor,
- QuicPacketCount* packets_dropped);
-
- // Reads and dispatches a single packet using recvmsg.
- static bool ReadAndDispatchSinglePacket(int fd,
- int port,
- const QuicClock& clock,
- ProcessPacketInterface* processor,
- QuicPacketCount* packets_dropped);
-
- // Storage only used when recvmmsg is available.
-
-#if MMSG_MORE
- // TODO(danzh): change it to be a pointer to avoid the allocation on the stack
- // from exceeding maximum allowed frame size.
- // packets_ and mmsg_hdr_ are used to supply cbuf and buf to the recvmmsg
- // call.
-
- struct PacketData {
- iovec iov;
- // raw_address is used for address information provided by the recvmmsg
- // call on the packets.
- struct sockaddr_storage raw_address;
- // cbuf is used for ancillary data from the kernel on recvmmsg.
- char cbuf[QuicSocketUtils::kSpaceForCmsg];
- // buf is used for the data read from the kernel on recvmmsg.
- char buf[kMaxPacketSize];
- };
- PacketData packets_[kNumPacketsPerReadMmsgCall];
- mmsghdr mmsg_hdr_[kNumPacketsPerReadMmsgCall];
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(QuicPacketReader);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_PACKET_READER_H_
diff --git a/chromium/net/tools/quic/quic_packet_writer_wrapper.cc b/chromium/net/tools/quic/quic_packet_writer_wrapper.cc
deleted file mode 100644
index 42f7d0a1ee3..00000000000
--- a/chromium/net/tools/quic/quic_packet_writer_wrapper.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2014 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/tools/quic/quic_packet_writer_wrapper.h"
-
-#include "net/quic/core/quic_types.h"
-
-namespace net {
-
-QuicPacketWriterWrapper::QuicPacketWriterWrapper() = default;
-
-QuicPacketWriterWrapper::~QuicPacketWriterWrapper() = default;
-
-WriteResult QuicPacketWriterWrapper::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- return writer_->WritePacket(buffer, buf_len, self_address, peer_address,
- options);
-}
-
-bool QuicPacketWriterWrapper::IsWriteBlockedDataBuffered() const {
- return writer_->IsWriteBlockedDataBuffered();
-}
-
-bool QuicPacketWriterWrapper::IsWriteBlocked() const {
- return writer_->IsWriteBlocked();
-}
-
-void QuicPacketWriterWrapper::SetWritable() {
- writer_->SetWritable();
-}
-
-QuicByteCount QuicPacketWriterWrapper::GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const {
- return writer_->GetMaxPacketSize(peer_address);
-}
-
-void QuicPacketWriterWrapper::set_writer(QuicPacketWriter* writer) {
- writer_.reset(writer);
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_packet_writer_wrapper.h b/chromium/net/tools/quic/quic_packet_writer_wrapper.h
deleted file mode 100644
index 72273181fcb..00000000000
--- a/chromium/net/tools/quic/quic_packet_writer_wrapper.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2014 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_TOOLS_QUIC_QUIC_PACKET_WRITER_WRAPPER_H_
-#define NET_TOOLS_QUIC_QUIC_PACKET_WRITER_WRAPPER_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_packet_writer.h"
-
-namespace net {
-
-// Wraps a writer object to allow dynamically extending functionality. Use
-// cases: replace writer while dispatcher and connections hold on to the
-// wrapper; mix in monitoring; mix in mocks in unit tests.
-class QuicPacketWriterWrapper : public QuicPacketWriter {
- public:
- QuicPacketWriterWrapper();
- ~QuicPacketWriterWrapper() override;
-
- // Default implementation of the QuicPacketWriter interface. Passes everything
- // to |writer_|.
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
- bool IsWriteBlockedDataBuffered() const override;
- bool IsWriteBlocked() const override;
- void SetWritable() override;
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override;
-
- // Takes ownership of |writer|.
- void set_writer(QuicPacketWriter* writer);
-
- virtual void set_peer_address(const QuicSocketAddress& peer_address) {}
-
- QuicPacketWriter* writer() { return writer_.get(); }
-
- private:
- std::unique_ptr<QuicPacketWriter> writer_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicPacketWriterWrapper);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_PACKET_WRITER_WRAPPER_H_
diff --git a/chromium/net/tools/quic/quic_per_connection_packet_writer.cc b/chromium/net/tools/quic/quic_per_connection_packet_writer.cc
deleted file mode 100644
index c9d3b514c3c..00000000000
--- a/chromium/net/tools/quic/quic_per_connection_packet_writer.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 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/tools/quic/quic_per_connection_packet_writer.h"
-
-namespace net {
-
-QuicPerConnectionPacketWriter::QuicPerConnectionPacketWriter(
- QuicPacketWriter* shared_writer)
- : shared_writer_(shared_writer) {}
-
-QuicPerConnectionPacketWriter::~QuicPerConnectionPacketWriter() = default;
-
-WriteResult QuicPerConnectionPacketWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- return shared_writer_->WritePacket(buffer, buf_len, self_address,
- peer_address, options);
-}
-
-bool QuicPerConnectionPacketWriter::IsWriteBlockedDataBuffered() const {
- return shared_writer_->IsWriteBlockedDataBuffered();
-}
-
-bool QuicPerConnectionPacketWriter::IsWriteBlocked() const {
- return shared_writer_->IsWriteBlocked();
-}
-
-void QuicPerConnectionPacketWriter::SetWritable() {
- shared_writer_->SetWritable();
-}
-
-QuicByteCount QuicPerConnectionPacketWriter::GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const {
- return shared_writer_->GetMaxPacketSize(peer_address);
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_per_connection_packet_writer.h b/chromium/net/tools/quic/quic_per_connection_packet_writer.h
deleted file mode 100644
index 35e9131460e..00000000000
--- a/chromium/net/tools/quic/quic_per_connection_packet_writer.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 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_TOOLS_QUIC_QUIC_PER_CONNECTION_PACKET_WRITER_H_
-#define NET_TOOLS_QUIC_QUIC_PER_CONNECTION_PACKET_WRITER_H_
-
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_packet_writer.h"
-
-namespace net {
-
-// A connection-specific packet writer that wraps a shared writer.
-class QuicPerConnectionPacketWriter : public QuicPacketWriter {
- public:
- // Does not take ownership of |shared_writer|.
- explicit QuicPerConnectionPacketWriter(QuicPacketWriter* shared_writer);
- ~QuicPerConnectionPacketWriter() override;
-
- // Default implementation of the QuicPacketWriter interface: Passes everything
- // to |shared_writer_|.
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
- bool IsWriteBlockedDataBuffered() const override;
- bool IsWriteBlocked() const override;
- void SetWritable() override;
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override;
-
- private:
- QuicPacketWriter* shared_writer_; // Not owned.
-
- DISALLOW_COPY_AND_ASSIGN(QuicPerConnectionPacketWriter);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_PER_CONNECTION_PACKET_WRITER_H_
diff --git a/chromium/net/tools/quic/quic_process_packet_interface.h b/chromium/net/tools/quic/quic_process_packet_interface.h
deleted file mode 100644
index e960788d4c2..00000000000
--- a/chromium/net/tools/quic/quic_process_packet_interface.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 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_TOOLS_QUIC_QUIC_PROCESS_PACKET_INTERFACE_H_
-#define NET_TOOLS_QUIC_QUIC_PROCESS_PACKET_INTERFACE_H_
-
-#include "base/macros.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-
-namespace net {
-
-// A class to process each incoming packet.
-class ProcessPacketInterface {
- public:
- virtual ~ProcessPacketInterface() {}
- virtual void ProcessPacket(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const QuicReceivedPacket& packet) = 0;
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_PROCESS_PACKET_INTERFACE_H_
diff --git a/chromium/net/tools/quic/quic_reject_reason_decoder_bin.cc b/chromium/net/tools/quic/quic_reject_reason_decoder_bin.cc
deleted file mode 100644
index 96d63e6656f..00000000000
--- a/chromium/net/tools/quic/quic_reject_reason_decoder_bin.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2016 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.
-
-// Decodes the packet HandshakeFailureReason from the chromium histogram
-// Net.QuicClientHelloRejectReasons
-
-#include <iostream>
-
-#include "base/command_line.h"
-#include "base/strings/string_number_conversions.h"
-#include "net/quic/core/crypto/crypto_handshake.h"
-#include "net/quic/core/crypto/crypto_utils.h"
-
-using base::CommandLine;
-using net::HandshakeFailureReason;
-using net::CryptoUtils;
-using net::MAX_FAILURE_REASON;
-
-int main(int argc, char* argv[]) {
- CommandLine::Init(argc, argv);
- CommandLine* line = CommandLine::ForCurrentProcess();
- const CommandLine::StringVector& args = line->GetArgs();
-
- if (args.size() != 1) {
- std::cerr << "Missing argument (Usage: " << argv[0] << " <packed_reason>\n";
- return 1;
- }
-
- uint32_t packed_error = 0;
- if (!base::StringToUint(args[0], &packed_error)) {
- std::cerr << "Unable to parse: " << args[0] << "\n";
- return 2;
- }
-
- for (int i = 1; i < MAX_FAILURE_REASON; ++i) {
- if ((packed_error & (1 << (i - 1))) == 0) {
- continue;
- }
- HandshakeFailureReason reason = static_cast<HandshakeFailureReason>(i);
- std::cout << CryptoUtils::HandshakeFailureReasonToString(reason) << "\n";
- }
- return 0;
-}
diff --git a/chromium/net/tools/quic/quic_server.cc b/chromium/net/tools/quic/quic_server.cc
deleted file mode 100644
index 45269bdd489..00000000000
--- a/chromium/net/tools/quic/quic_server.cc
+++ /dev/null
@@ -1,213 +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/tools/quic/quic_server.h"
-
-#include <errno.h>
-#include <features.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-
-#include <memory>
-
-#include "net/quic/core/crypto/crypto_handshake.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_crypto_stream.h"
-#include "net/quic/core/quic_data_reader.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/tls_server_handshaker.h"
-#include "net/quic/platform/api/quic_clock.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/tools/quic/platform/impl/quic_epoll_clock.h"
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-#include "net/tools/quic/quic_dispatcher.h"
-#include "net/tools/quic/quic_epoll_alarm_factory.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-#include "net/tools/quic/quic_packet_reader.h"
-#include "net/tools/quic/quic_simple_crypto_server_stream_helper.h"
-#include "net/tools/quic/quic_simple_dispatcher.h"
-
-#ifndef SO_RXQ_OVFL
-#define SO_RXQ_OVFL 40
-#endif
-
-namespace net {
-
-namespace {
-
-// Specifies the directory used during QuicHttpResponseCache
-// construction to seed the cache. Cache directory can be
-// generated using `wget -p --save-headers <url>`
-std::string FLAGS_quic_response_cache_dir = "";
-
-const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
-const char kSourceAddressTokenSecret[] = "secret";
-
-} // namespace
-
-const size_t kNumSessionsToCreatePerSocketEvent = 16;
-
-QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
- QuicHttpResponseCache* response_cache)
- : QuicServer(std::move(proof_source),
- QuicConfig(),
- QuicCryptoServerConfig::ConfigOptions(),
- AllSupportedVersions(),
- response_cache) {}
-
-QuicServer::QuicServer(
- std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
- const ParsedQuicVersionVector& supported_versions,
- QuicHttpResponseCache* response_cache)
- : port_(0),
- fd_(-1),
- packets_dropped_(0),
- overflow_supported_(false),
- silent_close_(false),
- config_(config),
- crypto_config_(kSourceAddressTokenSecret,
- QuicRandom::GetInstance(),
- std::move(proof_source),
- TlsServerHandshaker::CreateSslCtx()),
- crypto_config_options_(crypto_config_options),
- version_manager_(supported_versions),
- packet_reader_(new QuicPacketReader()),
- response_cache_(response_cache) {
- Initialize();
-}
-
-void QuicServer::Initialize() {
- // If an initial flow control window has not explicitly been set, then use a
- // sensible value for a server: 1 MB for session, 64 KB for each stream.
- const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
- const uint32_t kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
- if (config_.GetInitialStreamFlowControlWindowToSend() ==
- kMinimumFlowControlSendWindow) {
- config_.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindow);
- }
- if (config_.GetInitialSessionFlowControlWindowToSend() ==
- kMinimumFlowControlSendWindow) {
- config_.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindow);
- }
-
- epoll_server_.set_timeout_in_us(50 * 1000);
-
- if (!FLAGS_quic_response_cache_dir.empty()) {
- response_cache_->InitializeFromDirectory(FLAGS_quic_response_cache_dir);
- }
-
- QuicEpollClock clock(&epoll_server_);
-
- std::unique_ptr<CryptoHandshakeMessage> scfg(crypto_config_.AddDefaultConfig(
- QuicRandom::GetInstance(), &clock, crypto_config_options_));
-}
-
-QuicServer::~QuicServer() = default;
-
-bool QuicServer::CreateUDPSocketAndListen(const QuicSocketAddress& address) {
- fd_ = QuicSocketUtils::CreateUDPSocket(
- address,
- /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer, &overflow_supported_);
- if (fd_ < 0) {
- QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
- return false;
- }
-
- sockaddr_storage addr = address.generic_address();
- int rc = bind(fd_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
- if (rc < 0) {
- QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
- return false;
- }
- QUIC_LOG(INFO) << "Listening on " << address.ToString();
- port_ = address.port();
- if (port_ == 0) {
- QuicSocketAddress address;
- if (address.FromSocket(fd_) != 0) {
- QUIC_LOG(ERROR) << "Unable to get self address. Error: "
- << strerror(errno);
- }
- port_ = address.port();
- }
-
- epoll_server_.RegisterFD(fd_, this, kEpollFlags);
- dispatcher_.reset(CreateQuicDispatcher());
- dispatcher_->InitializeWithWriter(CreateWriter(fd_));
-
- return true;
-}
-
-QuicDefaultPacketWriter* QuicServer::CreateWriter(int fd) {
- return new QuicDefaultPacketWriter(fd);
-}
-
-QuicDispatcher* QuicServer::CreateQuicDispatcher() {
- QuicEpollAlarmFactory alarm_factory(&epoll_server_);
- return new QuicSimpleDispatcher(
- config_, &crypto_config_, &version_manager_,
- std::unique_ptr<QuicEpollConnectionHelper>(new QuicEpollConnectionHelper(
- &epoll_server_, QuicAllocator::BUFFER_POOL)),
- std::unique_ptr<QuicCryptoServerStream::Helper>(
- new QuicSimpleCryptoServerStreamHelper(QuicRandom::GetInstance())),
- std::unique_ptr<QuicEpollAlarmFactory>(
- new QuicEpollAlarmFactory(&epoll_server_)),
- response_cache_);
-}
-
-void QuicServer::WaitForEvents() {
- epoll_server_.WaitForEventsAndExecuteCallbacks();
-}
-
-void QuicServer::Shutdown() {
- if (!silent_close_) {
- // Before we shut down the epoll server, give all active sessions a chance
- // to notify clients that they're closing.
- dispatcher_->Shutdown();
- }
-
- close(fd_);
- fd_ = -1;
-}
-
-void QuicServer::OnEvent(int fd, EpollEvent* event) {
- DCHECK_EQ(fd, fd_);
- event->out_ready_mask = 0;
-
- if (event->in_events & EPOLLIN) {
- QUIC_DVLOG(1) << "EPOLLIN";
-
- dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent);
-
- bool more_to_read = true;
- while (more_to_read) {
- more_to_read = packet_reader_->ReadAndDispatchPackets(
- fd_, port_, QuicEpollClock(&epoll_server_), dispatcher_.get(),
- overflow_supported_ ? &packets_dropped_ : nullptr);
- }
-
- if (dispatcher_->HasChlosBuffered()) {
- // Register EPOLLIN event to consume buffered CHLO(s).
- event->out_ready_mask |= EPOLLIN;
- }
- }
- if (event->in_events & EPOLLOUT) {
- dispatcher_->OnCanWrite();
- if (dispatcher_->HasPendingWrites()) {
- event->out_ready_mask |= EPOLLOUT;
- }
- }
- if (event->in_events & EPOLLERR) {
- }
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_server.h b/chromium/net/tools/quic/quic_server.h
deleted file mode 100644
index e284941dc4d..00000000000
--- a/chromium/net/tools/quic/quic_server.h
+++ /dev/null
@@ -1,144 +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.
-//
-// A toy server, which listens on a specified address for QUIC traffic and
-// handles incoming responses.
-//
-// Note that this server is intended to verify correctness of the client and is
-// in no way expected to be performant.
-
-#ifndef NET_TOOLS_QUIC_QUIC_SERVER_H_
-#define NET_TOOLS_QUIC_QUIC_SERVER_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "net/quic/chromium/quic_chromium_connection_helper.h"
-#include "net/quic/core/crypto/quic_crypto_server_config.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/core/quic_version_manager.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/quic_default_packet_writer.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-
-namespace net {
-
-namespace test {
-class QuicServerPeer;
-} // namespace test
-
-class QuicDispatcher;
-class QuicPacketReader;
-
-class QuicServer : public EpollCallbackInterface {
- public:
- QuicServer(std::unique_ptr<ProofSource> proof_source,
- QuicHttpResponseCache* response_cache);
- QuicServer(std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const QuicCryptoServerConfig::ConfigOptions& server_config_options,
- const ParsedQuicVersionVector& supported_versions,
- QuicHttpResponseCache* response_cache);
-
- ~QuicServer() override;
-
- // Start listening on the specified address.
- bool CreateUDPSocketAndListen(const QuicSocketAddress& address);
-
- // Wait up to 50ms, and handle any events which occur.
- void WaitForEvents();
-
- // Server deletion is imminent. Start cleaning up the epoll server.
- virtual void Shutdown();
-
- // From EpollCallbackInterface
- void OnRegistration(EpollServer* eps, int fd, int event_mask) override {}
- void OnModification(int fd, int event_mask) override {}
- void OnEvent(int fd, EpollEvent* event) override;
- void OnUnregistration(int fd, bool replaced) override {}
-
- void OnShutdown(EpollServer* eps, int fd) override {}
-
- void SetChloMultiplier(size_t multiplier) {
- crypto_config_.set_chlo_multiplier(multiplier);
- }
-
- bool overflow_supported() { return overflow_supported_; }
-
- QuicPacketCount packets_dropped() { return packets_dropped_; }
-
- int port() { return port_; }
-
- protected:
- virtual QuicDefaultPacketWriter* CreateWriter(int fd);
-
- virtual QuicDispatcher* CreateQuicDispatcher();
-
- const QuicConfig& config() const { return config_; }
- const QuicCryptoServerConfig& crypto_config() const { return crypto_config_; }
- EpollServer* epoll_server() { return &epoll_server_; }
-
- QuicDispatcher* dispatcher() { return dispatcher_.get(); }
-
- QuicVersionManager* version_manager() { return &version_manager_; }
-
- QuicHttpResponseCache* response_cache() { return response_cache_; }
-
- void set_silent_close(bool value) { silent_close_ = value; }
-
- private:
- friend class net::test::QuicServerPeer;
-
- // Initialize the internal state of the server.
- void Initialize();
-
- // Accepts data from the framer and demuxes clients to sessions.
- std::unique_ptr<QuicDispatcher> dispatcher_;
- // Frames incoming packets and hands them to the dispatcher.
- EpollServer epoll_server_;
-
- // The port the server is listening on.
- int port_;
-
- // Listening connection. Also used for outbound client communication.
- int fd_;
-
- // If overflow_supported_ is true this will be the number of packets dropped
- // during the lifetime of the server. This may overflow if enough packets
- // are dropped.
- QuicPacketCount packets_dropped_;
-
- // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
- // because the socket would otherwise overflow.
- bool overflow_supported_;
-
- // If true, do not call Shutdown on the dispatcher. Connections will close
- // without sending a final connection close.
- bool silent_close_;
-
- // config_ contains non-crypto parameters that are negotiated in the crypto
- // handshake.
- QuicConfig config_;
- // crypto_config_ contains crypto parameters for the handshake.
- QuicCryptoServerConfig crypto_config_;
- // crypto_config_options_ contains crypto parameters for the handshake.
- QuicCryptoServerConfig::ConfigOptions crypto_config_options_;
-
- // Used to generate current supported versions.
- QuicVersionManager version_manager_;
-
- // Point to a QuicPacketReader object on the heap. The reader allocates more
- // space than allowed on the stack.
- std::unique_ptr<QuicPacketReader> packet_reader_;
-
- QuicHttpResponseCache* response_cache_; // unowned.
-
- DISALLOW_COPY_AND_ASSIGN(QuicServer);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SERVER_H_
diff --git a/chromium/net/tools/quic/quic_server_bin.cc b/chromium/net/tools/quic/quic_server_bin.cc
deleted file mode 100644
index c3d2291b9cb..00000000000
--- a/chromium/net/tools/quic/quic_server_bin.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2014 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.
-//
-// A binary wrapper for QuicServer. It listens forever on --port
-// (default 6121) until it's killed or ctrl-cd to death.
-
-#include <iostream>
-
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/task_scheduler/task_scheduler.h"
-#include "net/quic/chromium/crypto/proof_source_chromium.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-#include "net/tools/quic/quic_server.h"
-
-// The port the quic server will listen on.
-int32_t FLAGS_port = 6121;
-
-std::unique_ptr<net::ProofSource> CreateProofSource(
- const base::FilePath& cert_path,
- const base::FilePath& key_path) {
- std::unique_ptr<net::ProofSourceChromium> proof_source(
- new net::ProofSourceChromium());
- CHECK(proof_source->Initialize(cert_path, key_path, base::FilePath()));
- return std::move(proof_source);
-}
-
-int main(int argc, char* argv[]) {
- base::AtExitManager exit_manager;
- base::CommandLine::Init(argc, argv);
- base::CommandLine* line = base::CommandLine::ForCurrentProcess();
-
- base::MessageLoopForIO message_loop;
- base::TaskScheduler::CreateAndStartWithDefaultParams("quic_server");
-
- logging::LoggingSettings settings;
- settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
- CHECK(logging::InitLogging(settings));
-
- if (line->HasSwitch("h") || line->HasSwitch("help")) {
- const char* help_str =
- "Usage: quic_server [options]\n"
- "\n"
- "Options:\n"
- "-h, --help show this help message and exit\n"
- "--port=<port> specify the port to listen on\n"
- "--quic_response_cache_dir directory containing response data\n"
- " to load\n"
- "--certificate_file=<file> path to the certificate chain\n"
- "--key_file=<file> path to the pkcs8 private key\n";
- std::cout << help_str;
- exit(0);
- }
-
- net::QuicHttpResponseCache response_cache;
- if (line->HasSwitch("quic_response_cache_dir")) {
- response_cache.InitializeFromDirectory(
- line->GetSwitchValueASCII("quic_response_cache_dir"));
- }
-
- if (line->HasSwitch("port")) {
- if (!base::StringToInt(line->GetSwitchValueASCII("port"), &FLAGS_port)) {
- LOG(ERROR) << "--port must be an integer\n";
- return 1;
- }
- }
-
- if (!line->HasSwitch("certificate_file")) {
- LOG(ERROR) << "missing --certificate_file";
- return 1;
- }
-
- if (!line->HasSwitch("key_file")) {
- LOG(ERROR) << "missing --key_file";
- return 1;
- }
-
- net::QuicConfig config;
- net::QuicServer server(
- CreateProofSource(line->GetSwitchValuePath("certificate_file"),
- line->GetSwitchValuePath("key_file")),
- config, net::QuicCryptoServerConfig::ConfigOptions(),
- net::AllSupportedVersions(), &response_cache);
-
- int rc = server.CreateUDPSocketAndListen(
- net::QuicSocketAddress(net::QuicIpAddress::Any6(), FLAGS_port));
- if (rc < 0) {
- return 1;
- }
-
- while (true) {
- server.WaitForEvents();
- }
-}
diff --git a/chromium/net/tools/quic/quic_server_test.cc b/chromium/net/tools/quic/quic_server_test.cc
deleted file mode 100644
index df80fa7d7b4..00000000000
--- a/chromium/net/tools/quic/quic_server_test.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2013 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/tools/quic/quic_server.h"
-
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/core/tls_server_handshaker.h"
-#include "net/quic/platform/api/quic_arraysize.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/platform/api/quic_test_loopback.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/mock_quic_dispatcher.h"
-#include "net/tools/quic/quic_epoll_alarm_factory.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-#include "net/tools/quic/quic_simple_crypto_server_stream_helper.h"
-#include "net/tools/quic/test_tools/quic_server_peer.h"
-
-using ::testing::_;
-
-namespace net {
-namespace test {
-
-namespace {
-
-class MockQuicSimpleDispatcher : public QuicSimpleDispatcher {
- public:
- MockQuicSimpleDispatcher(
- const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- QuicHttpResponseCache* response_cache)
- : QuicSimpleDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- response_cache) {}
- ~MockQuicSimpleDispatcher() override = default;
-
- MOCK_METHOD0(OnCanWrite, void());
- MOCK_CONST_METHOD0(HasPendingWrites, bool());
- MOCK_CONST_METHOD0(HasChlosBuffered, bool());
- MOCK_METHOD1(ProcessBufferedChlos, void(size_t));
-};
-
-class TestQuicServer : public QuicServer {
- public:
- TestQuicServer()
- : QuicServer(crypto_test_utils::ProofSourceForTesting(),
- &response_cache_) {}
-
- ~TestQuicServer() override = default;
-
- MockQuicSimpleDispatcher* mock_dispatcher() { return mock_dispatcher_; }
-
- protected:
- QuicDispatcher* CreateQuicDispatcher() override {
- mock_dispatcher_ = new MockQuicSimpleDispatcher(
- config(), &crypto_config(), version_manager(),
- std::unique_ptr<QuicEpollConnectionHelper>(
- new QuicEpollConnectionHelper(epoll_server(),
- QuicAllocator::BUFFER_POOL)),
- std::unique_ptr<QuicCryptoServerStream::Helper>(
- new QuicSimpleCryptoServerStreamHelper(QuicRandom::GetInstance())),
- std::unique_ptr<QuicEpollAlarmFactory>(
- new QuicEpollAlarmFactory(epoll_server())),
- &response_cache_);
- return mock_dispatcher_;
- }
-
- MockQuicSimpleDispatcher* mock_dispatcher_ = nullptr;
- QuicHttpResponseCache response_cache_;
-};
-
-class QuicServerEpollInTest : public QuicTest {
- public:
- QuicServerEpollInTest()
- : port_(net::test::kTestPort),
- server_address_(QuicIpAddress::Loopback4(), port_) {}
-
- void StartListening() {
- server_.CreateUDPSocketAndListen(server_address_);
- ASSERT_TRUE(QuicServerPeer::SetSmallSocket(&server_));
-
- if (!server_.overflow_supported()) {
- QUIC_LOG(WARNING) << "Overflow not supported. Not testing.";
- return;
- }
- }
-
- protected:
- int port_;
- QuicSocketAddress server_address_;
- TestQuicServer server_;
-};
-
-// Tests that if dispatcher has CHLOs waiting for connection creation, EPOLLIN
-// event should try to create connections for them. And set epoll mask with
-// EPOLLIN if there are still CHLOs remaining at the end of epoll event.
-TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
- // Given an EPOLLIN event, try to create session for buffered CHLOs. In first
- // event, dispatcher can't create session for all of CHLOs. So listener should
- // register another EPOLLIN event by itself. Even without new packet arrival,
- // the rest CHLOs should be process in next epoll event.
- StartListening();
- bool more_chlos = true;
- MockQuicSimpleDispatcher* dispatcher_ = server_.mock_dispatcher();
- DCHECK(dispatcher_ != nullptr);
- EXPECT_CALL(*dispatcher_, OnCanWrite()).Times(testing::AnyNumber());
- EXPECT_CALL(*dispatcher_, ProcessBufferedChlos(_)).Times(2);
- EXPECT_CALL(*dispatcher_, HasPendingWrites()).Times(testing::AnyNumber());
- // Expect there are still CHLOs buffered after 1st event. But not any more
- // after 2nd event.
- EXPECT_CALL(*dispatcher_, HasChlosBuffered())
- .WillOnce(testing::Return(true))
- .WillOnce(
- DoAll(testing::Assign(&more_chlos, false), testing::Return(false)));
-
- // Send a packet to trigger epoll event.
- int fd = socket(
- AddressFamilyUnderTest() == IpAddressFamily::IP_V4 ? AF_INET : AF_INET6,
- SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
- ASSERT_LT(0, fd);
-
- char buf[1024];
- memset(buf, 0, QUIC_ARRAYSIZE(buf));
- sockaddr_storage storage = server_address_.generic_address();
- int rc = sendto(fd, buf, QUIC_ARRAYSIZE(buf), 0,
- reinterpret_cast<sockaddr*>(&storage), sizeof(storage));
- if (rc < 0) {
- QUIC_DLOG(INFO) << errno << " " << strerror(errno);
- }
-
- while (more_chlos) {
- server_.WaitForEvents();
- }
-}
-
-class QuicServerDispatchPacketTest : public QuicTest {
- public:
- QuicServerDispatchPacketTest()
- : crypto_config_("blah",
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- TlsServerHandshaker::CreateSslCtx()),
- version_manager_(AllSupportedVersions()),
- dispatcher_(
- config_,
- &crypto_config_,
- &version_manager_,
- std::unique_ptr<QuicEpollConnectionHelper>(
- new QuicEpollConnectionHelper(&eps_,
- QuicAllocator::BUFFER_POOL)),
- std::unique_ptr<QuicCryptoServerStream::Helper>(
- new QuicSimpleCryptoServerStreamHelper(
- QuicRandom::GetInstance())),
- std::unique_ptr<QuicEpollAlarmFactory>(
- new QuicEpollAlarmFactory(&eps_)),
- &response_cache_) {
- dispatcher_.InitializeWithWriter(new QuicDefaultPacketWriter(1234));
- }
-
- void DispatchPacket(const QuicReceivedPacket& packet) {
- QuicSocketAddress client_addr, server_addr;
- dispatcher_.ProcessPacket(server_addr, client_addr, packet);
- }
-
- protected:
- QuicConfig config_;
- QuicCryptoServerConfig crypto_config_;
- QuicVersionManager version_manager_;
- EpollServer eps_;
- QuicHttpResponseCache response_cache_;
- MockQuicDispatcher dispatcher_;
-};
-
-TEST_F(QuicServerDispatchPacketTest, DispatchPacket) {
- // clang-format off
- unsigned char valid_packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00
- };
- // clang-format on
- QuicReceivedPacket encrypted_valid_packet(
- reinterpret_cast<char*>(valid_packet), QUIC_ARRAYSIZE(valid_packet),
- QuicTime::Zero(), false);
-
- EXPECT_CALL(dispatcher_, ProcessPacket(_, _, _)).Times(1);
- DispatchPacket(encrypted_valid_packet);
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_client.cc b/chromium/net/tools/quic/quic_simple_client.cc
index 1273c1bed19..dbd6fff4b4a 100644
--- a/chromium/net/tools/quic/quic_simple_client.cc
+++ b/chromium/net/tools/quic/quic_simple_client.cc
@@ -18,16 +18,16 @@
#include "net/quic/chromium/quic_chromium_connection_helper.h"
#include "net/quic/chromium/quic_chromium_packet_reader.h"
#include "net/quic/chromium/quic_chromium_packet_writer.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/socket/udp_client_socket.h"
-#include "net/spdy/chromium/spdy_http_utils.h"
-#include "net/spdy/core/spdy_header_block.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/third_party/quic/core/crypto/quic_random.h"
+#include "net/third_party/quic/core/quic_connection.h"
+#include "net/third_party/quic/core/quic_packets.h"
+#include "net/third_party/quic/core/quic_server_id.h"
+#include "net/third_party/quic/core/spdy_utils.h"
+#include "net/third_party/quic/platform/api/quic_flags.h"
+#include "net/third_party/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/spdy/core/spdy_header_block.h"
using std::string;
diff --git a/chromium/net/tools/quic/quic_simple_client.h b/chromium/net/tools/quic/quic_simple_client.h
index 8f17f68a1d9..d3329f6598d 100644
--- a/chromium/net/tools/quic/quic_simple_client.h
+++ b/chromium/net/tools/quic/quic_simple_client.h
@@ -20,11 +20,11 @@
#include "net/http/http_response_headers.h"
#include "net/log/net_log.h"
#include "net/quic/chromium/quic_chromium_packet_reader.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/core/quic_spdy_stream.h"
-#include "net/quic/platform/impl/quic_chromium_clock.h"
+#include "net/third_party/quic/core/quic_config.h"
+#include "net/third_party/quic/core/quic_spdy_stream.h"
+#include "net/third_party/quic/platform/impl/quic_chromium_clock.h"
+#include "net/third_party/quic/tools/quic_spdy_client_base.h"
#include "net/tools/quic/quic_client_message_loop_network_helper.h"
-#include "net/tools/quic/quic_spdy_client_base.h"
namespace net {
diff --git a/chromium/net/tools/quic/quic_simple_client_bin.cc b/chromium/net/tools/quic/quic_simple_client_bin.cc
index f14f2aacf34..f21ef04445c 100644
--- a/chromium/net/tools/quic/quic_simple_client_bin.cc
+++ b/chromium/net/tools/quic/quic_simple_client_bin.cc
@@ -48,34 +48,33 @@
#include "net/base/net_errors.h"
#include "net/base/privacy_mode.h"
#include "net/cert/cert_verifier.h"
-#include "net/cert/ct_known_logs.h"
#include "net/cert/ct_log_verifier.h"
+#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/http/transport_security_state.h"
#include "net/quic/chromium/crypto/proof_verifier_chromium.h"
-#include "net/quic/core/quic_error_codes.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_str_cat.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/spdy/chromium/spdy_http_utils.h"
-#include "net/spdy/core/spdy_header_block.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/third_party/quic/core/quic_error_codes.h"
+#include "net/third_party/quic/core/quic_packets.h"
+#include "net/third_party/quic/core/quic_server_id.h"
+#include "net/third_party/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quic/platform/api/quic_str_cat.h"
+#include "net/third_party/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/spdy/core/spdy_header_block.h"
#include "net/tools/quic/quic_simple_client.h"
#include "net/tools/quic/synchronous_host_resolver.h"
#include "url/gurl.h"
using net::CertVerifier;
-using net::CTPolicyEnforcer;
using net::CTVerifier;
using net::MultiLogCTVerifier;
using net::ProofVerifier;
using net::ProofVerifierChromium;
using net::QuicStringPiece;
using net::QuicTextUtils;
-using net::SpdyHeaderBlock;
using net::TransportSecurityState;
+using spdy::SpdyHeaderBlock;
using std::cout;
using std::cerr;
using std::endl;
@@ -266,8 +265,8 @@ int main(int argc, char* argv[]) {
std::unique_ptr<TransportSecurityState> transport_security_state(
new TransportSecurityState);
std::unique_ptr<MultiLogCTVerifier> ct_verifier(new MultiLogCTVerifier());
- ct_verifier->AddLogs(net::ct::CreateLogVerifiersForKnownLogs());
- std::unique_ptr<CTPolicyEnforcer> ct_policy_enforcer(new CTPolicyEnforcer());
+ std::unique_ptr<net::CTPolicyEnforcer> ct_policy_enforcer(
+ new net::DefaultCTPolicyEnforcer());
std::unique_ptr<ProofVerifier> proof_verifier;
if (line->HasSwitch("disable-certificate-verification")) {
proof_verifier.reset(new FakeProofVerifier());
diff --git a/chromium/net/tools/quic/quic_simple_client_test.cc b/chromium/net/tools/quic/quic_simple_client_test.cc
index 16ff1bfa337..39ccbe63625 100644
--- a/chromium/net/tools/quic/quic_simple_client_test.cc
+++ b/chromium/net/tools/quic/quic_simple_client_test.cc
@@ -5,14 +5,16 @@
#include "net/tools/quic/quic_simple_client.h"
#include "base/strings/string_util.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_test_utils.h"
+#include "base/test/scoped_task_environment.h"
+#include "net/third_party/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quic/test_tools/quic_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace test {
TEST(QuicSimpleClientTest, Initialize) {
+ base::test::ScopedTaskEnvironment scoped_task_environment;
QuicSocketAddress server_address(QuicIpAddress::Loopback4(), 80);
QuicServerId server_id("hostname", server_address.port(),
PRIVACY_MODE_DISABLED);
diff --git a/chromium/net/tools/quic/quic_simple_crypto_server_stream_helper.cc b/chromium/net/tools/quic/quic_simple_crypto_server_stream_helper.cc
deleted file mode 100644
index 56afbf82dd4..00000000000
--- a/chromium/net/tools/quic/quic_simple_crypto_server_stream_helper.cc
+++ /dev/null
@@ -1,29 +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/tools/quic/quic_simple_crypto_server_stream_helper.h"
-
-namespace net {
-
-QuicSimpleCryptoServerStreamHelper::QuicSimpleCryptoServerStreamHelper(
- QuicRandom* random)
- : random_(random) {}
-
-QuicSimpleCryptoServerStreamHelper::~QuicSimpleCryptoServerStreamHelper() =
- default;
-
-QuicConnectionId
-QuicSimpleCryptoServerStreamHelper::GenerateConnectionIdForReject(
- QuicConnectionId /*connection_id*/) const {
- return random_->RandUint64();
-}
-
-bool QuicSimpleCryptoServerStreamHelper::CanAcceptClientHello(
- const CryptoHandshakeMessage& message,
- const QuicSocketAddress& self_address,
- std::string* error_details) const {
- return true;
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_crypto_server_stream_helper.h b/chromium/net/tools/quic/quic_simple_crypto_server_stream_helper.h
deleted file mode 100644
index 31c257df395..00000000000
--- a/chromium/net/tools/quic/quic_simple_crypto_server_stream_helper.h
+++ /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.
-
-#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
-#define NET_TOOLS_QUIC_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
-
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_crypto_server_stream.h"
-
-namespace net {
-
-// Simple helper for server crypto streams which generates a new random
-// connection ID for stateless rejects.
-class QuicSimpleCryptoServerStreamHelper
- : public QuicCryptoServerStream::Helper {
- public:
- explicit QuicSimpleCryptoServerStreamHelper(QuicRandom* random);
-
- ~QuicSimpleCryptoServerStreamHelper() override;
-
- QuicConnectionId GenerateConnectionIdForReject(
- QuicConnectionId /*connection_id*/) const override;
-
- bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
- const QuicSocketAddress& self_address,
- std::string* error_details) const override;
-
- private:
- QuicRandom* random_; // Unowned.
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
diff --git a/chromium/net/tools/quic/quic_simple_dispatcher.cc b/chromium/net/tools/quic/quic_simple_dispatcher.cc
deleted file mode 100644
index 1f64cb5d6f4..00000000000
--- a/chromium/net/tools/quic/quic_simple_dispatcher.cc
+++ /dev/null
@@ -1,66 +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/tools/quic/quic_simple_dispatcher.h"
-
-#include "net/tools/quic/quic_simple_server_session.h"
-
-namespace net {
-
-QuicSimpleDispatcher::QuicSimpleDispatcher(
- const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- QuicHttpResponseCache* response_cache)
- : QuicDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory)),
- response_cache_(response_cache) {}
-
-QuicSimpleDispatcher::~QuicSimpleDispatcher() = default;
-
-int QuicSimpleDispatcher::GetRstErrorCount(
- QuicRstStreamErrorCode error_code) const {
- auto it = rst_error_map_.find(error_code);
- if (it == rst_error_map_.end()) {
- return 0;
- } else {
- return it->second;
- }
-}
-
-void QuicSimpleDispatcher::OnRstStreamReceived(
- const QuicRstStreamFrame& frame) {
- auto it = rst_error_map_.find(frame.error_code);
- if (it == rst_error_map_.end()) {
- rst_error_map_.insert(std::make_pair(frame.error_code, 1));
- } else {
- it->second++;
- }
-}
-
-QuicServerSessionBase* QuicSimpleDispatcher::CreateQuicSession(
- QuicConnectionId connection_id,
- const QuicSocketAddress& client_address,
- QuicStringPiece /*alpn*/) {
- // The QuicServerSessionBase takes ownership of |connection| below.
- QuicConnection* connection = new QuicConnection(
- connection_id, client_address, helper(), alarm_factory(),
- CreatePerConnectionWriter(),
- /* owns_writer= */ true, Perspective::IS_SERVER, GetSupportedVersions());
-
- QuicServerSessionBase* session = new QuicSimpleServerSession(
- config(), connection, this, session_helper(), crypto_config(),
- compressed_certs_cache(), response_cache_);
- session->Initialize();
- return session;
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_dispatcher.h b/chromium/net/tools/quic/quic_simple_dispatcher.h
deleted file mode 100644
index 04e1252684b..00000000000
--- a/chromium/net/tools/quic/quic_simple_dispatcher.h
+++ /dev/null
@@ -1,48 +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_TOOLS_QUIC_QUIC_SIMPLE_DISPATCHER_H_
-#define NET_TOOLS_QUIC_QUIC_SIMPLE_DISPATCHER_H_
-
-#include "net/quic/core/quic_server_session_base.h"
-#include "net/tools/quic/quic_dispatcher.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-
-namespace net {
-
-class QuicSimpleDispatcher : public QuicDispatcher {
- public:
- QuicSimpleDispatcher(
- const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- QuicHttpResponseCache* response_cache);
-
- ~QuicSimpleDispatcher() override;
-
- int GetRstErrorCount(QuicRstStreamErrorCode rst_error_code) const;
-
- void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
-
- protected:
- QuicServerSessionBase* CreateQuicSession(
- QuicConnectionId connection_id,
- const QuicSocketAddress& client_address,
- QuicStringPiece alpn) override;
-
- QuicHttpResponseCache* response_cache() { return response_cache_; }
-
- private:
- QuicHttpResponseCache* response_cache_; // Unowned.
-
- // The map of the reset error code with its counter.
- std::map<QuicRstStreamErrorCode, int> rst_error_map_;
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_DISPATCHER_H_
diff --git a/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h b/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h
index 4c6710ce2c2..7e5132e59b5 100644
--- a/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h
+++ b/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h
@@ -9,8 +9,8 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_packet_writer.h"
+#include "net/third_party/quic/core/quic_connection.h"
+#include "net/third_party/quic/core/quic_packet_writer.h"
namespace net {
diff --git a/chromium/net/tools/quic/quic_simple_server.cc b/chromium/net/tools/quic/quic_simple_server.cc
index 6526e6ce6bb..1e990db9af1 100644
--- a/chromium/net/tools/quic/quic_simple_server.cc
+++ b/chromium/net/tools/quic/quic_simple_server.cc
@@ -12,14 +12,14 @@
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_source.h"
-#include "net/quic/core/crypto/crypto_handshake.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_crypto_stream.h"
-#include "net/quic/core/quic_data_reader.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/tls_server_handshaker.h"
#include "net/socket/udp_server_socket.h"
-#include "net/tools/quic/quic_simple_dispatcher.h"
+#include "net/third_party/quic/core/crypto/crypto_handshake.h"
+#include "net/third_party/quic/core/crypto/quic_random.h"
+#include "net/third_party/quic/core/quic_crypto_stream.h"
+#include "net/third_party/quic/core/quic_data_reader.h"
+#include "net/third_party/quic/core/quic_packets.h"
+#include "net/third_party/quic/core/tls_server_handshaker.h"
+#include "net/third_party/quic/tools/quic_simple_dispatcher.h"
#include "net/tools/quic/quic_simple_per_connection_packet_writer.h"
#include "net/tools/quic/quic_simple_server_packet_writer.h"
#include "net/tools/quic/quic_simple_server_session_helper.h"
@@ -42,7 +42,7 @@ QuicSimpleServer::QuicSimpleServer(
const QuicConfig& config,
const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
const ParsedQuicVersionVector& supported_versions,
- QuicHttpResponseCache* response_cache)
+ QuicSimpleServerBackend* quic_simple_server_backend)
: version_manager_(supported_versions),
helper_(
new QuicChromiumConnectionHelper(&clock_, QuicRandom::GetInstance())),
@@ -58,7 +58,7 @@ QuicSimpleServer::QuicSimpleServer(
read_pending_(false),
synchronous_read_count_(0),
read_buffer_(new IOBufferWithSize(kReadBufferSize)),
- response_cache_(response_cache),
+ quic_simple_server_backend_(quic_simple_server_backend),
weak_factory_(this) {
Initialize();
}
@@ -133,7 +133,8 @@ int QuicSimpleServer::Listen(const IPEndPoint& address) {
std::unique_ptr<QuicConnectionHelperInterface>(helper_),
std::unique_ptr<QuicCryptoServerStream::Helper>(
new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())),
- std::unique_ptr<QuicAlarmFactory>(alarm_factory_), response_cache_));
+ std::unique_ptr<QuicAlarmFactory>(alarm_factory_),
+ quic_simple_server_backend_));
QuicSimpleServerPacketWriter* writer =
new QuicSimpleServerPacketWriter(socket_.get(), dispatcher_.get());
dispatcher_->InitializeWithWriter(writer);
diff --git a/chromium/net/tools/quic/quic_simple_server.h b/chromium/net/tools/quic/quic_simple_server.h
index b72d967e8da..faae4fb4f75 100644
--- a/chromium/net/tools/quic/quic_simple_server.h
+++ b/chromium/net/tools/quic/quic_simple_server.h
@@ -16,11 +16,11 @@
#include "net/log/net_log.h"
#include "net/quic/chromium/quic_chromium_alarm_factory.h"
#include "net/quic/chromium/quic_chromium_connection_helper.h"
-#include "net/quic/core/crypto/quic_crypto_server_config.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/core/quic_version_manager.h"
-#include "net/quic/platform/impl/quic_chromium_clock.h"
-#include "net/tools/quic/quic_http_response_cache.h"
+#include "net/third_party/quic/core/crypto/quic_crypto_server_config.h"
+#include "net/third_party/quic/core/quic_config.h"
+#include "net/third_party/quic/core/quic_version_manager.h"
+#include "net/third_party/quic/platform/impl/quic_chromium_clock.h"
+#include "net/third_party/quic/tools/quic_simple_server_backend.h"
namespace net {
@@ -40,7 +40,7 @@ class QuicSimpleServer {
const QuicConfig& config,
const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
const ParsedQuicVersionVector& supported_versions,
- QuicHttpResponseCache* response_cache);
+ QuicSimpleServerBackend* quic_simple_server_backend);
virtual ~QuicSimpleServer();
@@ -114,7 +114,7 @@ class QuicSimpleServer {
// The log to use for the socket.
NetLog net_log_;
- QuicHttpResponseCache* response_cache_;
+ QuicSimpleServerBackend* quic_simple_server_backend_;
base::WeakPtrFactory<QuicSimpleServer> weak_factory_;
diff --git a/chromium/net/tools/quic/quic_simple_server_bin.cc b/chromium/net/tools/quic/quic_simple_server_bin.cc
index e7c44d2553c..57c4f1a9c7a 100644
--- a/chromium/net/tools/quic/quic_simple_server_bin.cc
+++ b/chromium/net/tools/quic/quic_simple_server_bin.cc
@@ -17,12 +17,18 @@
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/chromium/crypto/proof_source_chromium.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/tools/quic/quic_http_response_cache.h"
+#include "net/third_party/quic/core/quic_packets.h"
+#include "net/third_party/quic/tools/quic_memory_cache_backend.h"
#include "net/tools/quic/quic_simple_server.h"
// The port the quic server will listen on.
int32_t FLAGS_port = 6121;
+// Mode of operations: currently only support in-memory cache
+std::string FLAGS_quic_mode = "cache";
+// Specifies the directory used during QuicHttpResponseCache
+// construction to seed the cache. Cache directory can be
+// generated using `wget -p --save-headers <url>`
+std::string FLAGS_quic_response_cache_dir = "";
std::unique_ptr<net::ProofSource> CreateProofSource(
const base::FilePath& cert_path,
@@ -52,18 +58,37 @@ int main(int argc, char* argv[]) {
"Options:\n"
"-h, --help show this help message and exit\n"
"--port=<port> specify the port to listen on\n"
- "--quic_response_cache_dir directory containing response data\n"
- " to load\n"
+ "--mode=<cache> Default: cache\n"
+ " Specify mode of operation: Cache will "
+ "serve it "
+ "from a cache dir\n"
+ "--quic_response_cache_dir=<directory>\n"
+ " The directory containing cached response "
+ "data to load\n"
"--certificate_file=<file> path to the certificate chain\n"
"--key_file=<file> path to the pkcs8 private key\n";
std::cout << help_str;
exit(0);
}
- net::QuicHttpResponseCache response_cache;
- if (line->HasSwitch("quic_response_cache_dir")) {
- response_cache.InitializeFromDirectory(
- line->GetSwitchValueASCII("quic_response_cache_dir"));
+ net::QuicMemoryCacheBackend memory_cache_backend;
+ if (line->HasSwitch("mode")) {
+ FLAGS_quic_mode = line->GetSwitchValueASCII("mode");
+ }
+ if (FLAGS_quic_mode.compare("cache") == 0) {
+ if (line->HasSwitch("quic_response_cache_dir")) {
+ FLAGS_quic_response_cache_dir =
+ line->GetSwitchValueASCII("quic_response_cache_dir");
+ if (FLAGS_quic_response_cache_dir.empty() ||
+ memory_cache_backend.InitializeBackend(
+ FLAGS_quic_response_cache_dir) != true) {
+ LOG(ERROR) << "--quic_response_cache_dir is not valid !";
+ return 1;
+ }
+ }
+ } else {
+ LOG(ERROR) << "unknown --mode. cache is a valid mode of operation";
+ return 1;
}
if (line->HasSwitch("port")) {
@@ -90,7 +115,7 @@ int main(int argc, char* argv[]) {
CreateProofSource(line->GetSwitchValuePath("certificate_file"),
line->GetSwitchValuePath("key_file")),
config, net::QuicCryptoServerConfig::ConfigOptions(),
- net::AllSupportedVersions(), &response_cache);
+ net::AllSupportedVersions(), &memory_cache_backend);
int rc = server.Listen(net::IPEndPoint(ip, FLAGS_port));
if (rc < 0) {
diff --git a/chromium/net/tools/quic/quic_simple_server_packet_writer.cc b/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
index 15b24ca664f..c20b835bb0f 100644
--- a/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
+++ b/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
@@ -11,7 +11,7 @@
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/socket/udp_server_socket.h"
-#include "net/tools/quic/quic_dispatcher.h"
+#include "net/third_party/quic/core/quic_dispatcher.h"
namespace net {
diff --git a/chromium/net/tools/quic/quic_simple_server_packet_writer.h b/chromium/net/tools/quic/quic_simple_server_packet_writer.h
index b3bf6dbb785..5b266aa6914 100644
--- a/chromium/net/tools/quic/quic_simple_server_packet_writer.h
+++ b/chromium/net/tools/quic/quic_simple_server_packet_writer.h
@@ -10,9 +10,9 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_packet_writer.h"
-#include "net/quic/core/quic_packets.h"
+#include "net/third_party/quic/core/quic_connection.h"
+#include "net/third_party/quic/core/quic_packet_writer.h"
+#include "net/third_party/quic/core/quic_packets.h"
namespace net {
diff --git a/chromium/net/tools/quic/quic_simple_server_session.cc b/chromium/net/tools/quic/quic_simple_server_session.cc
deleted file mode 100644
index bc9ae358280..00000000000
--- a/chromium/net/tools/quic/quic_simple_server_session.cc
+++ /dev/null
@@ -1,210 +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/tools/quic/quic_simple_server_session.h"
-
-#include <utility>
-
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/tools/quic/quic_simple_server_stream.h"
-
-using std::string;
-
-namespace net {
-
-QuicSimpleServerSession::QuicSimpleServerSession(
- const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStream::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicHttpResponseCache* response_cache)
- : QuicServerSessionBase(config,
- connection,
- visitor,
- helper,
- crypto_config,
- compressed_certs_cache),
- highest_promised_stream_id_(0),
- response_cache_(response_cache) {}
-
-QuicSimpleServerSession::~QuicSimpleServerSession() {
- delete connection();
-}
-
-QuicCryptoServerStreamBase*
-QuicSimpleServerSession::CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) {
- return new QuicCryptoServerStream(
- crypto_config, compressed_certs_cache,
- GetQuicReloadableFlag(enable_quic_stateless_reject_support), this,
- stream_helper());
-}
-
-void QuicSimpleServerSession::StreamDraining(QuicStreamId id) {
- QuicSpdySession::StreamDraining(id);
- if (!IsIncomingStream(id)) {
- HandlePromisedPushRequests();
- }
-}
-
-void QuicSimpleServerSession::OnStreamFrame(const QuicStreamFrame& frame) {
- if (!IsIncomingStream(frame.stream_id)) {
- QUIC_LOG(WARNING) << "Client shouldn't send data on server push stream";
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Client sent data on server push stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
- QuicSpdySession::OnStreamFrame(frame);
-}
-
-void QuicSimpleServerSession::PromisePushResources(
- const string& request_url,
- const std::list<QuicHttpResponseCache::ServerPushInfo>& resources,
- QuicStreamId original_stream_id,
- const SpdyHeaderBlock& original_request_headers) {
- if (!server_push_enabled()) {
- return;
- }
-
- for (QuicHttpResponseCache::ServerPushInfo resource : resources) {
- SpdyHeaderBlock headers = SynthesizePushRequestHeaders(
- request_url, resource, original_request_headers);
- highest_promised_stream_id_ += 2;
- SendPushPromise(original_stream_id, highest_promised_stream_id_,
- headers.Clone());
- promised_streams_.push_back(PromisedStreamInfo(
- std::move(headers), highest_promised_stream_id_, resource.priority));
- }
-
- // Procese promised push request as many as possible.
- HandlePromisedPushRequests();
-}
-
-QuicSpdyStream* QuicSimpleServerSession::CreateIncomingDynamicStream(
- QuicStreamId id) {
- if (!ShouldCreateIncomingDynamicStream(id)) {
- return nullptr;
- }
-
- QuicSpdyStream* stream =
- new QuicSimpleServerStream(id, this, response_cache_);
- ActivateStream(QuicWrapUnique(stream));
- return stream;
-}
-
-QuicSimpleServerStream* QuicSimpleServerSession::CreateOutgoingDynamicStream() {
- if (!ShouldCreateOutgoingDynamicStream()) {
- return nullptr;
- }
-
- QuicSimpleServerStream* stream = new QuicSimpleServerStream(
- GetNextOutgoingStreamId(), this, response_cache_);
- ActivateStream(QuicWrapUnique(stream));
- return stream;
-}
-
-void QuicSimpleServerSession::CloseStreamInner(QuicStreamId stream_id,
- bool locally_reset) {
- QuicSpdySession::CloseStreamInner(stream_id, locally_reset);
- HandlePromisedPushRequests();
-}
-
-void QuicSimpleServerSession::HandleFrameOnNonexistentOutgoingStream(
- QuicStreamId stream_id) {
- // If this stream is a promised but not created stream (stream_id within the
- // range of next_outgoing_stream_id_ and highes_promised_stream_id_),
- // connection shouldn't be closed.
- // Otherwise behave in the same way as base class.
- if (stream_id > highest_promised_stream_id_) {
- QuicSession::HandleFrameOnNonexistentOutgoingStream(stream_id);
- }
-}
-
-void QuicSimpleServerSession::HandleRstOnValidNonexistentStream(
- const QuicRstStreamFrame& frame) {
- QuicSession::HandleRstOnValidNonexistentStream(frame);
- if (!IsClosedStream(frame.stream_id)) {
- // If a nonexistent stream is not a closed stream and still valid, it must
- // be a locally preserved stream. Resetting this kind of stream means
- // cancelling the promised server push.
- // Since PromisedStreamInfo are queued in sequence, the corresponding
- // index for it in promised_streams_ can be calculated.
- DCHECK(frame.stream_id >= next_outgoing_stream_id());
- size_t index = (frame.stream_id - next_outgoing_stream_id()) / 2;
- DCHECK(index <= promised_streams_.size());
- promised_streams_[index].is_cancelled = true;
- control_frame_manager().WriteOrBufferRstStream(frame.stream_id,
- QUIC_RST_ACKNOWLEDGEMENT, 0);
- connection()->OnStreamReset(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT);
- }
-}
-
-SpdyHeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders(
- string request_url,
- QuicHttpResponseCache::ServerPushInfo resource,
- const SpdyHeaderBlock& original_request_headers) {
- QuicUrl push_request_url = resource.request_url;
-
- SpdyHeaderBlock spdy_headers = original_request_headers.Clone();
- // :authority could be different from original request.
- spdy_headers[":authority"] = push_request_url.host();
- spdy_headers[":path"] = push_request_url.path();
- ;
- // Push request always use GET.
- spdy_headers[":method"] = "GET";
- spdy_headers["referer"] = request_url;
- spdy_headers[":scheme"] = push_request_url.scheme();
- // It is not possible to push a response to a request that includes a request
- // body.
- spdy_headers["content-length"] = "0";
- // Remove "host" field as push request is a directly generated HTTP2 request
- // which should use ":authority" instead of "host".
- spdy_headers.erase("host");
- return spdy_headers;
-}
-
-void QuicSimpleServerSession::SendPushPromise(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- SpdyHeaderBlock headers) {
- QUIC_DLOG(INFO) << "stream " << original_stream_id
- << " send PUSH_PROMISE for promised stream "
- << promised_stream_id;
- WritePushPromise(original_stream_id, promised_stream_id, std::move(headers));
-}
-
-void QuicSimpleServerSession::HandlePromisedPushRequests() {
- while (!promised_streams_.empty() && ShouldCreateOutgoingDynamicStream()) {
- PromisedStreamInfo& promised_info = promised_streams_.front();
- DCHECK_EQ(next_outgoing_stream_id(), promised_info.stream_id);
-
- if (promised_info.is_cancelled) {
- // This stream has been reset by client. Skip this stream id.
- promised_streams_.pop_front();
- GetNextOutgoingStreamId();
- return;
- }
-
- QuicSimpleServerStream* promised_stream =
- static_cast<QuicSimpleServerStream*>(CreateOutgoingDynamicStream());
- DCHECK_NE(promised_stream, nullptr);
- DCHECK_EQ(promised_info.stream_id, promised_stream->id());
- QUIC_DLOG(INFO) << "created server push stream " << promised_stream->id();
-
- promised_stream->SetPriority(promised_info.priority);
-
- SpdyHeaderBlock request_headers(std::move(promised_info.request_headers));
-
- promised_streams_.pop_front();
- promised_stream->PushResponse(std::move(request_headers));
- }
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_server_session.h b/chromium/net/tools/quic/quic_simple_server_session.h
deleted file mode 100644
index f40dc0d184f..00000000000
--- a/chromium/net/tools/quic/quic_simple_server_session.h
+++ /dev/null
@@ -1,155 +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.
-//
-// A toy server specific QuicSession subclass.
-
-#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_
-#define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_
-
-#include <stdint.h>
-
-#include <list>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_crypto_server_stream.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_session_base.h"
-#include "net/quic/core/quic_spdy_session.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-#include "net/tools/quic/quic_simple_server_stream.h"
-
-namespace net {
-
-namespace test {
-class QuicSimpleServerSessionPeer;
-} // namespace test
-
-class QuicSimpleServerSession : public QuicServerSessionBase {
- public:
- // A PromisedStreamInfo is an element of the queue to store promised
- // stream which hasn't been created yet. It keeps a mapping between promised
- // stream id with its priority and the headers sent out in PUSH_PROMISE.
- struct PromisedStreamInfo {
- public:
- PromisedStreamInfo(SpdyHeaderBlock request_headers,
- QuicStreamId stream_id,
- SpdyPriority priority)
- : request_headers(std::move(request_headers)),
- stream_id(stream_id),
- priority(priority),
- is_cancelled(false) {}
- SpdyHeaderBlock request_headers;
- QuicStreamId stream_id;
- SpdyPriority priority;
- bool is_cancelled;
- };
-
- // Takes ownership of |connection|.
- QuicSimpleServerSession(const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStream::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicHttpResponseCache* response_cache);
-
- ~QuicSimpleServerSession() override;
-
- // When a stream is marked draining, it will decrease the number of open
- // streams. If it is an outgoing stream, try to open a new stream to send
- // remaing push responses.
- void StreamDraining(QuicStreamId id) override;
-
- // Override base class to detact client sending data on server push stream.
- void OnStreamFrame(const QuicStreamFrame& frame) override;
-
- // Send out PUSH_PROMISE for all |resources| promised stream id in each frame
- // will increase by 2 for each item in |resources|.
- // And enqueue HEADERS block in those PUSH_PROMISED for sending push response
- // later.
- virtual void PromisePushResources(
- const std::string& request_url,
- const std::list<QuicHttpResponseCache::ServerPushInfo>& resources,
- QuicStreamId original_stream_id,
- const SpdyHeaderBlock& original_request_headers);
-
- protected:
- // QuicSession methods:
- QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override;
- QuicSimpleServerStream* CreateOutgoingDynamicStream() override;
- // Closing an outgoing stream can reduce open outgoing stream count, try
- // to handle queued promised streams right now.
- void CloseStreamInner(QuicStreamId stream_id, bool locally_reset) override;
- // Override to return true for locally preserved server push stream.
- void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override;
- // Override to handle reseting locally preserved streams.
- void HandleRstOnValidNonexistentStream(
- const QuicRstStreamFrame& frame) override;
-
- // QuicServerSessionBaseMethod:
- QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) override;
-
- QuicHttpResponseCache* response_cache() { return response_cache_; }
-
- private:
- friend class test::QuicSimpleServerSessionPeer;
-
- // Create a server push headers block by copying request's headers block.
- // But replace or add these pseudo-headers as they are specific to each
- // request:
- // :authority, :path, :method, :scheme, referer.
- // Copying the rest headers ensures they are the same as the original
- // request, especially cookies.
- SpdyHeaderBlock SynthesizePushRequestHeaders(
- std::string request_url,
- QuicHttpResponseCache::ServerPushInfo resource,
- const SpdyHeaderBlock& original_request_headers);
-
- // Send PUSH_PROMISE frame on headers stream.
- void SendPushPromise(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- SpdyHeaderBlock headers);
-
- // Fetch response from cache for request headers enqueued into
- // promised_headers_and_streams_ and send them on dedicated stream until
- // reaches max_open_stream_ limit.
- // Called when return value of GetNumOpenOutgoingStreams() changes:
- // CloseStreamInner();
- // StreamDraining();
- // Note that updateFlowControlOnFinalReceivedByteOffset() won't change the
- // return value becasue all push streams are impossible to become locally
- // closed. Since a locally preserved stream becomes remotely closed after
- // HandlePromisedPushRequests() starts to process it, and if it is reset
- // locally afterwards, it will be immediately become closed and never get into
- // locally_closed_stream_highest_offset_. So all the streams in this map
- // are not outgoing streams.
- void HandlePromisedPushRequests();
-
- // Keep track of the highest stream id which has been sent in PUSH_PROMISE.
- QuicStreamId highest_promised_stream_id_;
-
- // Promised streams which hasn't been created yet because of max_open_stream_
- // limit. New element is added to the end of the queue.
- // Since outgoing stream is created in sequence, stream_id of each element in
- // the queue also increases by 2 from previous one's. The front element's
- // stream_id is always next_outgoing_stream_id_, and the last one is always
- // highest_promised_stream_id_.
- QuicDeque<PromisedStreamInfo> promised_streams_;
-
- QuicHttpResponseCache* response_cache_; // Not owned.
-
- DISALLOW_COPY_AND_ASSIGN(QuicSimpleServerSession);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_
diff --git a/chromium/net/tools/quic/quic_simple_server_session_helper.cc b/chromium/net/tools/quic/quic_simple_server_session_helper.cc
index 819553aeb4c..21a7977cd17 100644
--- a/chromium/net/tools/quic/quic_simple_server_session_helper.cc
+++ b/chromium/net/tools/quic/quic_simple_server_session_helper.cc
@@ -18,6 +18,8 @@ QuicConnectionId QuicSimpleServerSessionHelper::GenerateConnectionIdForReject(
bool QuicSimpleServerSessionHelper::CanAcceptClientHello(
const CryptoHandshakeMessage& message,
+ const QuicSocketAddress& client_address,
+ const QuicSocketAddress& peer_address,
const QuicSocketAddress& self_address,
std::string* error_details) const {
return true;
diff --git a/chromium/net/tools/quic/quic_simple_server_session_helper.h b/chromium/net/tools/quic/quic_simple_server_session_helper.h
index 00a3bf9c8bb..6ddd5d96dfd 100644
--- a/chromium/net/tools/quic/quic_simple_server_session_helper.h
+++ b/chromium/net/tools/quic/quic_simple_server_session_helper.h
@@ -5,8 +5,8 @@
#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_HELPER_H_
#define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_HELPER_H_
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_server_session_base.h"
+#include "net/third_party/quic/core/crypto/quic_random.h"
+#include "net/third_party/quic/core/quic_server_session_base.h"
namespace net {
@@ -22,6 +22,8 @@ class QuicSimpleServerSessionHelper : public QuicCryptoServerStream::Helper {
QuicConnectionId /*connection_id*/) const override;
bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
+ const QuicSocketAddress& client_address,
+ const QuicSocketAddress& peer_address,
const QuicSocketAddress& self_address,
std::string* error_details) const override;
diff --git a/chromium/net/tools/quic/quic_simple_server_session_helper_test.cc b/chromium/net/tools/quic/quic_simple_server_session_helper_test.cc
index c25c60e54a8..b2bd7a922a0 100644
--- a/chromium/net/tools/quic/quic_simple_server_session_helper_test.cc
+++ b/chromium/net/tools/quic/quic_simple_server_session_helper_test.cc
@@ -2,8 +2,8 @@
// 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/mock_random.h"
-#include "net/tools/quic/quic_simple_crypto_server_stream_helper.h"
+#include "net/third_party/quic/test_tools/mock_random.h"
+#include "net/third_party/quic/tools/quic_simple_crypto_server_stream_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/tools/quic/quic_simple_server_session_test.cc b/chromium/net/tools/quic/quic_simple_server_session_test.cc
deleted file mode 100644
index 124ff389a2b..00000000000
--- a/chromium/net/tools/quic/quic_simple_server_session_test.cc
+++ /dev/null
@@ -1,658 +0,0 @@
-// Copyright 2013 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/tools/quic/quic_simple_server_session.h"
-
-#include <algorithm>
-#include <memory>
-
-#include "base/macros.h"
-#include "net/quic/core/crypto/quic_crypto_server_config.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/proto/cached_network_parameters.pb.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_crypto_server_stream.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/core/tls_server_handshaker.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_config_peer.h"
-#include "net/quic/test_tools/quic_connection_peer.h"
-#include "net/quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "net/quic/test_tools/quic_session_peer.h"
-#include "net/quic/test_tools/quic_spdy_session_peer.h"
-#include "net/quic/test_tools/quic_spdy_stream_peer.h"
-#include "net/quic/test_tools/quic_stream_peer.h"
-#include "net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/test/gtest_util.h"
-#include "net/tools/quic/quic_simple_server_stream.h"
-#include "net/tools/quic/test_tools/mock_quic_session_visitor.h"
-
-using std::string;
-using testing::_;
-using testing::AtLeast;
-using testing::InSequence;
-using testing::Return;
-using testing::StrictMock;
-
-namespace net {
-namespace test {
-namespace {
-typedef QuicSimpleServerSession::PromisedStreamInfo PromisedStreamInfo;
-} // namespace
-
-class QuicSimpleServerSessionPeer {
- public:
- static void SetCryptoStream(QuicSimpleServerSession* s,
- QuicCryptoServerStream* crypto_stream) {
- s->crypto_stream_.reset(crypto_stream);
- s->static_streams()[kCryptoStreamId] = crypto_stream;
- }
-
- static QuicSpdyStream* CreateIncomingDynamicStream(QuicSimpleServerSession* s,
- QuicStreamId id) {
- return s->CreateIncomingDynamicStream(id);
- }
-
- static QuicSimpleServerStream* CreateOutgoingDynamicStream(
- QuicSimpleServerSession* s) {
- return s->CreateOutgoingDynamicStream();
- }
-};
-
-namespace {
-
-const size_t kMaxStreamsForTest = 10;
-
-class MockQuicCryptoServerStream : public QuicCryptoServerStream {
- public:
- explicit MockQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicServerSessionBase* session,
- QuicCryptoServerStream::Helper* helper)
- : QuicCryptoServerStream(
- crypto_config,
- compressed_certs_cache,
- GetQuicReloadableFlag(
- enable_quic_stateless_reject_support), // NOLINT
- session,
- helper) {}
- ~MockQuicCryptoServerStream() override = default;
-
- MOCK_METHOD1(SendServerConfigUpdate,
- void(const CachedNetworkParameters* cached_network_parameters));
-
- void set_encryption_established(bool has_established) {
- encryption_established_override_ = has_established;
- }
-
- bool encryption_established() const override {
- return QuicCryptoServerStream::encryption_established() ||
- encryption_established_override_;
- }
-
- private:
- bool encryption_established_override_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream);
-};
-
-class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
- public:
- MockQuicConnectionWithSendStreamData(
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- Perspective perspective,
- const ParsedQuicVersionVector& supported_versions)
- : MockQuicConnection(helper,
- alarm_factory,
- perspective,
- supported_versions) {}
-
- MOCK_METHOD4(SendStreamData,
- QuicConsumedData(QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state));
-};
-
-class MockQuicSimpleServerSession : public QuicSimpleServerSession {
- public:
- MockQuicSimpleServerSession(const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStream::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicHttpResponseCache* response_cache)
- : QuicSimpleServerSession(config,
- connection,
- visitor,
- helper,
- crypto_config,
- compressed_certs_cache,
- response_cache) {}
- // Methods taking non-copyable types like SpdyHeaderBlock by value cannot be
- // mocked directly.
- size_t WritePushPromise(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- SpdyHeaderBlock headers) override {
- return WritePushPromiseMock(original_stream_id, promised_stream_id,
- headers);
- }
- MOCK_METHOD3(WritePushPromiseMock,
- size_t(QuicStreamId original_stream_id,
- QuicStreamId promised_stream_id,
- const SpdyHeaderBlock& headers));
-
- size_t WriteHeaders(QuicStreamId stream_id,
- SpdyHeaderBlock headers,
- bool fin,
- SpdyPriority priority,
- QuicReferenceCountedPointer<QuicAckListenerInterface>
- ack_listener) override {
- return WriteHeadersMock(stream_id, headers, fin, priority, ack_listener);
- }
- MOCK_METHOD5(
- WriteHeadersMock,
- size_t(QuicStreamId stream_id,
- const SpdyHeaderBlock& headers,
- bool fin,
- SpdyPriority priority,
- const QuicReferenceCountedPointer<QuicAckListenerInterface>&
- ack_listener));
- MOCK_METHOD1(SendBlocked, void(QuicStreamId));
-};
-
-class QuicSimpleServerSessionTest
- : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- bool ClearControlFrame(const QuicFrame& frame) {
- DeleteFrame(&const_cast<QuicFrame&>(frame));
- return true;
- }
-
- protected:
- QuicSimpleServerSessionTest()
- : crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- TlsServerHandshaker::CreateSslCtx()),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
- config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
- config_.SetMaxIncomingDynamicStreamsToSend(kMaxStreamsForTest);
- QuicConfigPeer::SetReceivedMaxIncomingDynamicStreams(&config_,
- kMaxStreamsForTest);
- config_.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- config_.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
-
- ParsedQuicVersionVector supported_versions = SupportedVersions(GetParam());
- connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
- &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
- session_ = QuicMakeUnique<MockQuicSimpleServerSession>(
- config_, connection_, &owner_, &stream_helper_, &crypto_config_,
- &compressed_certs_cache_, &response_cache_);
- MockClock clock;
- handshake_message_.reset(crypto_config_.AddDefaultConfig(
- QuicRandom::GetInstance(), &clock,
- QuicCryptoServerConfig::ConfigOptions()));
- session_->Initialize();
- QuicSessionPeer::GetMutableCryptoStream(session_.get())
- ->OnSuccessfulVersionNegotiation(supported_versions.front());
- visitor_ = QuicConnectionPeer::GetVisitor(connection_);
-
- session_->OnConfigNegotiated();
- }
-
- QuicStreamId GetNthClientInitiatedId(int n) {
- return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(*session_, n);
- }
-
- QuicStreamId GetNthServerInitiatedId(int n) {
- return QuicSpdySessionPeer::GetNthServerInitiatedStreamId(*session_, n);
- }
-
- StrictMock<MockQuicSessionVisitor> owner_;
- StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnectionWithSendStreamData>* connection_;
- QuicConfig config_;
- QuicCryptoServerConfig crypto_config_;
- QuicCompressedCertsCache compressed_certs_cache_;
- QuicHttpResponseCache response_cache_;
- std::unique_ptr<MockQuicSimpleServerSession> session_;
- std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
- QuicConnectionVisitorInterface* visitor_;
-};
-
-INSTANTIATE_TEST_CASE_P(Tests,
- QuicSimpleServerSessionTest,
- ::testing::ValuesIn(AllSupportedVersions()));
-
-TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) {
- // Open a stream, then reset it.
- // Send two bytes of payload to open it.
- QuicStreamFrame data1(GetNthClientInitiatedId(0), false, 0,
- QuicStringPiece("HT"));
- session_->OnStreamFrame(data1);
- EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
-
- // Receive a reset (and send a RST in response).
- QuicRstStreamFrame rst1(kInvalidControlFrameId, GetNthClientInitiatedId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- visitor_->OnRstStream(rst1);
- EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
-
- // Send the same two bytes of payload in a new packet.
- visitor_->OnStreamFrame(data1);
-
- // The stream should not be re-opened.
- EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) {
- // Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst1(kInvalidControlFrameId, GetNthClientInitiatedId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- visitor_->OnRstStream(rst1);
- EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
-
- // Send two bytes of payload.
- QuicStreamFrame data1(GetNthClientInitiatedId(0), false, 0,
- QuicStringPiece("HT"));
- visitor_->OnStreamFrame(data1);
-
- // The stream should never be opened, now that the reset is received.
- EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) {
- // Send (empty) compressed headers followed by two bytes of data.
- QuicStreamFrame frame1(GetNthClientInitiatedId(0), false, 0,
- QuicStringPiece("\1\0\0\0\0\0\0\0HT"));
- QuicStreamFrame frame2(GetNthClientInitiatedId(1), false, 0,
- QuicStringPiece("\2\0\0\0\0\0\0\0HT"));
- visitor_->OnStreamFrame(frame1);
- visitor_->OnStreamFrame(frame2);
- EXPECT_EQ(2u, session_->GetNumOpenIncomingStreams());
-
- // Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst(kInvalidControlFrameId, GetNthClientInitiatedId(0),
- QUIC_ERROR_PROCESSING_STREAM, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- visitor_->OnRstStream(rst);
-
- // If we were tracking, we'd probably want to reject this because it's data
- // past the reset point of stream 3. As it's a closed stream we just drop the
- // data on the floor, but accept the packet because it has data for stream 5.
- QuicStreamFrame frame3(GetNthClientInitiatedId(0), false, 2,
- QuicStringPiece("TP"));
- QuicStreamFrame frame4(GetNthClientInitiatedId(1), false, 2,
- QuicStringPiece("TP"));
- visitor_->OnStreamFrame(frame3);
- visitor_->OnStreamFrame(frame4);
- // The stream should never be opened, now that the reset is received.
- EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
- EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateIncomingDynamicStreamDisconnected) {
- // Tests that incoming stream creation fails when connection is not connected.
- size_t initial_num_open_stream = session_->GetNumOpenIncomingStreams();
- QuicConnectionPeer::TearDownLocalConnectionState(connection_);
- EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateIncomingDynamicStream(
- session_.get(), GetNthClientInitiatedId(0)),
- "ShouldCreateIncomingDynamicStream called when disconnected");
- EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenIncomingStreams());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateEvenIncomingDynamicStream) {
- // Tests that incoming stream creation fails when given stream id is even.
- size_t initial_num_open_stream = session_->GetNumOpenIncomingStreams();
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Client created even numbered stream", _));
- QuicSimpleServerSessionPeer::CreateIncomingDynamicStream(session_.get(), 2);
- EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenIncomingStreams());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateIncomingDynamicStream) {
- QuicSpdyStream* stream =
- QuicSimpleServerSessionPeer::CreateIncomingDynamicStream(
- session_.get(), GetNthClientInitiatedId(0));
- EXPECT_NE(nullptr, stream);
- EXPECT_EQ(GetNthClientInitiatedId(0), stream->id());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamDisconnected) {
- // Tests that outgoing stream creation fails when connection is not connected.
- size_t initial_num_open_stream = session_->GetNumOpenOutgoingStreams();
- QuicConnectionPeer::TearDownLocalConnectionState(connection_);
- EXPECT_QUIC_BUG(
- QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream(session_.get()),
- "ShouldCreateOutgoingDynamicStream called when disconnected");
-
- EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenOutgoingStreams());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUnencrypted) {
- // Tests that outgoing stream creation fails when encryption has not yet been
- // established.
- size_t initial_num_open_stream = session_->GetNumOpenOutgoingStreams();
- EXPECT_QUIC_BUG(
- QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream(session_.get()),
- "Encryption not established so no outgoing stream created.");
- EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenOutgoingStreams());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) {
- // Tests that outgoing stream creation should not be affected by existing
- // incoming stream and vice-versa. But when reaching the limit of max outgoing
- // stream allowed, creation should fail.
-
- // Receive some data to initiate a incoming stream which should not effect
- // creating outgoing streams.
- QuicStreamFrame data1(GetNthClientInitiatedId(0), false, 0,
- QuicStringPiece("HT"));
- session_->OnStreamFrame(data1);
- EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
- EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
-
- if (GetQuicReloadableFlag(quic_register_streams_early2) &&
- GetQuicReloadableFlag(quic_register_static_streams)) {
- session_->UnregisterStreamPriority(kHeadersStreamId, /*is_static=*/true);
- }
- // Assume encryption already established.
- QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), nullptr);
- MockQuicCryptoServerStream* crypto_stream =
- new MockQuicCryptoServerStream(&crypto_config_, &compressed_certs_cache_,
- session_.get(), &stream_helper_);
- crypto_stream->set_encryption_established(true);
- QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
- if (GetQuicReloadableFlag(quic_register_streams_early2) &&
- GetQuicReloadableFlag(quic_register_static_streams)) {
- session_->RegisterStreamPriority(kHeadersStreamId, /*is_static=*/true,
- QuicStream::kDefaultPriority);
- }
-
- // Create push streams till reaching the upper limit of allowed open streams.
- for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
- QuicSpdyStream* created_stream =
- QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream(
- session_.get());
- EXPECT_EQ(GetNthServerInitiatedId(i), created_stream->id());
- EXPECT_EQ(i + 1, session_->GetNumOpenOutgoingStreams());
- }
-
- // Continuing creating push stream would fail.
- EXPECT_EQ(nullptr, QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream(
- session_.get()));
- EXPECT_EQ(kMaxStreamsForTest, session_->GetNumOpenOutgoingStreams());
-
- // Create peer initiated stream should have no problem.
- QuicStreamFrame data2(GetNthClientInitiatedId(1), false, 0,
- QuicStringPiece("HT"));
- session_->OnStreamFrame(data2);
- EXPECT_EQ(2u, session_->GetNumOpenIncomingStreams());
-}
-
-TEST_P(QuicSimpleServerSessionTest, OnStreamFrameWithEvenStreamId) {
- QuicStreamFrame frame(2, false, 0, QuicStringPiece());
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Client sent data on server push stream", _));
- session_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSimpleServerSessionTest, GetEvenIncomingError) {
- // Tests that calling GetOrCreateDynamicStream() on an outgoing stream not
- // promised yet should result close connection.
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID,
- "Data for nonexistent stream", _));
- EXPECT_EQ(nullptr,
- QuicSessionPeer::GetOrCreateDynamicStream(session_.get(), 4));
-}
-
-// In order to test the case where server push stream creation goes beyond
-// limit, server push streams need to be hanging there instead of
-// immediately closing after sending back response.
-// To achieve this goal, this class resets flow control windows so that large
-// responses will not be sent fully in order to prevent push streams from being
-// closed immediately.
-// Also adjust connection-level flow control window to ensure a large response
-// can cause stream-level flow control blocked but not connection-level.
-class QuicSimpleServerSessionServerPushTest
- : public QuicSimpleServerSessionTest {
- protected:
- const size_t kStreamFlowControlWindowSize = 32 * 1024; // 32KB.
-
- QuicSimpleServerSessionServerPushTest() : QuicSimpleServerSessionTest() {
- config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
-
- // Reset stream level flow control window to be 32KB.
- QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
- &config_, kStreamFlowControlWindowSize);
- // Reset connection level flow control window to be 1.5 MB which is large
- // enough that it won't block any stream to write before stream level flow
- // control blocks it.
- QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
- &config_, kInitialSessionFlowControlWindowForTest);
- // Enable server push.
- QuicTagVector copt;
- copt.push_back(kSPSH);
- QuicConfigPeer::SetReceivedConnectionOptions(&config_, copt);
-
- ParsedQuicVersionVector supported_versions = SupportedVersions(GetParam());
- connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
- &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
- session_ = QuicMakeUnique<MockQuicSimpleServerSession>(
- config_, connection_, &owner_, &stream_helper_, &crypto_config_,
- &compressed_certs_cache_, &response_cache_);
- session_->Initialize();
- QuicSessionPeer::GetMutableCryptoStream(session_.get())
- ->OnSuccessfulVersionNegotiation(supported_versions.front());
- // Needed to make new session flow control window and server push work.
- session_->OnConfigNegotiated();
-
- visitor_ = QuicConnectionPeer::GetVisitor(connection_);
-
- if (GetQuicReloadableFlag(quic_register_streams_early2) &&
- GetQuicReloadableFlag(quic_register_static_streams)) {
- session_->UnregisterStreamPriority(kHeadersStreamId, /*is_static=*/true);
- }
- QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), nullptr);
- // Assume encryption already established.
- MockQuicCryptoServerStream* crypto_stream = new MockQuicCryptoServerStream(
- &crypto_config_, &compressed_certs_cache_, session_.get(),
- &stream_helper_);
-
- crypto_stream->set_encryption_established(true);
- QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
- if (GetQuicReloadableFlag(quic_register_streams_early2) &&
- GetQuicReloadableFlag(quic_register_static_streams)) {
- session_->RegisterStreamPriority(kHeadersStreamId, /*is_static=*/true,
- QuicStream::kDefaultPriority);
- }
- }
-
- // Given |num_resources|, create this number of fake push resources and push
- // them by sending PUSH_PROMISE for all and sending push responses for as much
- // as possible(limited by kMaxStreamsForTest).
- // If |num_resources| > kMaxStreamsForTest, the left over will be queued.
- void PromisePushResources(size_t num_resources) {
- // To prevent push streams from being closed the response need to be larger
- // than stream flow control window so stream won't send the full body.
- size_t body_size = 2 * kStreamFlowControlWindowSize; // 64KB.
-
- config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
-
- string request_url = "mail.google.com/";
- SpdyHeaderBlock request_headers;
- string resource_host = "www.google.com";
- string partial_push_resource_path = "/server_push_src";
- std::list<QuicHttpResponseCache::ServerPushInfo> push_resources;
- string scheme = "http";
- for (unsigned int i = 1; i <= num_resources; ++i) {
- QuicStreamId stream_id = GetNthServerInitiatedId(i - 1);
- string path =
- partial_push_resource_path + QuicTextUtils::Uint64ToString(i);
- string url = scheme + "://" + resource_host + path;
- QuicUrl resource_url = QuicUrl(url);
- string body(body_size, 'a');
- response_cache_.AddSimpleResponse(resource_host, path, 200, body);
- push_resources.push_back(QuicHttpResponseCache::ServerPushInfo(
- resource_url, SpdyHeaderBlock(), QuicStream::kDefaultPriority, body));
- // PUSH_PROMISED are sent for all the resources.
- EXPECT_CALL(*session_, WritePushPromiseMock(GetNthClientInitiatedId(0),
- stream_id, _));
- if (i <= kMaxStreamsForTest) {
- // |kMaxStreamsForTest| promised responses should be sent.
- EXPECT_CALL(*session_,
- WriteHeadersMock(stream_id, _, false,
- QuicStream::kDefaultPriority, _));
- // Since flow control window is smaller than response body, not the
- // whole body will be sent.
- EXPECT_CALL(*connection_, SendStreamData(stream_id, _, 0, NO_FIN))
- .WillOnce(
- Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
- EXPECT_CALL(*session_, SendBlocked(stream_id));
- }
- }
- session_->PromisePushResources(request_url, push_resources,
- GetNthClientInitiatedId(0), request_headers);
- }
-};
-
-INSTANTIATE_TEST_CASE_P(Tests,
- QuicSimpleServerSessionServerPushTest,
- ::testing::ValuesIn(AllSupportedVersions()));
-
-TEST_P(QuicSimpleServerSessionServerPushTest, TestPromisePushResources) {
- // Tests that given more than kMaxOpenStreamForTest resources, all their
- // PUSH_PROMISE's will be sent out and only |kMaxOpenStreamForTest| streams
- // will be opened and send push response.
-
- size_t num_resources = kMaxStreamsForTest + 5;
- PromisePushResources(num_resources);
- EXPECT_EQ(kMaxStreamsForTest, session_->GetNumOpenOutgoingStreams());
-}
-
-TEST_P(QuicSimpleServerSessionServerPushTest,
- HandlePromisedPushRequestsAfterStreamDraining) {
- // Tests that after promised stream queued up, when an opened stream is marked
- // draining, a queued promised stream will become open and send push response.
- size_t num_resources = kMaxStreamsForTest + 1;
- PromisePushResources(num_resources);
- QuicStreamId next_out_going_stream_id =
- GetNthServerInitiatedId(kMaxStreamsForTest);
-
- // After an open stream is marked draining, a new stream is expected to be
- // created and a response sent on the stream.
- EXPECT_CALL(*session_, WriteHeadersMock(next_out_going_stream_id, _, false,
- QuicStream::kDefaultPriority, _));
- EXPECT_CALL(*connection_,
- SendStreamData(next_out_going_stream_id, _, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
- EXPECT_CALL(*session_, SendBlocked(next_out_going_stream_id));
- session_->StreamDraining(2);
- // Number of open outgoing streams should still be the same, because a new
- // stream is opened. And the queue should be empty.
- EXPECT_EQ(kMaxStreamsForTest, session_->GetNumOpenOutgoingStreams());
-}
-
-TEST_P(QuicSimpleServerSessionServerPushTest,
- ResetPromisedStreamToCancelServerPush) {
- // Tests that after all resources are promised, a RST frame from client can
- // prevent a promised resource to be send out.
-
- // Having two extra resources to be send later. One of them will be reset, so
- // when opened stream become close, only one will become open.
- size_t num_resources = kMaxStreamsForTest + 2;
- PromisePushResources(num_resources);
-
- // Reset the last stream in the queue. It should be marked cancelled.
- QuicStreamId stream_got_reset =
- GetNthServerInitiatedId(kMaxStreamsForTest + 1);
- QuicRstStreamFrame rst(kInvalidControlFrameId, stream_got_reset,
- QUIC_STREAM_CANCELLED, 0);
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(
- this, &QuicSimpleServerSessionServerPushTest::ClearControlFrame));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT));
- visitor_->OnRstStream(rst);
-
- // When the first 2 streams becomes draining, the two queued up stream could
- // be created. But since one of them was marked cancelled due to RST frame,
- // only one queued resource will be sent out.
- QuicStreamId stream_not_reset = GetNthServerInitiatedId(kMaxStreamsForTest);
- InSequence s;
- EXPECT_CALL(*session_, WriteHeadersMock(stream_not_reset, _, false,
- QuicStream::kDefaultPriority, _));
- EXPECT_CALL(*connection_, SendStreamData(stream_not_reset, _, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
- EXPECT_CALL(*session_, SendBlocked(stream_not_reset));
- EXPECT_CALL(*session_, WriteHeadersMock(stream_got_reset, _, false,
- QuicStream::kDefaultPriority, _))
- .Times(0);
-
- session_->StreamDraining(GetNthServerInitiatedId(0));
- session_->StreamDraining(GetNthServerInitiatedId(1));
-}
-
-TEST_P(QuicSimpleServerSessionServerPushTest,
- CloseStreamToHandleMorePromisedStream) {
- // Tests that closing a open outgoing stream can trigger a promised resource
- // in the queue to be send out.
- size_t num_resources = kMaxStreamsForTest + 1;
- PromisePushResources(num_resources);
- QuicStreamId stream_to_open = GetNthServerInitiatedId(kMaxStreamsForTest);
-
- // Resetting 1st open stream will close the stream and give space for extra
- // stream to be opened.
- QuicStreamId stream_got_reset = GetNthServerInitiatedId(0);
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT));
- EXPECT_CALL(*session_, WriteHeadersMock(stream_to_open, _, false,
- QuicStream::kDefaultPriority, _));
- EXPECT_CALL(*connection_, SendStreamData(stream_to_open, _, 0, NO_FIN))
- .WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
-
- EXPECT_CALL(*session_, SendBlocked(stream_to_open));
- EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- QuicRstStreamFrame rst(kInvalidControlFrameId, stream_got_reset,
- QUIC_STREAM_CANCELLED, 0);
- visitor_->OnRstStream(rst);
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_server_stream.cc b/chromium/net/tools/quic/quic_simple_server_stream.cc
deleted file mode 100644
index c0ee02d3079..00000000000
--- a/chromium/net/tools/quic/quic_simple_server_stream.cc
+++ /dev/null
@@ -1,266 +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/tools/quic/quic_simple_server_stream.h"
-
-#include <list>
-#include <utility>
-
-#include "net/quic/core/quic_spdy_stream.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_map_util.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/spdy/core/spdy_protocol.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-#include "net/tools/quic/quic_simple_server_session.h"
-
-using std::string;
-
-namespace net {
-
-QuicSimpleServerStream::QuicSimpleServerStream(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache)
- : QuicSpdyServerStreamBase(id, session),
- content_length_(-1),
- response_cache_(response_cache) {}
-
-QuicSimpleServerStream::~QuicSimpleServerStream() = default;
-
-void QuicSimpleServerStream::OnInitialHeadersComplete(
- bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
- if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
- &request_headers_)) {
- QUIC_DVLOG(1) << "Invalid headers";
- SendErrorResponse();
- }
- ConsumeHeaderList();
-}
-
-void QuicSimpleServerStream::OnTrailingHeadersComplete(
- bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- QUIC_BUG << "Server does not support receiving Trailers.";
- SendErrorResponse();
-}
-
-void QuicSimpleServerStream::OnDataAvailable() {
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- // No more data to read.
- break;
- }
- QUIC_DVLOG(1) << "Stream " << id() << " processed " << iov.iov_len
- << " bytes.";
- body_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
-
- if (content_length_ >= 0 &&
- body_.size() > static_cast<uint64_t>(content_length_)) {
- QUIC_DVLOG(1) << "Body size (" << body_.size() << ") > content length ("
- << content_length_ << ").";
- SendErrorResponse();
- return;
- }
- MarkConsumed(iov.iov_len);
- }
- if (!sequencer()->IsClosed()) {
- sequencer()->SetUnblocked();
- return;
- }
-
- // If the sequencer is closed, then all the body, including the fin, has been
- // consumed.
- OnFinRead();
-
- if (write_side_closed() || fin_buffered()) {
- return;
- }
-
- SendResponse();
-}
-
-void QuicSimpleServerStream::PushResponse(
- SpdyHeaderBlock push_request_headers) {
- if (id() % 2 != 0) {
- QUIC_BUG << "Client initiated stream shouldn't be used as promised stream.";
- return;
- }
- // Change the stream state to emulate a client request.
- request_headers_ = std::move(push_request_headers);
- content_length_ = 0;
- QUIC_DVLOG(1) << "Stream " << id()
- << " ready to receive server push response.";
-
- // Set as if stream decompresed the headers and received fin.
- QuicSpdyStream::OnInitialHeadersComplete(/*fin=*/true, 0, QuicHeaderList());
-}
-
-void QuicSimpleServerStream::SendResponse() {
- if (request_headers_.empty()) {
- QUIC_DVLOG(1) << "Request headers empty.";
- SendErrorResponse();
- return;
- }
-
- if (content_length_ > 0 &&
- static_cast<uint64_t>(content_length_) != body_.size()) {
- QUIC_DVLOG(1) << "Content length (" << content_length_ << ") != body size ("
- << body_.size() << ").";
- SendErrorResponse();
- return;
- }
-
- if (!QuicContainsKey(request_headers_, ":authority") ||
- !QuicContainsKey(request_headers_, ":path")) {
- QUIC_DVLOG(1) << "Request headers do not contain :authority or :path.";
- SendErrorResponse();
- return;
- }
-
- // Find response in cache. If not found, send error response.
- const QuicHttpResponseCache::Response* response = nullptr;
- auto authority = request_headers_.find(":authority");
- auto path = request_headers_.find(":path");
- if (authority != request_headers_.end() && path != request_headers_.end()) {
- response = response_cache_->GetResponse(authority->second, path->second);
- }
- if (response == nullptr) {
- QUIC_DVLOG(1) << "Response not found in cache.";
- SendNotFoundResponse();
- return;
- }
-
- if (response->response_type() == QuicHttpResponseCache::CLOSE_CONNECTION) {
- QUIC_DVLOG(1) << "Special response: closing connection.";
- CloseConnectionWithDetails(QUIC_NO_ERROR, "Toy server forcing close");
- return;
- }
-
- if (response->response_type() == QuicHttpResponseCache::IGNORE_REQUEST) {
- QUIC_DVLOG(1) << "Special response: ignoring request.";
- return;
- }
-
- // Examing response status, if it was not pure integer as typical h2
- // response status, send error response. Notice that
- // QuicHttpResponseCache push urls are strictly authority + path only,
- // scheme is not included (see |QuicHttpResponseCache::GetKey()|).
- string request_url = request_headers_[":authority"].as_string() +
- request_headers_[":path"].as_string();
- int response_code;
- const SpdyHeaderBlock& response_headers = response->headers();
- if (!ParseHeaderStatusCode(response_headers, &response_code)) {
- auto status = response_headers.find(":status");
- if (status == response_headers.end()) {
- QUIC_LOG(WARNING)
- << ":status not present in response from cache for request "
- << request_url;
- } else {
- QUIC_LOG(WARNING) << "Illegal (non-integer) response :status from cache: "
- << status->second << " for request " << request_url;
- }
- SendErrorResponse();
- return;
- }
-
- if (id() % 2 == 0) {
- // A server initiated stream is only used for a server push response,
- // and only 200 and 30X response codes are supported for server push.
- // This behavior mirrors the HTTP/2 implementation.
- bool is_redirection = response_code / 100 == 3;
- if (response_code != 200 && !is_redirection) {
- QUIC_LOG(WARNING) << "Response to server push request " << request_url
- << " result in response code " << response_code;
- Reset(QUIC_STREAM_CANCELLED);
- return;
- }
- }
- std::list<QuicHttpResponseCache::ServerPushInfo> resources =
- response_cache_->GetServerPushResources(request_url);
- QUIC_DVLOG(1) << "Stream " << id() << " found " << resources.size()
- << " push resources.";
-
- if (!resources.empty()) {
- QuicSimpleServerSession* session =
- static_cast<QuicSimpleServerSession*>(spdy_session());
- session->PromisePushResources(request_url, resources, id(),
- request_headers_);
- }
-
- QUIC_DVLOG(1) << "Stream " << id() << " sending response.";
- SendHeadersAndBodyAndTrailers(response->headers().Clone(), response->body(),
- response->trailers().Clone());
-}
-
-void QuicSimpleServerStream::SendNotFoundResponse() {
- QUIC_DVLOG(1) << "Stream " << id() << " sending not found response.";
- SpdyHeaderBlock headers;
- headers[":status"] = "404";
- headers["content-length"] =
- QuicTextUtils::Uint64ToString(strlen(kNotFoundResponseBody));
- SendHeadersAndBody(std::move(headers), kNotFoundResponseBody);
-}
-
-void QuicSimpleServerStream::SendErrorResponse() {
- QUIC_DVLOG(1) << "Stream " << id() << " sending error response.";
- SpdyHeaderBlock headers;
- headers[":status"] = "500";
- headers["content-length"] =
- QuicTextUtils::Uint64ToString(strlen(kErrorResponseBody));
- SendHeadersAndBody(std::move(headers), kErrorResponseBody);
-}
-
-void QuicSimpleServerStream::SendHeadersAndBody(
- SpdyHeaderBlock response_headers,
- QuicStringPiece body) {
- SendHeadersAndBodyAndTrailers(std::move(response_headers), body,
- SpdyHeaderBlock());
-}
-
-void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers(
- SpdyHeaderBlock response_headers,
- QuicStringPiece body,
- SpdyHeaderBlock response_trailers) {
- // Send the headers, with a FIN if there's nothing else to send.
- bool send_fin = (body.empty() && response_trailers.empty());
- QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = " << send_fin
- << ") : " << response_headers.DebugString();
- WriteHeaders(std::move(response_headers), send_fin, nullptr);
- if (send_fin) {
- // Nothing else to send.
- return;
- }
-
- // Send the body, with a FIN if there's no trailers to send.
- send_fin = response_trailers.empty();
- QUIC_DLOG(INFO) << "Stream " << id() << " writing body (fin = " << send_fin
- << ") with size: " << body.size();
- if (!body.empty() || send_fin) {
- WriteOrBufferData(body, send_fin, nullptr);
- }
- if (send_fin) {
- // Nothing else to send.
- return;
- }
-
- // Send the trailers. A FIN is always sent with trailers.
- QUIC_DLOG(INFO) << "Stream " << id() << " writing trailers (fin = true): "
- << response_trailers.DebugString();
- WriteTrailers(std::move(response_trailers), nullptr);
-}
-
-const char* const QuicSimpleServerStream::kErrorResponseBody = "bad";
-const char* const QuicSimpleServerStream::kNotFoundResponseBody =
- "file not found";
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_server_stream.h b/chromium/net/tools/quic/quic_simple_server_stream.h
deleted file mode 100644
index c792af1352c..00000000000
--- a/chromium/net/tools/quic/quic_simple_server_stream.h
+++ /dev/null
@@ -1,92 +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_TOOLS_QUIC_QUIC_SIMPLE_SERVER_STREAM_H_
-#define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_STREAM_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_spdy_stream.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/spdy/core/spdy_framer.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-#include "net/tools/quic/quic_spdy_server_stream_base.h"
-
-namespace net {
-
-namespace test {
-class QuicSimpleServerStreamPeer;
-} // namespace test
-
-// All this does right now is aggregate data, and on fin, send an HTTP
-// response.
-class QuicSimpleServerStream : public QuicSpdyServerStreamBase {
- public:
- QuicSimpleServerStream(QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache);
- ~QuicSimpleServerStream() override;
-
- // QuicSpdyStream
- void OnInitialHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
- void OnTrailingHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-
- // QuicStream implementation called by the sequencer when there is
- // data (or a FIN) to be read.
- void OnDataAvailable() override;
-
- // Make this stream start from as if it just finished parsing an incoming
- // request whose headers are equivalent to |push_request_headers|.
- // Doing so will trigger this toy stream to fetch response and send it back.
- virtual void PushResponse(SpdyHeaderBlock push_request_headers);
-
- // The response body of error responses.
- static const char* const kErrorResponseBody;
- static const char* const kNotFoundResponseBody;
-
- protected:
- // Sends a basic 200 response using SendHeaders for the headers and WriteData
- // for the body.
- virtual void SendResponse();
-
- // Sends a basic 500 response using SendHeaders for the headers and WriteData
- // for the body.
- virtual void SendErrorResponse();
-
- // Sends a basic 404 response using SendHeaders for the headers and WriteData
- // for the body.
- void SendNotFoundResponse();
-
- void SendHeadersAndBody(SpdyHeaderBlock response_headers,
- QuicStringPiece body);
- void SendHeadersAndBodyAndTrailers(SpdyHeaderBlock response_headers,
- QuicStringPiece body,
- SpdyHeaderBlock response_trailers);
-
- SpdyHeaderBlock* request_headers() { return &request_headers_; }
-
- const std::string& body() { return body_; }
-
- private:
- friend class test::QuicSimpleServerStreamPeer;
-
- // The parsed headers received from the client.
- SpdyHeaderBlock request_headers_;
- int64_t content_length_;
- std::string body_;
-
- QuicHttpResponseCache* response_cache_; // Not owned.
-
- DISALLOW_COPY_AND_ASSIGN(QuicSimpleServerStream);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_STREAM_H_
diff --git a/chromium/net/tools/quic/quic_simple_server_stream_test.cc b/chromium/net/tools/quic/quic_simple_server_stream_test.cc
deleted file mode 100644
index 5163c42f66c..00000000000
--- a/chromium/net/tools/quic/quic_simple_server_stream_test.cc
+++ /dev/null
@@ -1,618 +0,0 @@
-// Copyright (c) 2013 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/tools/quic/quic_simple_server_stream.h"
-
-#include <list>
-#include <memory>
-#include <utility>
-
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/core/tls_server_handshaker.h"
-#include "net/quic/platform/api/quic_arraysize.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_spdy_session_peer.h"
-#include "net/quic/test_tools/quic_stream_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/test/gtest_util.h"
-#include "net/tools/quic/quic_http_response_cache.h"
-#include "net/tools/quic/quic_simple_server_session.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using std::string;
-using testing::_;
-using testing::AnyNumber;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-
-namespace net {
-namespace test {
-
-size_t kFakeFrameLen = 60;
-
-class QuicSimpleServerStreamPeer : public QuicSimpleServerStream {
- public:
- QuicSimpleServerStreamPeer(QuicStreamId stream_id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache)
- : QuicSimpleServerStream(stream_id, session, response_cache) {}
-
- ~QuicSimpleServerStreamPeer() override = default;
-
- using QuicSimpleServerStream::SendErrorResponse;
- using QuicSimpleServerStream::SendResponse;
-
- SpdyHeaderBlock* mutable_headers() { return &request_headers_; }
-
- static void SendResponse(QuicSimpleServerStream* stream) {
- stream->SendResponse();
- }
-
- static void SendErrorResponse(QuicSimpleServerStream* stream) {
- stream->SendErrorResponse();
- }
-
- static const string& body(QuicSimpleServerStream* stream) {
- return stream->body_;
- }
-
- static int content_length(QuicSimpleServerStream* stream) {
- return stream->content_length_;
- }
-
- static SpdyHeaderBlock& headers(QuicSimpleServerStream* stream) {
- return stream->request_headers_;
- }
-};
-
-namespace {
-
-class MockQuicSimpleServerSession : public QuicSimpleServerSession {
- public:
- const size_t kMaxStreamsForTest = 100;
-
- explicit MockQuicSimpleServerSession(
- QuicConnection* connection,
- MockQuicSessionVisitor* owner,
- MockQuicCryptoServerStreamHelper* helper,
- QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicHttpResponseCache* response_cache)
- : QuicSimpleServerSession(DefaultQuicConfig(),
- connection,
- owner,
- helper,
- crypto_config,
- compressed_certs_cache,
- response_cache) {
- set_max_open_incoming_streams(kMaxStreamsForTest);
- set_max_open_outgoing_streams(kMaxStreamsForTest);
- ON_CALL(*this, WritevData(_, _, _, _, _))
- .WillByDefault(testing::Return(QuicConsumedData(0, false)));
- }
-
- ~MockQuicSimpleServerSession() override = default;
-
- MOCK_METHOD3(OnConnectionClosed,
- void(QuicErrorCode error,
- const string& error_details,
- ConnectionCloseSource source));
- MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
- MOCK_METHOD5(WritevData,
- QuicConsumedData(QuicStream* stream,
- QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state));
- MOCK_METHOD4(OnStreamHeaderList,
- void(QuicStreamId stream_id,
- bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list));
- MOCK_METHOD2(OnStreamHeadersPriority,
- void(QuicStreamId stream_id, SpdyPriority priority));
- // Methods taking non-copyable types like SpdyHeaderBlock by value cannot be
- // mocked directly.
- size_t WriteHeaders(QuicStreamId id,
- SpdyHeaderBlock headers,
- bool fin,
- SpdyPriority priority,
- QuicReferenceCountedPointer<QuicAckListenerInterface>
- ack_listener) override {
- return WriteHeadersMock(id, headers, fin, priority, ack_listener);
- }
- MOCK_METHOD5(
- WriteHeadersMock,
- size_t(QuicStreamId id,
- const SpdyHeaderBlock& headers,
- bool fin,
- SpdyPriority priority,
- const QuicReferenceCountedPointer<QuicAckListenerInterface>&
- ack_listener));
- MOCK_METHOD3(SendRstStream,
- void(QuicStreamId stream_id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written));
- MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta));
- // Matchers cannot be used on non-copyable types like SpdyHeaderBlock.
- void PromisePushResources(
- const string& request_url,
- const std::list<QuicHttpResponseCache::ServerPushInfo>& resources,
- QuicStreamId original_stream_id,
- const SpdyHeaderBlock& original_request_headers) override {
- original_request_headers_ = original_request_headers.Clone();
- PromisePushResourcesMock(request_url, resources, original_stream_id,
- original_request_headers);
- }
- MOCK_METHOD4(PromisePushResourcesMock,
- void(const string&,
- const std::list<QuicHttpResponseCache::ServerPushInfo>&,
- QuicStreamId,
- const SpdyHeaderBlock&));
-
- using QuicSession::ActivateStream;
-
- SpdyHeaderBlock original_request_headers_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockQuicSimpleServerSession);
-};
-
-class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
- QuicSimpleServerStreamTest()
- : connection_(
- new StrictMock<MockQuicConnection>(&helper_,
- &alarm_factory_,
- Perspective::IS_SERVER,
- SupportedVersions(GetParam()))),
- crypto_config_(new QuicCryptoServerConfig(
- QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- TlsServerHandshaker::CreateSslCtx())),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- session_(connection_,
- &session_owner_,
- &session_helper_,
- crypto_config_.get(),
- &compressed_certs_cache_,
- &response_cache_),
- body_("hello world") {
- header_list_.OnHeaderBlockStart();
- header_list_.OnHeader(":authority", "www.google.com");
- header_list_.OnHeader(":path", "/");
- header_list_.OnHeader(":method", "POST");
- header_list_.OnHeader(":version", "HTTP/1.1");
- header_list_.OnHeader("content-length", "11");
- header_list_.OnHeaderBlockEnd(128, 128);
-
- // New streams rely on having the peer's flow control receive window
- // negotiated in the config.
- session_.config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session_.config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- stream_ = new QuicSimpleServerStreamPeer(
- QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, 0),
- &session_, &response_cache_);
- // Register stream_ in dynamic_stream_map_ and pass ownership to session_.
- session_.ActivateStream(QuicWrapUnique(stream_));
- }
-
- const string& StreamBody() {
- return QuicSimpleServerStreamPeer::body(stream_);
- }
-
- string StreamHeadersValue(const string& key) {
- return (*stream_->mutable_headers())[key].as_string();
- }
-
- SpdyHeaderBlock response_headers_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- StrictMock<MockQuicSessionVisitor> session_owner_;
- StrictMock<MockQuicCryptoServerStreamHelper> session_helper_;
- std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
- QuicCompressedCertsCache compressed_certs_cache_;
- QuicHttpResponseCache response_cache_;
- StrictMock<MockQuicSimpleServerSession> session_;
- QuicSimpleServerStreamPeer* stream_; // Owned by session_.
- string body_;
- QuicHeaderList header_list_;
-};
-
-INSTANTIATE_TEST_CASE_P(Tests,
- QuicSimpleServerStreamTest,
- ::testing::ValuesIn(AllSupportedVersions()));
-
-TEST_P(QuicSimpleServerStreamTest, TestFraming) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
- stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
- EXPECT_EQ(body_, StreamBody());
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
-
- stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
- EXPECT_EQ(body_, StreamBody());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
-
- EXPECT_FALSE(stream_->fin_received());
- EXPECT_FALSE(stream_->rst_received());
-
- stream_->set_fin_sent(true);
- stream_->CloseWriteSide();
-
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1);
- stream_->StopReading();
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
- string large_body = "hello world!!!!!!";
-
- // We'll automatically write out an error (headers + body)
- EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .WillOnce(Invoke(MockQuicSession::ConsumeData));
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
-
- stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- // Content length is still 11. This will register as an error and we won't
- // accept the bytes.
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/true, body_.size(), large_body));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) {
- // Send an illegal response with response status not supported by HTTP/2.
- SpdyHeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = "/bar";
- (*request_headers)[":authority"] = "www.google.com";
- (*request_headers)[":version"] = "HTTP/1.1";
- (*request_headers)[":method"] = "GET";
-
- response_headers_[":version"] = "HTTP/1.1";
- // HTTP/2 only supports integer responsecode, so "200 OK" is illegal.
- response_headers_[":status"] = "200 OK";
- response_headers_["content-length"] = "5";
- string body = "Yummm";
- response_cache_.AddResponse("www.google.com", "/bar",
- std::move(response_headers_), body);
-
- stream_->set_fin_received(true);
-
- InSequence s;
- EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(1)
- .WillOnce(Return(QuicConsumedData(
- strlen(QuicSimpleServerStream::kErrorResponseBody), true)));
-
- QuicSimpleServerStreamPeer::SendResponse(stream_);
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) {
- // Send an illegal response with response status not supported by HTTP/2.
- SpdyHeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = "/bar";
- (*request_headers)[":authority"] = "www.google.com";
- (*request_headers)[":version"] = "HTTP/1.1";
- (*request_headers)[":method"] = "GET";
-
- response_headers_[":version"] = "HTTP/1.1";
- // HTTP/2 only supports 3-digit-integer, so "+200" is illegal.
- response_headers_[":status"] = "+200";
- response_headers_["content-length"] = "5";
- string body = "Yummm";
- response_cache_.AddResponse("www.google.com", "/bar",
- std::move(response_headers_), body);
-
- stream_->set_fin_received(true);
-
- InSequence s;
- EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(1)
- .WillOnce(Return(QuicConsumedData(
- strlen(QuicSimpleServerStream::kErrorResponseBody), true)));
-
- QuicSimpleServerStreamPeer::SendResponse(stream_);
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) {
- // Create a new promised stream with even id().
- QuicSimpleServerStreamPeer* promised_stream =
- new QuicSimpleServerStreamPeer(2, &session_, &response_cache_);
- session_.ActivateStream(QuicWrapUnique(promised_stream));
-
- // Send a push response with response status 404, which will be regarded as
- // invalid server push response.
- SpdyHeaderBlock* request_headers = promised_stream->mutable_headers();
- (*request_headers)[":path"] = "/bar";
- (*request_headers)[":authority"] = "www.google.com";
- (*request_headers)[":version"] = "HTTP/1.1";
- (*request_headers)[":method"] = "GET";
-
- response_headers_[":version"] = "HTTP/1.1";
- response_headers_[":status"] = "404";
- response_headers_["content-length"] = "8";
- string body = "NotFound";
- response_cache_.AddResponse("www.google.com", "/bar",
- std::move(response_headers_), body);
-
- InSequence s;
- EXPECT_CALL(session_,
- SendRstStream(promised_stream->id(), QUIC_STREAM_CANCELLED, 0));
-
- QuicSimpleServerStreamPeer::SendResponse(promised_stream);
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) {
- // Add a request and response with valid headers.
- SpdyHeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = "/bar";
- (*request_headers)[":authority"] = "www.google.com";
- (*request_headers)[":version"] = "HTTP/1.1";
- (*request_headers)[":method"] = "GET";
-
- response_headers_[":version"] = "HTTP/1.1";
- response_headers_[":status"] = "200";
- response_headers_["content-length"] = "5";
- string body = "Yummm";
- response_cache_.AddResponse("www.google.com", "/bar",
- std::move(response_headers_), body);
- stream_->set_fin_received(true);
-
- InSequence s;
- EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(1)
- .WillOnce(Return(QuicConsumedData(body.length(), true)));
-
- QuicSimpleServerStreamPeer::SendResponse(stream_);
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendReponseWithPushResources) {
- // Tests that if a reponse has push resources to be send, SendResponse() will
- // call PromisePushResources() to handle these resources.
-
- // Add a request and response with valid headers into cache.
- string host = "www.google.com";
- string request_path = "/foo";
- string body = "Yummm";
- QuicHttpResponseCache::ServerPushInfo push_info(
- QuicUrl(host, "/bar"), SpdyHeaderBlock(), QuicStream::kDefaultPriority,
- "Push body");
- std::list<QuicHttpResponseCache::ServerPushInfo> push_resources;
- push_resources.push_back(push_info);
- response_cache_.AddSimpleResponseWithServerPushResources(
- host, request_path, 200, body, push_resources);
-
- SpdyHeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = request_path;
- (*request_headers)[":authority"] = host;
- (*request_headers)[":version"] = "HTTP/1.1";
- (*request_headers)[":method"] = "GET";
-
- stream_->set_fin_received(true);
- InSequence s;
- EXPECT_CALL(
- session_,
- PromisePushResourcesMock(
- host + request_path, _,
- QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, 0), _));
- EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(1)
- .WillOnce(Return(QuicConsumedData(body.length(), true)));
- QuicSimpleServerStreamPeer::SendResponse(stream_);
- EXPECT_EQ(*request_headers, session_.original_request_headers_);
-}
-
-TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) {
- // Calling PushResponse() on a client initialted stream is never supposed to
- // happen.
- EXPECT_QUIC_BUG(stream_->PushResponse(SpdyHeaderBlock()),
- "Client initiated stream"
- " shouldn't be used as promised stream.");
-}
-
-TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) {
- // Tests that PushResponse() should take the given headers as request headers
- // and fetch response from cache, and send it out.
-
- // Create a stream with even stream id and test against this stream.
- const QuicStreamId kServerInitiatedStreamId = 2;
- // Create a server initiated stream and pass it to session_.
- QuicSimpleServerStreamPeer* server_initiated_stream =
- new QuicSimpleServerStreamPeer(kServerInitiatedStreamId, &session_,
- &response_cache_);
- session_.ActivateStream(QuicWrapUnique(server_initiated_stream));
-
- const string kHost = "www.foo.com";
- const string kPath = "/bar";
- SpdyHeaderBlock headers;
- headers[":path"] = kPath;
- headers[":authority"] = kHost;
- headers[":version"] = "HTTP/1.1";
- headers[":method"] = "GET";
-
- response_headers_[":version"] = "HTTP/1.1";
- response_headers_[":status"] = "200";
- response_headers_["content-length"] = "5";
- const string kBody = "Hello";
- response_cache_.AddResponse(kHost, kPath, std::move(response_headers_),
- kBody);
-
- // Call PushResponse() should trigger stream to fetch response from cache
- // and send it back.
- EXPECT_CALL(session_,
- WriteHeadersMock(kServerInitiatedStreamId, _, false,
- server_initiated_stream->priority(), _));
- EXPECT_CALL(session_, WritevData(_, kServerInitiatedStreamId, _, _, _))
- .Times(1)
- .WillOnce(Return(QuicConsumedData(kBody.size(), true)));
- server_initiated_stream->PushResponse(std::move(headers));
- EXPECT_EQ(kPath, QuicSimpleServerStreamPeer::headers(
- server_initiated_stream)[":path"]
- .as_string());
- EXPECT_EQ("GET", QuicSimpleServerStreamPeer::headers(
- server_initiated_stream)[":method"]
- .as_string());
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) {
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
-
- stream_->set_fin_received(true);
-
- InSequence s;
- EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(1)
- .WillOnce(Return(QuicConsumedData(3, true)));
-
- QuicSimpleServerStreamPeer::SendErrorResponse(stream_);
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
-
- SpdyHeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- header_list_.OnHeader("content-length", QuicStringPiece("11\00012", 5));
-
- EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
- stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
-
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->reading_stopped());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
-
- SpdyHeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- header_list_.OnHeader("content-length", QuicStringPiece("\00012", 3));
-
- EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
- stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
-
- EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_TRUE(stream_->reading_stopped());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) {
- SpdyHeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- header_list_.OnHeader("content-length", QuicStringPiece("11\00011", 5));
-
- stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
-
- EXPECT_EQ(11, QuicSimpleServerStreamPeer::content_length(stream_));
- EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
- EXPECT_FALSE(stream_->reading_stopped());
- EXPECT_FALSE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest,
- DoNotSendQuicRstStreamNoErrorWithRstReceived) {
- InSequence s;
- EXPECT_FALSE(stream_->reading_stopped());
-
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
- EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _)).Times(1);
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
-
- EXPECT_TRUE(stream_->reading_stopped());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
- char arr[] = {
- 0x3a, 0x68, 0x6f, 0x73, // :hos
- 0x74, 0x00, 0x00, 0x00, // t...
- 0x00, 0x00, 0x00, 0x00, // ....
- 0x07, 0x3a, 0x6d, 0x65, // .:me
- 0x74, 0x68, 0x6f, 0x64, // thod
- 0x00, 0x00, 0x00, 0x03, // ....
- 0x47, 0x45, 0x54, 0x00, // GET.
- 0x00, 0x00, 0x05, 0x3a, // ...:
- 0x70, 0x61, 0x74, 0x68, // path
- 0x00, 0x00, 0x00, 0x04, // ....
- 0x2f, 0x66, 0x6f, 0x6f, // /foo
- 0x00, 0x00, 0x00, 0x07, // ....
- 0x3a, 0x73, 0x63, 0x68, // :sch
- 0x65, 0x6d, 0x65, 0x00, // eme.
- 0x00, 0x00, 0x00, 0x00, // ....
- 0x00, 0x00, 0x08, 0x3a, // ...:
- 0x76, 0x65, 0x72, 0x73, // vers
- 0x96, 0x6f, 0x6e, 0x00, // <i(69)>on.
- 0x00, 0x00, 0x08, 0x48, // ...H
- 0x54, 0x54, 0x50, 0x2f, // TTP/
- 0x31, 0x2e, 0x31, // 1.1
- };
- QuicStringPiece data(arr, QUIC_ARRAYSIZE(arr));
- QuicStreamFrame frame(stream_->id(), true, 0, data);
- // Verify that we don't crash when we get a invalid headers in stream frame.
- stream_->OnStreamFrame(frame);
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_server_test.cc b/chromium/net/tools/quic/quic_simple_server_test.cc
index 66bbd33774b..2b99b65b99a 100644
--- a/chromium/net/tools/quic/quic_simple_server_test.cc
+++ b/chromium/net/tools/quic/quic_simple_server_test.cc
@@ -4,14 +4,15 @@
#include "net/tools/quic/quic_simple_server.h"
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_crypto_stream.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/core/tls_server_handshaker.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/mock_quic_dispatcher.h"
-#include "net/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quic/core/crypto/quic_random.h"
+#include "net/third_party/quic/core/quic_crypto_stream.h"
+#include "net/third_party/quic/core/quic_utils.h"
+#include "net/third_party/quic/core/tls_server_handshaker.h"
+#include "net/third_party/quic/platform/api/quic_test.h"
+#include "net/third_party/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quic/test_tools/mock_quic_dispatcher.h"
+#include "net/third_party/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quic/tools/quic_memory_cache_backend.h"
#include "net/tools/quic/quic_simple_server_session_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -38,7 +39,7 @@ class QuicChromeServerDispatchPacketTest : public QuicTest {
std::unique_ptr<QuicCryptoServerStream::Helper>(
new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())),
std::unique_ptr<MockAlarmFactory>(new net::test::MockAlarmFactory),
- &response_cache_) {
+ &memory_cache_backend_) {
dispatcher_.InitializeWithWriter(nullptr);
}
@@ -54,7 +55,7 @@ class QuicChromeServerDispatchPacketTest : public QuicTest {
QuicCryptoServerConfig crypto_config_;
QuicVersionManager version_manager_;
net::test::MockQuicDispatcher dispatcher_;
- QuicHttpResponseCache response_cache_;
+ QuicMemoryCacheBackend memory_cache_backend_;
};
TEST_F(QuicChromeServerDispatchPacketTest, DispatchPacket) {
diff --git a/chromium/net/tools/quic/quic_spdy_client_base.cc b/chromium/net/tools/quic/quic_spdy_client_base.cc
deleted file mode 100644
index b7bf7c3f053..00000000000
--- a/chromium/net/tools/quic/quic_spdy_client_base.cc
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright (c) 2015 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/tools/quic/quic_spdy_client_base.h"
-
-#include "net/quic/core/crypto/quic_random.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-
-using base::StringToInt;
-using std::string;
-
-namespace net {
-
-void QuicSpdyClientBase::ClientQuicDataToResend::Resend() {
- client_->SendRequest(*headers_, body_, fin_);
- headers_ = nullptr;
-}
-
-QuicSpdyClientBase::QuicDataToResend::QuicDataToResend(
- std::unique_ptr<SpdyHeaderBlock> headers,
- QuicStringPiece body,
- bool fin)
- : headers_(std::move(headers)), body_(body), fin_(fin) {}
-
-QuicSpdyClientBase::QuicDataToResend::~QuicDataToResend() = default;
-
-QuicSpdyClientBase::QuicSpdyClientBase(
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<NetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicClientBase(server_id,
- supported_versions,
- config,
- helper,
- alarm_factory,
- std::move(network_helper),
- std::move(proof_verifier)),
- store_response_(false),
- latest_response_code_(-1) {}
-
-QuicSpdyClientBase::~QuicSpdyClientBase() {
- // We own the push promise index. We need to explicitly kill
- // the session before the push promise index goes out of scope.
- ResetSession();
-}
-
-QuicSpdyClientSession* QuicSpdyClientBase::client_session() {
- return static_cast<QuicSpdyClientSession*>(QuicClientBase::session());
-}
-
-void QuicSpdyClientBase::InitializeSession() {
- client_session()->Initialize();
- client_session()->CryptoConnect();
-}
-
-void QuicSpdyClientBase::OnClose(QuicSpdyStream* stream) {
- DCHECK(stream != nullptr);
- QuicSpdyClientStream* client_stream =
- static_cast<QuicSpdyClientStream*>(stream);
-
- const SpdyHeaderBlock& response_headers = client_stream->response_headers();
- if (response_listener_ != nullptr) {
- response_listener_->OnCompleteResponse(stream->id(), response_headers,
- client_stream->data());
- }
-
- // Store response headers and body.
- if (store_response_) {
- auto status = response_headers.find(":status");
- if (status == response_headers.end() ||
- !QuicTextUtils::StringToInt(status->second, &latest_response_code_)) {
- QUIC_LOG(ERROR) << "Invalid response headers";
- }
- latest_response_headers_ = response_headers.DebugString();
- preliminary_response_headers_ =
- client_stream->preliminary_headers().DebugString();
- latest_response_header_block_ = response_headers.Clone();
- latest_response_body_ = client_stream->data();
- latest_response_trailers_ =
- client_stream->received_trailers().DebugString();
- }
-}
-
-std::unique_ptr<QuicSession> QuicSpdyClientBase::CreateQuicClientSession(
- QuicConnection* connection) {
- return QuicMakeUnique<QuicSpdyClientSession>(*config(), connection,
- server_id(), crypto_config(),
- &push_promise_index_);
-}
-
-void QuicSpdyClientBase::SendRequest(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin) {
- QuicClientPushPromiseIndex::TryHandle* handle;
- QuicAsyncStatus rv = push_promise_index()->Try(headers, this, &handle);
- if (rv == QUIC_SUCCESS)
- return;
-
- if (rv == QUIC_PENDING) {
- // May need to retry request if asynchronous rendezvous fails.
- AddPromiseDataToResend(headers, body, fin);
- return;
- }
-
- QuicSpdyClientStream* stream = CreateClientStream();
- if (stream == nullptr) {
- QUIC_BUG << "stream creation failed!";
- return;
- }
- stream->SendRequest(headers.Clone(), body, fin);
- // Record this in case we need to resend.
- MaybeAddDataToResend(headers, body, fin);
-}
-
-void QuicSpdyClientBase::SendRequestAndWaitForResponse(
- const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin) {
- SendRequest(headers, body, fin);
- while (WaitForEvents()) {
- }
-}
-
-void QuicSpdyClientBase::SendRequestsAndWaitForResponse(
- const std::vector<string>& url_list) {
- for (size_t i = 0; i < url_list.size(); ++i) {
- SpdyHeaderBlock headers;
- if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) {
- QUIC_BUG << "Unable to create request";
- continue;
- }
- SendRequest(headers, "", true);
- }
- while (WaitForEvents()) {
- }
-}
-
-QuicSpdyClientStream* QuicSpdyClientBase::CreateClientStream() {
- if (!connected()) {
- return nullptr;
- }
-
- auto* stream = static_cast<QuicSpdyClientStream*>(
- client_session()->CreateOutgoingDynamicStream());
- if (stream) {
- stream->SetPriority(QuicStream::kDefaultPriority);
- stream->set_visitor(this);
- }
- return stream;
-}
-
-int QuicSpdyClientBase::GetNumSentClientHellosFromSession() {
- return client_session()->GetNumSentClientHellos();
-}
-
-int QuicSpdyClientBase::GetNumReceivedServerConfigUpdatesFromSession() {
- return client_session()->GetNumReceivedServerConfigUpdates();
-}
-
-void QuicSpdyClientBase::MaybeAddDataToResend(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin) {
- if (!GetQuicReloadableFlag(enable_quic_stateless_reject_support)) {
- return;
- }
-
- if (client_session()->IsCryptoHandshakeConfirmed()) {
- // The handshake is confirmed. No need to continue saving requests to
- // resend.
- data_to_resend_on_connect_.clear();
- return;
- }
-
- // The handshake is not confirmed. Push the data onto the queue of data to
- // resend if statelessly rejected.
- std::unique_ptr<SpdyHeaderBlock> new_headers(
- new SpdyHeaderBlock(headers.Clone()));
- std::unique_ptr<QuicDataToResend> data_to_resend(
- new ClientQuicDataToResend(std::move(new_headers), body, fin, this));
- MaybeAddQuicDataToResend(std::move(data_to_resend));
-}
-
-void QuicSpdyClientBase::MaybeAddQuicDataToResend(
- std::unique_ptr<QuicDataToResend> data_to_resend) {
- data_to_resend_on_connect_.push_back(std::move(data_to_resend));
-}
-
-void QuicSpdyClientBase::ClearDataToResend() {
- data_to_resend_on_connect_.clear();
-}
-
-void QuicSpdyClientBase::ResendSavedData() {
- // Calling Resend will re-enqueue the data, so swap out
- // data_to_resend_on_connect_ before iterating.
- std::vector<std::unique_ptr<QuicDataToResend>> old_data;
- old_data.swap(data_to_resend_on_connect_);
- for (const auto& data : old_data) {
- data->Resend();
- }
-}
-
-void QuicSpdyClientBase::AddPromiseDataToResend(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin) {
- std::unique_ptr<SpdyHeaderBlock> new_headers(
- new SpdyHeaderBlock(headers.Clone()));
- push_promise_data_to_resend_.reset(
- new ClientQuicDataToResend(std::move(new_headers), body, fin, this));
-}
-
-bool QuicSpdyClientBase::CheckVary(const SpdyHeaderBlock& client_request,
- const SpdyHeaderBlock& promise_request,
- const SpdyHeaderBlock& promise_response) {
- return true;
-}
-
-void QuicSpdyClientBase::OnRendezvousResult(QuicSpdyStream* stream) {
- std::unique_ptr<ClientQuicDataToResend> data_to_resend =
- std::move(push_promise_data_to_resend_);
- if (stream) {
- stream->set_visitor(this);
- stream->OnDataAvailable();
- } else if (data_to_resend) {
- data_to_resend->Resend();
- }
-}
-
-size_t QuicSpdyClientBase::latest_response_code() const {
- QUIC_BUG_IF(!store_response_) << "Response not stored!";
- return latest_response_code_;
-}
-
-const string& QuicSpdyClientBase::latest_response_headers() const {
- QUIC_BUG_IF(!store_response_) << "Response not stored!";
- return latest_response_headers_;
-}
-
-const string& QuicSpdyClientBase::preliminary_response_headers() const {
- QUIC_BUG_IF(!store_response_) << "Response not stored!";
- return preliminary_response_headers_;
-}
-
-const SpdyHeaderBlock& QuicSpdyClientBase::latest_response_header_block()
- const {
- QUIC_BUG_IF(!store_response_) << "Response not stored!";
- return latest_response_header_block_;
-}
-
-const string& QuicSpdyClientBase::latest_response_body() const {
- QUIC_BUG_IF(!store_response_) << "Response not stored!";
- return latest_response_body_;
-}
-
-const string& QuicSpdyClientBase::latest_response_trailers() const {
- QUIC_BUG_IF(!store_response_) << "Response not stored!";
- return latest_response_trailers_;
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_spdy_client_base.h b/chromium/net/tools/quic/quic_spdy_client_base.h
deleted file mode 100644
index 468e712c1de..00000000000
--- a/chromium/net/tools/quic/quic_spdy_client_base.h
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) 2015 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.
-//
-// A base class for the toy client, which connects to a specified port and sends
-// QUIC request to that endpoint.
-
-#ifndef NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_BASE_H_
-#define NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_BASE_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "net/quic/core/crypto/crypto_handshake.h"
-#include "net/quic/core/quic_client_push_promise_index.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/tools/quic/quic_client_base.h"
-#include "net/tools/quic/quic_spdy_client_session.h"
-#include "net/tools/quic/quic_spdy_client_stream.h"
-
-namespace net {
-
-class ProofVerifier;
-class QuicServerId;
-
-class QuicSpdyClientBase : public QuicClientBase,
- public QuicClientPushPromiseIndex::Delegate,
- public QuicSpdyStream::Visitor {
- public:
- // A ResponseListener is notified when a complete response is received.
- class ResponseListener {
- public:
- ResponseListener() {}
- virtual ~ResponseListener() {}
- virtual void OnCompleteResponse(QuicStreamId id,
- const SpdyHeaderBlock& response_headers,
- const std::string& response_body) = 0;
- };
-
- // The client uses these objects to keep track of any data to resend upon
- // receipt of a stateless reject. Recall that the client API allows callers
- // to optimistically send data to the server prior to handshake-confirmation.
- // If the client subsequently receives a stateless reject, it must tear down
- // its existing session, create a new session, and resend all previously sent
- // data. It uses these objects to keep track of all the sent data, and to
- // resend the data upon a subsequent connection.
- class QuicDataToResend {
- public:
- // |headers| may be null, since it's possible to send data without headers.
- QuicDataToResend(std::unique_ptr<SpdyHeaderBlock> headers,
- QuicStringPiece body,
- bool fin);
-
- virtual ~QuicDataToResend();
-
- // Must be overridden by specific classes with the actual method for
- // re-sending data.
- virtual void Resend() = 0;
-
- protected:
- std::unique_ptr<SpdyHeaderBlock> headers_;
- QuicStringPiece body_;
- bool fin_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(QuicDataToResend);
- };
-
- QuicSpdyClientBase(const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- const QuicConfig& config,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- std::unique_ptr<NetworkHelper> network_helper,
- std::unique_ptr<ProofVerifier> proof_verifier);
-
- ~QuicSpdyClientBase() override;
-
- // QuicSpdyStream::Visitor
- void OnClose(QuicSpdyStream* stream) override;
-
- // A spdy session has to call CryptoConnect on top of the regular
- // initialization.
- void InitializeSession() override;
-
- // Sends an HTTP request and does not wait for response before returning.
- void SendRequest(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin);
-
- // Sends an HTTP request and waits for response before returning.
- void SendRequestAndWaitForResponse(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin);
-
- // Sends a request simple GET for each URL in |url_list|, and then waits for
- // each to complete.
- void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list);
-
- // Returns a newly created QuicSpdyClientStream.
- QuicSpdyClientStream* CreateClientStream();
-
- // Returns a the session used for this client downcasted to a
- // QuicSpdyClientSession.
- QuicSpdyClientSession* client_session();
-
- QuicClientPushPromiseIndex* push_promise_index() {
- return &push_promise_index_;
- }
-
- bool CheckVary(const SpdyHeaderBlock& client_request,
- const SpdyHeaderBlock& promise_request,
- const SpdyHeaderBlock& promise_response) override;
- void OnRendezvousResult(QuicSpdyStream*) override;
-
- // If the crypto handshake has not yet been confirmed, adds the data to the
- // queue of data to resend if the client receives a stateless reject.
- // Otherwise, deletes the data.
- void MaybeAddQuicDataToResend(
- std::unique_ptr<QuicDataToResend> data_to_resend);
-
- void set_store_response(bool val) { store_response_ = val; }
-
- size_t latest_response_code() const;
- const std::string& latest_response_headers() const;
- const std::string& preliminary_response_headers() const;
- const SpdyHeaderBlock& latest_response_header_block() const;
- const std::string& latest_response_body() const;
- const std::string& latest_response_trailers() const;
-
- void set_response_listener(std::unique_ptr<ResponseListener> listener) {
- response_listener_ = std::move(listener);
- }
-
- protected:
- int GetNumSentClientHellosFromSession() override;
- int GetNumReceivedServerConfigUpdatesFromSession() override;
-
- // Takes ownership of |connection|.
- std::unique_ptr<QuicSession> CreateQuicClientSession(
- QuicConnection* connection) override;
-
- // If the crypto handshake has not yet been confirmed, adds the data to the
- // queue of data to resend if the client receives a stateless reject.
- // Otherwise, deletes the data.
- void MaybeAddDataToResend(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin);
-
- void ClearDataToResend() override;
-
- void ResendSavedData() override;
-
- void AddPromiseDataToResend(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin);
-
- private:
- // Specific QuicClient class for storing data to resend.
- class ClientQuicDataToResend : public QuicDataToResend {
- public:
- ClientQuicDataToResend(std::unique_ptr<SpdyHeaderBlock> headers,
- QuicStringPiece body,
- bool fin,
- QuicSpdyClientBase* client)
- : QuicDataToResend(std::move(headers), body, fin), client_(client) {
- DCHECK(headers_);
- DCHECK(client);
- }
-
- ~ClientQuicDataToResend() override {}
-
- void Resend() override;
-
- private:
- QuicSpdyClientBase* client_;
-
- DISALLOW_COPY_AND_ASSIGN(ClientQuicDataToResend);
- };
-
- // Index of pending promised streams. Must outlive |session_|.
- QuicClientPushPromiseIndex push_promise_index_;
-
- // If true, store the latest response code, headers, and body.
- bool store_response_;
- // HTTP response code from most recent response.
- int latest_response_code_;
- // HTTP/2 headers from most recent response.
- std::string latest_response_headers_;
- // preliminary 100 Continue HTTP/2 headers from most recent response, if any.
- std::string preliminary_response_headers_;
- // HTTP/2 headers from most recent response.
- SpdyHeaderBlock latest_response_header_block_;
- // Body of most recent response.
- std::string latest_response_body_;
- // HTTP/2 trailers from most recent response.
- std::string latest_response_trailers_;
-
- // Listens for full responses.
- std::unique_ptr<ResponseListener> response_listener_;
-
- // Keeps track of any data that must be resent upon a subsequent successful
- // connection, in case the client receives a stateless reject.
- std::vector<std::unique_ptr<QuicDataToResend>> data_to_resend_on_connect_;
-
- std::unique_ptr<ClientQuicDataToResend> push_promise_data_to_resend_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientBase);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_BASE_H_
diff --git a/chromium/net/tools/quic/quic_spdy_client_session.cc b/chromium/net/tools/quic/quic_spdy_client_session.cc
deleted file mode 100644
index c178cccb2e9..00000000000
--- a/chromium/net/tools/quic/quic_spdy_client_session.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/tools/quic/quic_spdy_client_session.h"
-
-#include "net/log/net_log_with_source.h"
-#include "net/quic/chromium/crypto/proof_verifier_chromium.h"
-#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_string.h"
-
-namespace net {
-
-QuicSpdyClientSession::QuicSpdyClientSession(
- const QuicConfig& config,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSessionBase(connection, push_promise_index, config),
- server_id_(server_id),
- crypto_config_(crypto_config),
- respect_goaway_(true) {}
-
-QuicSpdyClientSession::~QuicSpdyClientSession() = default;
-
-void QuicSpdyClientSession::Initialize() {
- crypto_stream_ = CreateQuicCryptoStream();
- QuicSpdyClientSessionBase::Initialize();
-}
-
-void QuicSpdyClientSession::OnProofValid(
- const QuicCryptoClientConfig::CachedState& /*cached*/) {}
-
-void QuicSpdyClientSession::OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& /*verify_details*/) {}
-
-bool QuicSpdyClientSession::ShouldCreateOutgoingDynamicStream() {
- if (!crypto_stream_->encryption_established()) {
- QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created.";
- return false;
- }
- if (GetNumOpenOutgoingStreams() >= max_open_outgoing_streams()) {
- QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
- << "Already " << GetNumOpenOutgoingStreams() << " open.";
- return false;
- }
- if (goaway_received() && respect_goaway_) {
- QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
- << "Already received goaway.";
- return false;
- }
- return true;
-}
-
-QuicSpdyClientStream* QuicSpdyClientSession::CreateOutgoingDynamicStream() {
- if (!ShouldCreateOutgoingDynamicStream()) {
- return nullptr;
- }
- std::unique_ptr<QuicSpdyClientStream> stream = CreateClientStream();
- QuicSpdyClientStream* stream_ptr = stream.get();
- ActivateStream(std::move(stream));
- return stream_ptr;
-}
-
-std::unique_ptr<QuicSpdyClientStream>
-QuicSpdyClientSession::CreateClientStream() {
- return QuicMakeUnique<QuicSpdyClientStream>(GetNextOutgoingStreamId(), this);
-}
-
-QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream()
- const {
- return crypto_stream_.get();
-}
-
-void QuicSpdyClientSession::CryptoConnect() {
- DCHECK(flow_controller());
- crypto_stream_->CryptoConnect();
-}
-
-int QuicSpdyClientSession::GetNumSentClientHellos() const {
- return crypto_stream_->num_sent_client_hellos();
-}
-
-int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const {
- return crypto_stream_->num_scup_messages_received();
-}
-
-bool QuicSpdyClientSession::ShouldCreateIncomingDynamicStream(QuicStreamId id) {
- if (!connection()->connected()) {
- QUIC_BUG << "ShouldCreateIncomingDynamicStream called when disconnected";
- return false;
- }
- if (goaway_received() && respect_goaway_) {
- QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
- << "Already received goaway.";
- return false;
- }
- if (id % 2 != 0) {
- QUIC_LOG(WARNING) << "Received invalid push stream id " << id;
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Server created odd numbered stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return false;
- }
- return true;
-}
-
-QuicSpdyStream* QuicSpdyClientSession::CreateIncomingDynamicStream(
- QuicStreamId id) {
- if (!ShouldCreateIncomingDynamicStream(id)) {
- return nullptr;
- }
- QuicSpdyStream* stream = new QuicSpdyClientStream(id, this);
- stream->CloseWriteSide();
- ActivateStream(QuicWrapUnique(stream));
- return stream;
-}
-
-std::unique_ptr<QuicCryptoClientStreamBase>
-QuicSpdyClientSession::CreateQuicCryptoStream() {
- return QuicMakeUnique<QuicCryptoClientStream>(
- server_id_, this, new ProofVerifyContextChromium(0, NetLogWithSource()),
- crypto_config_, this);
-}
-
-bool QuicSpdyClientSession::IsAuthorized(const QuicString& authority) {
- return true;
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_spdy_client_session.h b/chromium/net/tools/quic/quic_spdy_client_session.h
deleted file mode 100644
index a5a0cbf14fb..00000000000
--- a/chromium/net/tools/quic/quic_spdy_client_session.h
+++ /dev/null
@@ -1,98 +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.
-//
-// A client specific QuicSession subclass.
-
-#ifndef NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_SESSION_H_
-#define NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_SESSION_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_crypto_client_stream.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_spdy_client_session_base.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/tools/quic/quic_spdy_client_stream.h"
-
-namespace net {
-
-class QuicConnection;
-class QuicServerId;
-
-class QuicSpdyClientSession : public QuicSpdyClientSessionBase {
- public:
- // Takes ownership of |connection|. Caller retains ownership of
- // |promised_by_url|.
- QuicSpdyClientSession(const QuicConfig& config,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index);
- ~QuicSpdyClientSession() override;
- // Set up the QuicSpdyClientSession. Must be called prior to use.
- void Initialize() override;
-
- // QuicSession methods:
- QuicSpdyClientStream* CreateOutgoingDynamicStream() override;
- QuicCryptoClientStreamBase* GetMutableCryptoStream() override;
- const QuicCryptoClientStreamBase* GetCryptoStream() const override;
-
- bool IsAuthorized(const QuicString& authority) override;
-
- // QuicSpdyClientSessionBase methods:
- void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
- void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) override;
-
- // Performs a crypto handshake with the server.
- virtual void CryptoConnect();
-
- // Returns the number of client hello messages that have been sent on the
- // crypto stream. If the handshake has completed then this is one greater
- // than the number of round-trips needed for the handshake.
- int GetNumSentClientHellos() const;
-
- int GetNumReceivedServerConfigUpdates() const;
-
- void set_respect_goaway(bool respect_goaway) {
- respect_goaway_ = respect_goaway;
- }
-
- protected:
- // QuicSession methods:
- QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override;
- // If an outgoing stream can be created, return true.
- bool ShouldCreateOutgoingDynamicStream() override;
-
- // If an incoming stream can be created, return true.
- bool ShouldCreateIncomingDynamicStream(QuicStreamId id) override;
-
- // Create the crypto stream. Called by Initialize().
- virtual std::unique_ptr<QuicCryptoClientStreamBase> CreateQuicCryptoStream();
-
- // Unlike CreateOutgoingDynamicStream, which applies a bunch of sanity checks,
- // this simply returns a new QuicSpdyClientStream. This may be used by
- // subclasses which want to use a subclass of QuicSpdyClientStream for streams
- // but wish to use the sanity checks in CreateOutgoingDynamicStream.
- virtual std::unique_ptr<QuicSpdyClientStream> CreateClientStream();
-
- const QuicServerId& server_id() { return server_id_; }
- QuicCryptoClientConfig* crypto_config() { return crypto_config_; }
-
- private:
- std::unique_ptr<QuicCryptoClientStreamBase> crypto_stream_;
- QuicServerId server_id_;
- QuicCryptoClientConfig* crypto_config_;
-
- // If this is set to false, the client will ignore server GOAWAYs and allow
- // the creation of streams regardless of the high chance they will fail.
- bool respect_goaway_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientSession);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_SESSION_H_
diff --git a/chromium/net/tools/quic/quic_spdy_client_session_test.cc b/chromium/net/tools/quic/quic_spdy_client_session_test.cc
deleted file mode 100644
index b805d89e93f..00000000000
--- a/chromium/net/tools/quic/quic_spdy_client_session_test.cc
+++ /dev/null
@@ -1,611 +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/tools/quic/quic_spdy_client_session.h"
-
-#include <vector>
-
-#include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/core/tls_client_handshaker.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_str_cat.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/mock_quic_spdy_client_stream.h"
-#include "net/quic/test_tools/quic_config_peer.h"
-#include "net/quic/test_tools/quic_connection_peer.h"
-#include "net/quic/test_tools/quic_packet_creator_peer.h"
-#include "net/quic/test_tools/quic_spdy_session_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/tools/quic/quic_spdy_client_stream.h"
-
-using google::protobuf::implicit_cast;
-using testing::_;
-using testing::AnyNumber;
-using testing::Invoke;
-using testing::Truly;
-
-namespace net {
-namespace test {
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kPort = 443;
-
-class TestQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
- explicit TestQuicSpdyClientSession(
- const QuicConfig& config,
- QuicConnection* connection,
- const QuicServerId& server_id,
- QuicCryptoClientConfig* crypto_config,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSession(config,
- connection,
- server_id,
- crypto_config,
- push_promise_index) {}
-
- std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override {
- return QuicMakeUnique<MockQuicSpdyClientStream>(GetNextOutgoingStreamId(),
- this);
- }
-
- MockQuicSpdyClientStream* CreateIncomingDynamicStream(
- QuicStreamId id) override {
- MockQuicSpdyClientStream* stream = new MockQuicSpdyClientStream(id, this);
- ActivateStream(QuicWrapUnique(stream));
- return stream;
- }
-};
-
-class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
- QuicSpdyClientSessionTest()
- : crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
- TlsClientHandshaker::CreateSslCtx()),
- promised_stream_id_(kInvalidStreamId),
- associated_stream_id_(kInvalidStreamId) {
- Initialize();
- // Advance the time, because timers do not like uninitialized times.
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- }
-
- ~QuicSpdyClientSessionTest() override {
- // Session must be destroyed before promised_by_url_
- session_.reset(nullptr);
- }
-
- void Initialize() {
- session_.reset();
- connection_ = new PacketSavingConnection(&helper_, &alarm_factory_,
- Perspective::IS_CLIENT,
- SupportedVersions(GetParam()));
- session_ = QuicMakeUnique<TestQuicSpdyClientSession>(
- DefaultQuicConfig(), connection_,
- QuicServerId(kServerHostname, kPort, PRIVACY_MODE_DISABLED),
- &crypto_config_, &push_promise_index_);
- session_->Initialize();
- push_promise_[":path"] = "/bar";
- push_promise_[":authority"] = "www.google.com";
- push_promise_[":version"] = "HTTP/1.1";
- push_promise_[":method"] = "GET";
- push_promise_[":scheme"] = "https";
- promise_url_ = SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
- promised_stream_id_ =
- QuicSpdySessionPeer::GetNthServerInitiatedStreamId(*session_, 0);
- associated_stream_id_ =
- QuicSpdySessionPeer::GetNthClientInitiatedStreamId(*session_, 0);
- }
-
- void CompleteCryptoHandshake() {
- CompleteCryptoHandshake(kDefaultMaxStreamsPerConnection);
- }
-
- void CompleteCryptoHandshake(uint32_t server_max_incoming_streams) {
- session_->CryptoConnect();
- QuicCryptoClientStream* stream = static_cast<QuicCryptoClientStream*>(
- session_->GetMutableCryptoStream());
- crypto_test_utils::FakeServerOptions options;
- QuicConfig config = DefaultQuicConfig();
- config.SetMaxIncomingDynamicStreamsToSend(server_max_incoming_streams);
- crypto_test_utils::HandshakeWithFakeServer(
- &config, &helper_, &alarm_factory_, connection_, stream, options);
- }
-
- QuicCryptoClientConfig crypto_config_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- PacketSavingConnection* connection_;
- std::unique_ptr<TestQuicSpdyClientSession> session_;
- QuicClientPushPromiseIndex push_promise_index_;
- SpdyHeaderBlock push_promise_;
- QuicString promise_url_;
- QuicStreamId promised_stream_id_;
- QuicStreamId associated_stream_id_;
-};
-
-INSTANTIATE_TEST_CASE_P(Tests,
- QuicSpdyClientSessionTest,
- ::testing::ValuesIn(AllSupportedVersions()));
-
-TEST_P(QuicSpdyClientSessionTest, CryptoConnect) {
- CompleteCryptoHandshake();
-}
-
-TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
- // Complete a handshake in order to prime the crypto config for 0-RTT.
- CompleteCryptoHandshake();
-
- // Now create a second session using the same crypto config.
- Initialize();
-
- EXPECT_CALL(*connection_, OnCanWrite());
- // Starting the handshake should move immediately to encryption
- // established and will allow streams to be created.
- session_->CryptoConnect();
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
- ASSERT_TRUE(stream != nullptr);
- EXPECT_NE(kCryptoStreamId, stream->id());
-
- // Process an "inchoate" REJ from the server which will cause
- // an inchoate CHLO to be sent and will leave the encryption level
- // at NONE.
- CryptoHandshakeMessage rej;
- crypto_test_utils::FillInDummyReject(&rej, /* stateless */ false);
- EXPECT_TRUE(session_->IsEncryptionEstablished());
- crypto_test_utils::SendHandshakeMessageToStream(
- session_->GetMutableCryptoStream(), rej, Perspective::IS_CLIENT);
- EXPECT_FALSE(session_->IsEncryptionEstablished());
- EXPECT_EQ(ENCRYPTION_NONE,
- QuicPacketCreatorPeer::GetEncryptionLevel(
- QuicConnectionPeer::GetPacketCreator(connection_)));
- // Verify that no new streams may be created.
- EXPECT_TRUE(session_->CreateOutgoingDynamicStream() == nullptr);
- // Verify that no data may be send on existing streams.
- char data[] = "hello world";
- QuicConsumedData consumed =
- session_->WritevData(stream, stream->id(), arraysize(data), 0, NO_FIN);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_EQ(0u, consumed.bytes_consumed);
-}
-
-TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber());
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber());
-
- const uint32_t kServerMaxIncomingStreams = 1;
- CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
- QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
- ASSERT_TRUE(stream);
- EXPECT_FALSE(session_->CreateOutgoingDynamicStream());
-
- // Close the stream, but without having received a FIN or a RST_STREAM
- // and check that a new one can not be created.
- session_->CloseStream(stream->id());
- EXPECT_EQ(1u, session_->GetNumOpenOutgoingStreams());
-
- stream = session_->CreateOutgoingDynamicStream();
- EXPECT_FALSE(stream);
-}
-
-TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber());
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber());
-
- const uint32_t kServerMaxIncomingStreams = 1;
- CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
- QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
- ASSERT_NE(nullptr, stream);
- EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream());
-
- // Close the stream and receive an RST frame to remove the unfinished stream
- session_->CloseStream(stream->id());
- session_->OnRstStream(QuicRstStreamFrame(kInvalidControlFrameId, stream->id(),
- QUIC_RST_ACKNOWLEDGEMENT, 0));
- // Check that a new one can be created.
- EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
- stream = session_->CreateOutgoingDynamicStream();
- EXPECT_NE(nullptr, stream);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) {
- // Tests the situation in which the client sends a RST at the same time that
- // the server sends trailing headers (trailers). Receipt of the trailers by
- // the client should result in all outstanding stream state being tidied up
- // (including flow control, and number of available outgoing streams).
- const uint32_t kServerMaxIncomingStreams = 1;
- CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
- QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
- ASSERT_NE(nullptr, stream);
- EXPECT_FALSE(session_->CreateOutgoingDynamicStream());
-
- QuicStreamId stream_id = stream->id();
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
-
- // A new stream cannot be created as the reset stream still counts as an open
- // outgoing stream until closed by the server.
- EXPECT_EQ(1u, session_->GetNumOpenOutgoingStreams());
- stream = session_->CreateOutgoingDynamicStream();
- EXPECT_EQ(nullptr, stream);
-
- // The stream receives trailers with final byte offset: this is one of three
- // ways that a peer can signal the end of a stream (the others being RST,
- // stream data + FIN).
- QuicHeaderList trailers;
- trailers.OnHeaderBlockStart();
- trailers.OnHeader(kFinalOffsetHeaderKey, "0");
- trailers.OnHeaderBlockEnd(0, 0);
- session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
-
- // The stream is now complete from the client's perspective, and it should
- // be able to create a new outgoing stream.
- EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
- stream = session_->CreateOutgoingDynamicStream();
- EXPECT_NE(nullptr, stream);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
- // Tests the situation where the client has sent a RST to the server, and has
- // received trailing headers with a malformed final byte offset value.
- CompleteCryptoHandshake();
-
- QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
- ASSERT_NE(nullptr, stream);
-
- // Send the RST, which results in the stream being closed locally (but some
- // state remains while the client waits for a response from the server).
- QuicStreamId stream_id = stream->id();
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
-
- // The stream receives trailers with final byte offset, but the header value
- // is non-numeric and should be treated as malformed.
- QuicHeaderList trailers;
- trailers.OnHeaderBlockStart();
- trailers.OnHeader(kFinalOffsetHeaderKey, "invalid non-numeric value");
- trailers.OnHeaderBlockEnd(0, 0);
-
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
- session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, GoAwayReceived) {
- CompleteCryptoHandshake();
-
- // After receiving a GoAway, I should no longer be able to create outgoing
- // streams.
- session_->connection()->OnGoAwayFrame(QuicGoAwayFrame(
- kInvalidControlFrameId, QUIC_PEER_GOING_AWAY, 1u, "Going away."));
- EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream());
-}
-
-static bool CheckForDecryptionError(QuicFramer* framer) {
- return framer->error() == QUIC_DECRYPTION_FAILURE;
-}
-
-// Various sorts of invalid packets that should not cause a connection
-// to be closed.
-TEST_P(QuicSpdyClientSessionTest, InvalidPacketReceived) {
- QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
- QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
-
- EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
- .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
- &MockQuicConnection::ReallyProcessUdpPacket));
- EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
- EXPECT_CALL(*connection_, OnError(_)).Times(1);
-
- // Verify that empty packets don't close the connection.
- QuicReceivedPacket zero_length_packet(nullptr, 0, QuicTime::Zero(), false);
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_->ProcessUdpPacket(client_address, server_address,
- zero_length_packet);
-
- // Verifiy that small, invalid packets don't close the connection.
- char buf[2] = {0x00, 0x01};
- QuicReceivedPacket valid_packet(buf, 2, QuicTime::Zero(), false);
- // Close connection shouldn't be called.
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- session_->ProcessUdpPacket(client_address, server_address, valid_packet);
-
- // Verify that a non-decryptable packet doesn't close the connection.
- QuicConnectionId connection_id = session_->connection()->connection_id();
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
- connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, nullptr, Perspective::IS_SERVER));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*packet, QuicTime::Zero()));
- // Change the last byte of the encrypted data.
- *(const_cast<char*>(received->data() + received->length() - 1)) += 1;
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- EXPECT_CALL(*connection_, OnError(Truly(CheckForDecryptionError))).Times(1);
- session_->ProcessUdpPacket(client_address, server_address, *received);
-}
-
-// A packet with invalid framing should cause a connection to be closed.
-TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
- QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
- QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
-
- EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
- .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
- &MockQuicConnection::ReallyProcessUdpPacket));
- EXPECT_CALL(*connection_, OnError(_)).Times(1);
-
- // Verify that a decryptable packet with bad frames does close the connection.
- QuicConnectionId connection_id = session_->connection()->connection_id();
- ParsedQuicVersionVector versions = {GetParam()};
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
- connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
- std::unique_ptr<QuicReceivedPacket> received(
- ConstructReceivedPacket(*packet, QuicTime::Zero()));
- EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
- session_->ProcessUdpPacket(client_address, server_address, *received);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeaders) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
- session_->CreateOutgoingDynamicStream());
-
- EXPECT_CALL(*stream, OnPromiseHeaderList(_, _, _));
- session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
- QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeadersAlreadyClosed) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingDynamicStream();
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(associated_stream_id_, QUIC_REFUSED_STREAM));
- session_->ResetPromised(associated_stream_id_, QUIC_REFUSED_STREAM);
-
- session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
- QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOutOfOrder) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
- session_->CreateOutgoingDynamicStream());
-
- EXPECT_CALL(*stream, OnPromiseHeaderList(promised_stream_id_, _, _));
- session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
- QuicHeaderList());
- associated_stream_id_ += 2;
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_STREAM_ID,
- "Received push stream id lesser or equal to the"
- " last accepted before",
- _));
- session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
- QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseHandlePromise) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingDynamicStream();
-
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseAlreadyClosed) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingDynamicStream();
- session_->GetOrCreateStream(promised_stream_id_);
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
-
- session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
- SpdyHeaderBlock promise_headers;
- EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, promise_headers));
-
- // Verify that the promise was not created.
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseDuplicateUrl) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingDynamicStream();
-
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
- promised_stream_id_ += 2;
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_DUPLICATE_PROMISE_URL));
-
- EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- // Verify that the promise was not created.
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) {
- for (size_t i = 0u; i < session_->get_max_promises(); i++) {
- push_promise_[":path"] = QuicStringPrintf("/bar%zu", i);
-
- QuicStreamId id = promised_stream_id_ + i * 2;
-
- EXPECT_TRUE(
- session_->HandlePromised(associated_stream_id_, id, push_promise_));
-
- // Verify that the promise is in the unclaimed streams map.
- QuicString promise_url(SpdyUtils::GetPromisedUrlFromHeaders(push_promise_));
- EXPECT_NE(session_->GetPromisedByUrl(promise_url), nullptr);
- EXPECT_NE(session_->GetPromisedById(id), nullptr);
- }
-
- // One more promise, this should be refused.
- int i = session_->get_max_promises();
- push_promise_[":path"] = QuicStringPrintf("/bar%d", i);
-
- QuicStreamId id = promised_stream_id_ + i * 2;
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(id, QUIC_REFUSED_STREAM));
- EXPECT_FALSE(
- session_->HandlePromised(associated_stream_id_, id, push_promise_));
-
- // Verify that the promise was not created.
- QuicString promise_url(SpdyUtils::GetPromisedUrlFromHeaders(push_promise_));
- EXPECT_EQ(session_->GetPromisedById(id), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedAlreadyOpen) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->GetOrCreateStream(promised_stream_id_);
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
- session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
- EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
-}
-
-TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedNonexistant) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
- session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
- EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsPush) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- session_->GetOrCreateStream(promised_stream_id_);
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
- EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
- session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsNotPush) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- session_->CreateOutgoingDynamicStream();
- session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
-}
-
-TEST_P(QuicSpdyClientSessionTest, DeletePromised) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- session_->GetOrCreateStream(promised_stream_id_);
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
- QuicClientPromisedInfo* promised =
- session_->GetPromisedById(promised_stream_id_);
- EXPECT_NE(promised, nullptr);
- EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
- session_->DeletePromised(promised);
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ResetPromised) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
- session_->GetOrCreateStream(promised_stream_id_);
- EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY));
- session_->SendRstStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
- QuicClientPromisedInfo* promised =
- session_->GetPromisedById(promised_stream_id_);
- EXPECT_NE(promised, nullptr);
- EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
- EXPECT_EQ(session_->GetPromisedStream(promised_stream_id_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidMethod) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingDynamicStream();
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_METHOD));
-
- push_promise_[":method"] = "POST";
- EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidHost) {
- // Initialize crypto before the client session will create a stream.
- CompleteCryptoHandshake();
-
- session_->CreateOutgoingDynamicStream();
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_URL));
-
- push_promise_[":authority"] = "";
- EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
- promised_stream_id_, push_promise_));
-
- EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
- EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_spdy_client_stream.cc b/chromium/net/tools/quic/quic_spdy_client_stream.cc
deleted file mode 100644
index ac0ff0d9f0b..00000000000
--- a/chromium/net/tools/quic/quic_spdy_client_stream.cc
+++ /dev/null
@@ -1,148 +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/tools/quic/quic_spdy_client_stream.h"
-
-#include <utility>
-
-#include "net/quic/core/quic_alarm.h"
-#include "net/quic/core/quic_client_promised_info.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/spdy/core/spdy_protocol.h"
-#include "net/tools/quic/quic_spdy_client_session.h"
-
-using std::string;
-
-namespace net {
-
-QuicSpdyClientStream::QuicSpdyClientStream(QuicStreamId id,
- QuicSpdyClientSession* session)
- : QuicSpdyStream(id, session),
- content_length_(-1),
- response_code_(0),
- header_bytes_read_(0),
- header_bytes_written_(0),
- session_(session),
- has_preliminary_headers_(false) {}
-
-QuicSpdyClientStream::~QuicSpdyClientStream() = default;
-
-void QuicSpdyClientStream::OnInitialHeadersComplete(
- bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
-
- DCHECK(headers_decompressed());
- header_bytes_read_ += frame_len;
- if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
- &response_headers_)) {
- QUIC_DLOG(ERROR) << "Failed to parse header list: "
- << header_list.DebugString();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
-
- if (!ParseHeaderStatusCode(response_headers_, &response_code_)) {
- QUIC_DLOG(ERROR) << "Received invalid response code: "
- << response_headers_[":status"].as_string();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
-
- if (response_code_ == 100 && !has_preliminary_headers_) {
- // These are preliminary 100 Continue headers, not the actual response
- // headers.
- set_headers_decompressed(false);
- has_preliminary_headers_ = true;
- preliminary_headers_ = std::move(response_headers_);
- }
-
- ConsumeHeaderList();
- QUIC_DVLOG(1) << "headers complete for stream " << id();
-
- session_->OnInitialHeadersComplete(id(), response_headers_);
-}
-
-void QuicSpdyClientStream::OnTrailingHeadersComplete(
- bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list);
- MarkTrailersConsumed();
-}
-
-void QuicSpdyClientStream::OnPromiseHeaderList(
- QuicStreamId promised_id,
- size_t frame_len,
- const QuicHeaderList& header_list) {
- header_bytes_read_ += frame_len;
- int64_t content_length = -1;
- SpdyHeaderBlock promise_headers;
- if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length,
- &promise_headers)) {
- QUIC_DLOG(ERROR) << "Failed to parse promise headers: "
- << header_list.DebugString();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
-
- session_->HandlePromised(id(), promised_id, promise_headers);
- if (visitor() != nullptr) {
- visitor()->OnPromiseHeadersComplete(promised_id, frame_len);
- }
-}
-
-void QuicSpdyClientStream::OnDataAvailable() {
- // For push streams, visitor will not be set until the rendezvous
- // between server promise and client request is complete.
- if (visitor() == nullptr)
- return;
-
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- // No more data to read.
- break;
- }
- QUIC_DVLOG(1) << "Client processed " << iov.iov_len << " bytes for stream "
- << id();
- data_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
-
- if (content_length_ >= 0 &&
- data_.size() > static_cast<uint64_t>(content_length_)) {
- QUIC_DLOG(ERROR) << "Invalid content length (" << content_length_
- << ") with data of size " << data_.size();
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
- MarkConsumed(iov.iov_len);
- }
- if (sequencer()->IsClosed()) {
- OnFinRead();
- } else {
- sequencer()->SetUnblocked();
- }
-}
-
-size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers,
- QuicStringPiece body,
- bool fin) {
- QuicConnection::ScopedPacketFlusher flusher(
- session_->connection(), QuicConnection::SEND_ACK_IF_QUEUED);
- bool send_fin_with_headers = fin && body.empty();
- size_t bytes_sent = body.size();
- header_bytes_written_ =
- WriteHeaders(std::move(headers), send_fin_with_headers, nullptr);
- bytes_sent += header_bytes_written_;
-
- if (!body.empty()) {
- WriteOrBufferData(body, fin, nullptr);
- }
-
- return bytes_sent;
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_spdy_client_stream.h b/chromium/net/tools/quic/quic_spdy_client_stream.h
deleted file mode 100644
index e138f01485d..00000000000
--- a/chromium/net/tools/quic/quic_spdy_client_stream.h
+++ /dev/null
@@ -1,93 +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_TOOLS_QUIC_QUIC_SPDY_CLIENT_STREAM_H_
-#define NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_STREAM_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_spdy_stream.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/spdy/core/spdy_framer.h"
-
-namespace net {
-
-class QuicSpdyClientSession;
-
-// All this does right now is send an SPDY request, and aggregate the
-// SPDY response.
-class QuicSpdyClientStream : public QuicSpdyStream {
- public:
- QuicSpdyClientStream(QuicStreamId id, QuicSpdyClientSession* session);
- ~QuicSpdyClientStream() override;
-
- // Override the base class to parse and store headers.
- void OnInitialHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-
- // Override the base class to parse and store trailers.
- void OnTrailingHeadersComplete(bool fin,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-
- // Override the base class to handle creation of the push stream.
- void OnPromiseHeaderList(QuicStreamId promised_id,
- size_t frame_len,
- const QuicHeaderList& header_list) override;
-
- // QuicStream implementation called by the session when there's data for us.
- void OnDataAvailable() override;
-
- // Serializes the headers and body, sends it to the server, and
- // returns the number of bytes sent.
- size_t SendRequest(SpdyHeaderBlock headers, QuicStringPiece body, bool fin);
-
- // Returns the response data.
- const QuicString& data() { return data_; }
-
- // Returns whatever headers have been received for this stream.
- const SpdyHeaderBlock& response_headers() { return response_headers_; }
-
- const SpdyHeaderBlock& preliminary_headers() { return preliminary_headers_; }
-
- size_t header_bytes_read() const { return header_bytes_read_; }
-
- size_t header_bytes_written() const { return header_bytes_written_; }
-
- int response_code() const { return response_code_; }
-
- // While the server's SetPriority shouldn't be called externally, the creator
- // of client-side streams should be able to set the priority.
- using QuicSpdyStream::SetPriority;
-
- private:
- // The parsed headers received from the server.
- SpdyHeaderBlock response_headers_;
-
- // The parsed content-length, or -1 if none is specified.
- int64_t content_length_;
- int response_code_;
- QuicString data_;
- size_t header_bytes_read_;
- size_t header_bytes_written_;
-
- QuicSpdyClientSession* session_;
-
- // These preliminary headers are used for the 100 Continue headers
- // that may arrive before the response headers when the request has
- // Expect: 100-continue.
- bool has_preliminary_headers_;
- SpdyHeaderBlock preliminary_headers_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientStream);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/chromium/net/tools/quic/quic_spdy_client_stream_test.cc b/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
deleted file mode 100644
index 46d060c7a82..00000000000
--- a/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2013 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/tools/quic/quic_spdy_client_stream.h"
-
-#include <memory>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/core/tls_client_handshaker.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_spdy_session_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/tools/quic/quic_spdy_client_session.h"
-
-using base::IntToString;
-using testing::_;
-using testing::StrictMock;
-
-namespace net {
-namespace test {
-
-namespace {
-
-class MockQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
- explicit MockQuicSpdyClientSession(
- QuicConnection* connection,
- QuicClientPushPromiseIndex* push_promise_index)
- : QuicSpdyClientSession(
- DefaultQuicConfig(),
- connection,
- QuicServerId("example.com", 443, PRIVACY_MODE_DISABLED),
- &crypto_config_,
- push_promise_index),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
- TlsClientHandshaker::CreateSslCtx()) {}
- ~MockQuicSpdyClientSession() override = default;
-
- MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id));
-
- private:
- QuicCryptoClientConfig crypto_config_;
-
- DISALLOW_COPY_AND_ASSIGN(MockQuicSpdyClientSession);
-};
-
-class QuicSpdyClientStreamTest : public QuicTest {
- public:
- class StreamVisitor;
-
- QuicSpdyClientStreamTest()
- : connection_(new StrictMock<MockQuicConnection>(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT)),
- session_(connection_, &push_promise_index_),
- body_("hello world") {
- session_.Initialize();
-
- headers_[":status"] = "200";
- headers_["content-length"] = "11";
-
- stream_ = QuicMakeUnique<QuicSpdyClientStream>(
- QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, 0),
- &session_);
- stream_visitor_ = QuicMakeUnique<StreamVisitor>();
- stream_->set_visitor(stream_visitor_.get());
- }
-
- class StreamVisitor : public QuicSpdyClientStream::Visitor {
- void OnClose(QuicSpdyStream* stream) override {
- QUIC_DVLOG(1) << "stream " << stream->id();
- }
- };
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- QuicClientPushPromiseIndex push_promise_index_;
-
- MockQuicSpdyClientSession session_;
- std::unique_ptr<QuicSpdyClientStream> stream_;
- std::unique_ptr<StreamVisitor> stream_visitor_;
- SpdyHeaderBlock headers_;
- QuicString body_;
-};
-
-TEST_F(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) {
- headers_[":status"] = "200 ok";
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- EXPECT_EQ(QUIC_BAD_APPLICATION_PAYLOAD, stream_->stream_error());
-}
-
-TEST_F(QuicSpdyClientStreamTest, TestFraming) {
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
- EXPECT_EQ(200, stream_->response_code());
- EXPECT_EQ(body_, stream_->data());
-}
-
-TEST_F(QuicSpdyClientStreamTest, TestFraming100Continue) {
- headers_[":status"] = "100";
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
- EXPECT_EQ(0u, stream_->response_headers().size());
- EXPECT_EQ(100, stream_->response_code());
- EXPECT_EQ("", stream_->data());
-}
-
-TEST_F(QuicSpdyClientStreamTest, TestFramingOnePacket) {
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
- EXPECT_EQ(200, stream_->response_code());
- EXPECT_EQ(body_, stream_->data());
-}
-
-TEST_F(QuicSpdyClientStreamTest, DISABLED_TestFramingExtraData) {
- QuicString large_body = "hello world!!!!!!";
-
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
- // The headers should parse successfully.
- EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
- EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
- EXPECT_EQ(200, stream_->response_code());
-
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, large_body));
-
- EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error());
-}
-
-TEST_F(QuicSpdyClientStreamTest, ReceivingTrailers) {
- // Test that receiving trailing headers, containing a final offset, results in
- // the stream being closed at that byte offset.
- // Send headers as usual.
- auto headers = AsHeaderList(headers_);
- stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
- headers);
-
- // Send trailers before sending the body. Even though a FIN has been received
- // the stream should not be closed, as it does not yet have all the data bytes
- // promised by the final offset field.
- SpdyHeaderBlock trailer_block;
- trailer_block["trailer key"] = "trailer value";
- trailer_block[kFinalOffsetHeaderKey] =
- QuicTextUtils::Uint64ToString(body_.size());
- auto trailers = AsHeaderList(trailer_block);
- stream_->OnStreamHeaderList(true, trailers.uncompressed_header_bytes(),
- trailers);
-
- // Now send the body, which should close the stream as the FIN has been
- // received, as well as all data.
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- EXPECT_TRUE(stream_->reading_stopped());
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_spdy_server_stream_base.cc b/chromium/net/tools/quic/quic_spdy_server_stream_base.cc
deleted file mode 100644
index f7af8734b51..00000000000
--- a/chromium/net/tools/quic/quic_spdy_server_stream_base.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2016 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/tools/quic/quic_spdy_server_stream_base.h"
-
-#include "net/quic/core/quic_error_codes.h"
-#include "net/quic/platform/api/quic_logging.h"
-
-namespace net {
-
-QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(QuicStreamId id,
- QuicSpdySession* session)
- : QuicSpdyStream(id, session) {}
-
-void QuicSpdyServerStreamBase::CloseWriteSide() {
- if (!fin_received() && !rst_received() && sequencer()->ignore_read_data() &&
- !rst_sent()) {
- // Early cancel the stream if it has stopped reading before receiving FIN
- // or RST.
- DCHECK(fin_sent());
- // Tell the peer to stop sending further data.
- QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
- Reset(QUIC_STREAM_NO_ERROR);
- }
-
- QuicSpdyStream::CloseWriteSide();
-}
-
-void QuicSpdyServerStreamBase::StopReading() {
- if (!fin_received() && !rst_received() && write_side_closed() &&
- !rst_sent()) {
- DCHECK(fin_sent());
- // Tell the peer to stop sending further data.
- QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
- Reset(QUIC_STREAM_NO_ERROR);
- }
- QuicSpdyStream::StopReading();
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_spdy_server_stream_base.h b/chromium/net/tools/quic/quic_spdy_server_stream_base.h
deleted file mode 100644
index 46462a16b83..00000000000
--- a/chromium/net/tools/quic/quic_spdy_server_stream_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2016 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_TOOLS_QUIC_QUIC_SPDY_SERVER_STREAM_BASE_H_
-#define NET_TOOLS_QUIC_QUIC_SPDY_SERVER_STREAM_BASE_H_
-
-#include "net/quic/core/quic_spdy_stream.h"
-
-namespace net {
-
-class QuicSpdyServerStreamBase : public QuicSpdyStream {
- public:
- QuicSpdyServerStreamBase(QuicStreamId id, QuicSpdySession* session);
-
- // Override the base class to send QUIC_STREAM_NO_ERROR to the peer
- // when the stream has not received all the data.
- void CloseWriteSide() override;
- void StopReading() override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(QuicSpdyServerStreamBase);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SPDY_SERVER_STREAM_BASE_H_
diff --git a/chromium/net/tools/quic/quic_spdy_server_stream_base_test.cc b/chromium/net/tools/quic/quic_spdy_server_stream_base_test.cc
deleted file mode 100644
index 869ca74c428..00000000000
--- a/chromium/net/tools/quic/quic_spdy_server_stream_base_test.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2016 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/tools/quic/quic_spdy_server_stream_base.h"
-
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/test_tools/quic_spdy_session_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-
-namespace net {
-namespace test {
-namespace {
-
-class TestQuicSpdyServerStream : public QuicSpdyServerStreamBase {
- public:
- TestQuicSpdyServerStream(QuicStreamId id, QuicSpdySession* session)
- : QuicSpdyServerStreamBase(id, session) {}
-
- void OnDataAvailable() override {}
-};
-
-class QuicSpdyServerStreamBaseTest : public QuicTest {
- protected:
- QuicSpdyServerStreamBaseTest()
- : session_(new MockQuicConnection(&helper_,
- &alarm_factory_,
- Perspective::IS_SERVER)) {
- stream_ = new TestQuicSpdyServerStream(
- QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, 0),
- &session_);
- session_.ActivateStream(QuicWrapUnique(stream_));
- }
-
- QuicSpdyServerStreamBase* stream_ = nullptr;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- MockQuicSpdySession session_;
-};
-
-TEST_F(QuicSpdyServerStreamBaseTest,
- SendQuicRstStreamNoErrorWithEarlyResponse) {
- stream_->StopReading();
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1);
- stream_->set_fin_sent(true);
- stream_->CloseWriteSide();
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest,
- DoNotSendQuicRstStreamNoErrorWithRstReceived) {
- EXPECT_FALSE(stream_->reading_stopped());
-
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
- EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _)).Times(1);
- QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
- QUIC_STREAM_CANCELLED, 1234);
- stream_->OnStreamReset(rst_frame);
-
- EXPECT_TRUE(stream_->reading_stopped());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager.cc b/chromium/net/tools/quic/quic_time_wait_list_manager.cc
deleted file mode 100644
index cdc8d632072..00000000000
--- a/chromium/net/tools/quic/quic_time_wait_list_manager.cc
+++ /dev/null
@@ -1,329 +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/tools/quic/quic_time_wait_list_manager.h"
-
-#include <errno.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/crypto/quic_decrypter.h"
-#include "net/quic/core/crypto/quic_encrypter.h"
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/platform/api/quic_clock.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_map_util.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-
-namespace net {
-
-// A very simple alarm that just informs the QuicTimeWaitListManager to clean
-// up old connection_ids. This alarm should be cancelled and deleted before
-// the QuicTimeWaitListManager is deleted.
-class ConnectionIdCleanUpAlarm : public QuicAlarm::Delegate {
- public:
- explicit ConnectionIdCleanUpAlarm(
- QuicTimeWaitListManager* time_wait_list_manager)
- : time_wait_list_manager_(time_wait_list_manager) {}
-
- void OnAlarm() override {
- time_wait_list_manager_->CleanUpOldConnectionIds();
- }
-
- private:
- // Not owned.
- QuicTimeWaitListManager* time_wait_list_manager_;
-
- DISALLOW_COPY_AND_ASSIGN(ConnectionIdCleanUpAlarm);
-};
-
-// This class stores pending public reset packets to be sent to clients.
-// server_address - server address on which a packet what was received for
-// a connection_id in time wait state.
-// client_address - address of the client that sent that packet. Needed to send
-// the public reset packet back to the client.
-// packet - the pending public reset packet that is to be sent to the client.
-// created instance takes the ownership of this packet.
-class QuicTimeWaitListManager::QueuedPacket {
- public:
- QueuedPacket(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- std::unique_ptr<QuicEncryptedPacket> packet)
- : server_address_(server_address),
- client_address_(client_address),
- packet_(std::move(packet)) {}
-
- const QuicSocketAddress& server_address() const { return server_address_; }
- const QuicSocketAddress& client_address() const { return client_address_; }
- QuicEncryptedPacket* packet() { return packet_.get(); }
-
- private:
- const QuicSocketAddress server_address_;
- const QuicSocketAddress client_address_;
- std::unique_ptr<QuicEncryptedPacket> packet_;
-
- DISALLOW_COPY_AND_ASSIGN(QueuedPacket);
-};
-
-QuicTimeWaitListManager::QuicTimeWaitListManager(
- QuicPacketWriter* writer,
- Visitor* visitor,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory)
- : time_wait_period_(
- QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)),
- connection_id_clean_up_alarm_(
- alarm_factory->CreateAlarm(new ConnectionIdCleanUpAlarm(this))),
- clock_(helper->GetClock()),
- writer_(writer),
- visitor_(visitor) {
- SetConnectionIdCleanUpAlarm();
-}
-
-QuicTimeWaitListManager::~QuicTimeWaitListManager() {
- connection_id_clean_up_alarm_->Cancel();
-}
-
-void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
- QuicConnectionId connection_id,
- ParsedQuicVersion version,
- bool ietf_quic,
- bool connection_rejected_statelessly,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) {
- if (connection_rejected_statelessly) {
- DCHECK(termination_packets != nullptr && !termination_packets->empty())
- << "Connections that were rejected statelessly must "
- << "have a close packet. connection_id = " << connection_id;
- }
- int num_packets = 0;
- ConnectionIdMap::iterator it = connection_id_map_.find(connection_id);
- const bool new_connection_id = it == connection_id_map_.end();
- if (!new_connection_id) { // Replace record if it is reinserted.
- num_packets = it->second.num_packets;
- connection_id_map_.erase(it);
- }
- TrimTimeWaitListIfNeeded();
- DCHECK_LT(num_connections(),
- static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections));
- ConnectionIdData data(num_packets, version, ietf_quic,
- clock_->ApproximateNow(),
- connection_rejected_statelessly);
- if (termination_packets != nullptr) {
- data.termination_packets.swap(*termination_packets);
- }
- connection_id_map_.emplace(std::make_pair(connection_id, std::move(data)));
- if (new_connection_id) {
- visitor_->OnConnectionAddedToTimeWaitList(connection_id);
- }
-}
-
-bool QuicTimeWaitListManager::IsConnectionIdInTimeWait(
- QuicConnectionId connection_id) const {
- return QuicContainsKey(connection_id_map_, connection_id);
-}
-
-ParsedQuicVersion QuicTimeWaitListManager::GetQuicVersionFromConnectionId(
- QuicConnectionId connection_id) {
- ConnectionIdMap::iterator it = connection_id_map_.find(connection_id);
- DCHECK(it != connection_id_map_.end());
- return (it->second).version;
-}
-
-void QuicTimeWaitListManager::OnBlockedWriterCanWrite() {
- while (!pending_packets_queue_.empty()) {
- QueuedPacket* queued_packet = pending_packets_queue_.front().get();
- if (!WriteToWire(queued_packet)) {
- return;
- }
- pending_packets_queue_.pop_front();
- }
-}
-
-void QuicTimeWaitListManager::ProcessPacket(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- QuicConnectionId connection_id) {
- DCHECK(IsConnectionIdInTimeWait(connection_id));
- QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state.";
- // TODO(satyamshekhar): Think about handling packets from different client
- // addresses.
- ConnectionIdMap::iterator it = connection_id_map_.find(connection_id);
- DCHECK(it != connection_id_map_.end());
- // Increment the received packet count.
- ConnectionIdData* connection_data = &it->second;
- ++(connection_data->num_packets);
-
- if (!ShouldSendResponse(connection_data->num_packets)) {
- return;
- }
-
- if (!connection_data->termination_packets.empty()) {
- if (connection_data->connection_rejected_statelessly) {
- QUIC_DVLOG(3)
- << "Time wait list sending previous stateless reject response "
- << "for connection " << connection_id;
- }
- for (const auto& packet : connection_data->termination_packets) {
- SendOrQueuePacket(QuicMakeUnique<QueuedPacket>(
- server_address, client_address, packet->Clone()));
- }
- return;
- }
-
- SendPublicReset(server_address, client_address, connection_id);
-}
-
-void QuicTimeWaitListManager::SendVersionNegotiationPacket(
- QuicConnectionId connection_id,
- bool ietf_quic,
- const ParsedQuicVersionVector& supported_versions,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address) {
- SendOrQueuePacket(QuicMakeUnique<QueuedPacket>(
- server_address, client_address,
- QuicFramer::BuildVersionNegotiationPacket(connection_id, ietf_quic,
- supported_versions)));
-}
-
-// Returns true if the number of packets received for this connection_id is a
-// power of 2 to throttle the number of public reset packets we send to a
-// client.
-bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) {
- return (received_packet_count & (received_packet_count - 1)) == 0;
-}
-
-void QuicTimeWaitListManager::SendPublicReset(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- QuicConnectionId connection_id) {
- QuicPublicResetPacket packet;
- packet.connection_id = connection_id;
- // TODO(satyamshekhar): generate a valid nonce for this connection_id.
- packet.nonce_proof = 1010101;
- packet.client_address = client_address;
- // Takes ownership of the packet.
- SendOrQueuePacket(QuicMakeUnique<QueuedPacket>(server_address, client_address,
- BuildPublicReset(packet)));
-}
-
-std::unique_ptr<QuicEncryptedPacket> QuicTimeWaitListManager::BuildPublicReset(
- const QuicPublicResetPacket& packet) {
- return QuicFramer::BuildPublicResetPacket(packet);
-}
-
-// Either sends the packet and deletes it or makes pending queue the
-// owner of the packet.
-void QuicTimeWaitListManager::SendOrQueuePacket(
- std::unique_ptr<QueuedPacket> packet) {
- if (WriteToWire(packet.get())) {
- // Allow the packet to be deleted upon leaving this function.
- return;
- }
- pending_packets_queue_.push_back(std::move(packet));
-}
-
-bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) {
- if (writer_->IsWriteBlocked()) {
- visitor_->OnWriteBlocked(this);
- return false;
- }
- WriteResult result = writer_->WritePacket(
- queued_packet->packet()->data(), queued_packet->packet()->length(),
- queued_packet->server_address().host(), queued_packet->client_address(),
- nullptr);
- if (result.status == WRITE_STATUS_BLOCKED) {
- // If blocked and unbuffered, return false to retry sending.
- DCHECK(writer_->IsWriteBlocked());
- visitor_->OnWriteBlocked(this);
- return writer_->IsWriteBlockedDataBuffered();
- } else if (IsWriteError(result.status)) {
- QUIC_LOG_FIRST_N(WARNING, 1)
- << "Received unknown error while sending reset packet to "
- << queued_packet->client_address().ToString() << ": "
- << strerror(result.error_code);
- }
- return true;
-}
-
-void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() {
- QuicTime::Delta next_alarm_interval = QuicTime::Delta::Zero();
- if (!connection_id_map_.empty()) {
- QuicTime oldest_connection_id =
- connection_id_map_.begin()->second.time_added;
- QuicTime now = clock_->ApproximateNow();
- if (now - oldest_connection_id < time_wait_period_) {
- next_alarm_interval = oldest_connection_id + time_wait_period_ - now;
- } else {
- QUIC_LOG(ERROR)
- << "ConnectionId lingered for longer than time_wait_period_";
- }
- } else {
- // No connection_ids added so none will expire before time_wait_period_.
- next_alarm_interval = time_wait_period_;
- }
-
- connection_id_clean_up_alarm_->Update(
- clock_->ApproximateNow() + next_alarm_interval, QuicTime::Delta::Zero());
-}
-
-bool QuicTimeWaitListManager::MaybeExpireOldestConnection(
- QuicTime expiration_time) {
- if (connection_id_map_.empty()) {
- return false;
- }
- ConnectionIdMap::iterator it = connection_id_map_.begin();
- QuicTime oldest_connection_id_time = it->second.time_added;
- if (oldest_connection_id_time > expiration_time) {
- // Too recent, don't retire.
- return false;
- }
- // This connection_id has lived its age, retire it now.
- connection_id_map_.erase(it);
- return true;
-}
-
-void QuicTimeWaitListManager::CleanUpOldConnectionIds() {
- QuicTime now = clock_->ApproximateNow();
- QuicTime expiration = now - time_wait_period_;
-
- while (MaybeExpireOldestConnection(expiration)) {
- }
-
- SetConnectionIdCleanUpAlarm();
-}
-
-void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
- if (FLAGS_quic_time_wait_list_max_connections < 0) {
- return;
- }
- while (num_connections() >=
- static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)) {
- MaybeExpireOldestConnection(QuicTime::Infinite());
- }
-}
-
-QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
- int num_packets,
- ParsedQuicVersion version,
- bool ietf_quic,
- QuicTime time_added,
- bool connection_rejected_statelessly)
- : num_packets(num_packets),
- version(version),
- ietf_quic(ietf_quic),
- time_added(time_added),
- connection_rejected_statelessly(connection_rejected_statelessly) {}
-
-QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
- ConnectionIdData&& other) = default;
-
-QuicTimeWaitListManager::ConnectionIdData::~ConnectionIdData() = default;
-
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager.h b/chromium/net/tools/quic/quic_time_wait_list_manager.h
deleted file mode 100644
index e5ab534b860..00000000000
--- a/chromium/net/tools/quic/quic_time_wait_list_manager.h
+++ /dev/null
@@ -1,215 +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.
-//
-// Handles packets for connection_ids in time wait state by discarding the
-// packet and sending the clients a public reset packet with exponential
-// backoff.
-
-#ifndef NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_
-#define NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_blocked_writer_interface.h"
-#include "net/quic/core/quic_connection.h"
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/core/quic_packet_writer.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_session.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/quic/platform/api/quic_flags.h"
-
-namespace net {
-
-namespace test {
-class QuicDispatcherPeer;
-class QuicTimeWaitListManagerPeer;
-} // namespace test
-
-// Maintains a list of all connection_ids that have been recently closed. A
-// connection_id lives in this state for time_wait_period_. All packets received
-// for connection_ids in this state are handed over to the
-// QuicTimeWaitListManager by the QuicDispatcher. Decides whether to send a
-// public reset packet, a copy of the previously sent connection close packet,
-// or nothing to the client which sent a packet with the connection_id in time
-// wait state. After the connection_id expires its time wait period, a new
-// connection/session will be created if a packet is received for this
-// connection_id.
-class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
- public:
- class Visitor : public QuicSession::Visitor {
- public:
- // Called after the given connection is added to the time-wait std::list.
- virtual void OnConnectionAddedToTimeWaitList(
- QuicConnectionId connection_id) = 0;
- };
-
- // writer - the entity that writes to the socket. (Owned by the dispatcher)
- // visitor - the entity that manages blocked writers. (The dispatcher)
- // helper - provides a clock (Owned by the dispatcher)
- // alarm_factory - used to run clean up alarms. (Owned by the dispatcher)
- QuicTimeWaitListManager(QuicPacketWriter* writer,
- Visitor* visitor,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory);
- ~QuicTimeWaitListManager() override;
-
- // Adds the given connection_id to time wait state for time_wait_period_.
- // If |termination_packets| are provided, copies of these packets will be sent
- // when a packet with this connection ID is processed. If no termination
- // packets are provided, then a PUBLIC_RESET will be sent with the specified
- // |version|. Any termination packets will be move from |termination_packets|
- // and will become owned by the manager. If |connection_rejected_statelessly|
- // is true, it means that the connection was closed due to a stateless reject,
- // and termination packets are expected.
- virtual void AddConnectionIdToTimeWait(
- QuicConnectionId connection_id,
- ParsedQuicVersion version,
- bool ietf_quic,
- bool connection_rejected_statelessly,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets);
-
- // Returns true if the connection_id is in time wait state, false otherwise.
- // Packets received for this connection_id should not lead to creation of new
- // QuicSessions.
- bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) const;
-
- // Called when a packet is received for a connection_id that is in time wait
- // state. Sends a public reset packet to the client which sent this
- // connection_id. Sending of the public reset packet is throttled by using
- // exponential back off. DCHECKs for the connection_id to be in time wait
- // state. virtual to override in tests.
- virtual void ProcessPacket(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- QuicConnectionId connection_id);
-
- // Called by the dispatcher when the underlying socket becomes writable again,
- // since we might need to send pending public reset packets which we didn't
- // send because the underlying socket was write blocked.
- void OnBlockedWriterCanWrite() override;
-
- // Used to delete connection_id entries that have outlived their time wait
- // period.
- void CleanUpOldConnectionIds();
-
- // If necessary, trims the oldest connections from the time-wait list until
- // the size is under the configured maximum.
- void TrimTimeWaitListIfNeeded();
-
- // Given a ConnectionId that exists in the time wait list, returns the
- // ParsedQuicVersion associated with it.
- ParsedQuicVersion GetQuicVersionFromConnectionId(
- QuicConnectionId connection_id);
-
- // The number of connections on the time-wait list.
- size_t num_connections() const { return connection_id_map_.size(); }
-
- // Sends a version negotiation packet for |connection_id| announcing support
- // for |supported_versions| to |client_address| from |server_address|.
- virtual void SendVersionNegotiationPacket(
- QuicConnectionId connection_id,
- bool ietf_quic,
- const ParsedQuicVersionVector& supported_versions,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address);
-
- protected:
- virtual std::unique_ptr<QuicEncryptedPacket> BuildPublicReset(
- const QuicPublicResetPacket& packet);
-
- // Creates a public reset packet and sends it or queues it to be sent later.
- virtual void SendPublicReset(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- QuicConnectionId connection_id);
-
- private:
- friend class test::QuicDispatcherPeer;
- friend class test::QuicTimeWaitListManagerPeer;
-
- // Internal structure to store pending public reset packets.
- class QueuedPacket;
-
- // Decides if a packet should be sent for this connection_id based on the
- // number of received packets.
- bool ShouldSendResponse(int received_packet_count);
-
- // Either sends the packet and deletes it or makes pending_packets_queue_ the
- // owner of the packet.
- void SendOrQueuePacket(std::unique_ptr<QueuedPacket> packet);
-
- // Sends the packet out. Returns true if the packet was successfully consumed.
- // If the writer got blocked and did not buffer the packet, we'll need to keep
- // the packet and retry sending. In case of all other errors we drop the
- // packet.
- bool WriteToWire(QueuedPacket* packet);
-
- // Register the alarm server to wake up at appropriate time.
- void SetConnectionIdCleanUpAlarm();
-
- // Removes the oldest connection from the time-wait list if it was added prior
- // to "expiration_time". To unconditionally remove the oldest connection, use
- // a QuicTime::Delta:Infinity(). This function modifies the
- // connection_id_map_. If you plan to call this function in a loop, any
- // iterators that you hold before the call to this function may be invalid
- // afterward. Returns true if the oldest connection was expired. Returns
- // false if the map is empty or the oldest connection has not expired.
- bool MaybeExpireOldestConnection(QuicTime expiration_time);
-
- // A map from a recently closed connection_id to the number of packets
- // received after the termination of the connection bound to the
- // connection_id.
- struct ConnectionIdData {
- ConnectionIdData(int num_packets,
- ParsedQuicVersion version,
- bool ietf_quic,
- QuicTime time_added,
- bool connection_rejected_statelessly);
-
- ConnectionIdData(const ConnectionIdData& other) = delete;
- ConnectionIdData(ConnectionIdData&& other);
-
- ~ConnectionIdData();
-
- int num_packets;
- ParsedQuicVersion version;
- bool ietf_quic;
- QuicTime time_added;
- // These packets may contain CONNECTION_CLOSE frames, or SREJ messages.
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- bool connection_rejected_statelessly;
- };
-
- // QuicLinkedHashMap allows lookup by ConnectionId and traversal in add order.
- typedef QuicLinkedHashMap<QuicConnectionId, ConnectionIdData> ConnectionIdMap;
- ConnectionIdMap connection_id_map_;
-
- // Pending public reset packets that need to be sent out to the client
- // when we are given a chance to write by the dispatcher.
- QuicDeque<std::unique_ptr<QueuedPacket>> pending_packets_queue_;
-
- // Time period for which connection_ids should remain in time wait state.
- const QuicTime::Delta time_wait_period_;
-
- // Alarm to clean up connection_ids that have out lived their duration in
- // time wait state.
- std::unique_ptr<QuicAlarm> connection_id_clean_up_alarm_;
-
- // Clock to efficiently measure approximate time.
- const QuicClock* clock_;
-
- // Interface that writes given buffer to the socket.
- QuicPacketWriter* writer_;
-
- // Interface that manages blocked writers.
- Visitor* visitor_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicTimeWaitListManager);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc b/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc
deleted file mode 100644
index 225471f9115..00000000000
--- a/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc
+++ /dev/null
@@ -1,501 +0,0 @@
-// Copyright 2013 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/tools/quic/quic_time_wait_list_manager.h"
-
-#include <errno.h>
-#include <memory>
-#include <ostream>
-
-#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/crypto/null_encrypter.h"
-#include "net/quic/core/crypto/quic_decrypter.h"
-#include "net/quic/core/crypto/quic_encrypter.h"
-#include "net/quic/core/quic_data_reader.h"
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/core/quic_packet_writer.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/quic/test_tools/quic_time_wait_list_manager_peer.h"
-#include "net/tools/quic/quic_epoll_alarm_factory.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-#include "net/tools/quic/test_tools/mock_epoll_server.h"
-#include "net/tools/quic/test_tools/mock_quic_session_visitor.h"
-
-using testing::_;
-using testing::Args;
-using testing::Assign;
-using testing::DoAll;
-using testing::Matcher;
-using testing::NiceMock;
-using testing::Return;
-using testing::ReturnPointee;
-using testing::StrictMock;
-using testing::Truly;
-
-namespace net {
-namespace test {
-namespace {
-
-class FramerVisitorCapturingPublicReset : public NoOpFramerVisitor {
- public:
- FramerVisitorCapturingPublicReset() = default;
- ~FramerVisitorCapturingPublicReset() override = default;
-
- void OnPublicResetPacket(const QuicPublicResetPacket& public_reset) override {
- public_reset_packet_ = public_reset;
- }
-
- const QuicPublicResetPacket public_reset_packet() {
- return public_reset_packet_;
- }
-
- private:
- QuicPublicResetPacket public_reset_packet_;
-};
-
-class MockFakeTimeEpollServer : public FakeTimeEpollServer {
- public:
- MOCK_METHOD2(RegisterAlarm,
- void(int64_t timeout_in_us, EpollAlarmCallbackInterface* alarm));
-};
-
-class QuicTimeWaitListManagerTest : public QuicTest {
- protected:
- QuicTimeWaitListManagerTest()
- : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL),
- alarm_factory_(&epoll_server_),
- time_wait_list_manager_(&writer_, &visitor_, &helper_, &alarm_factory_),
- connection_id_(45),
- client_address_(TestPeerIPAddress(), kTestPort),
- writer_is_blocked_(false) {}
-
- ~QuicTimeWaitListManagerTest() override = default;
-
- void SetUp() override {
- EXPECT_CALL(writer_, IsWriteBlocked())
- .WillRepeatedly(ReturnPointee(&writer_is_blocked_));
- EXPECT_CALL(writer_, IsWriteBlockedDataBuffered())
- .WillRepeatedly(Return(false));
- }
-
- void AddConnectionId(QuicConnectionId connection_id) {
- AddConnectionId(connection_id, QuicVersionMax(),
- /*connection_rejected_statelessly=*/false, nullptr);
- }
-
- void AddStatelessConnectionId(QuicConnectionId connection_id) {
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(std::unique_ptr<QuicEncryptedPacket>(
- new QuicEncryptedPacket(nullptr, 0, false)));
- time_wait_list_manager_.AddConnectionIdToTimeWait(
- connection_id, QuicVersionMax(), false,
- /*connection_rejected_statelessly=*/true, &termination_packets);
- }
-
- void AddConnectionId(
- QuicConnectionId connection_id,
- ParsedQuicVersion version,
- bool connection_rejected_statelessly,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
- time_wait_list_manager_.AddConnectionIdToTimeWait(
- connection_id, version, false, connection_rejected_statelessly,
- packets);
- }
-
- bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
- return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id);
- }
-
- void ProcessPacket(QuicConnectionId connection_id) {
- time_wait_list_manager_.ProcessPacket(server_address_, client_address_,
- connection_id);
- }
-
- QuicEncryptedPacket* ConstructEncryptedPacket(
- QuicConnectionId connection_id,
- QuicPacketNumber packet_number) {
- return net::test::ConstructEncryptedPacket(connection_id, false, false,
- packet_number, "data");
- }
-
- NiceMock<MockFakeTimeEpollServer> epoll_server_;
- QuicEpollConnectionHelper helper_;
- QuicEpollAlarmFactory alarm_factory_;
- StrictMock<MockPacketWriter> writer_;
- StrictMock<MockQuicSessionVisitor> visitor_;
- QuicTimeWaitListManager time_wait_list_manager_;
- QuicConnectionId connection_id_;
- QuicSocketAddress server_address_;
- QuicSocketAddress client_address_;
- bool writer_is_blocked_;
-};
-
-bool ValidPublicResetPacketPredicate(
- QuicConnectionId expected_connection_id,
- const testing::tuple<const char*, int>& packet_buffer) {
- FramerVisitorCapturingPublicReset visitor;
- QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
- Perspective::IS_CLIENT);
- framer.set_visitor(&visitor);
- QuicEncryptedPacket encrypted(testing::get<0>(packet_buffer),
- testing::get<1>(packet_buffer));
- framer.ProcessPacket(encrypted);
- QuicPublicResetPacket packet = visitor.public_reset_packet();
- return expected_connection_id == packet.connection_id &&
- TestPeerIPAddress() == packet.client_address.host() &&
- kTestPort == packet.client_address.port();
-}
-
-Matcher<const testing::tuple<const char*, int>> PublicResetPacketEq(
- QuicConnectionId connection_id) {
- return Truly(
- [connection_id](const testing::tuple<const char*, int> packet_buffer) {
- return ValidPublicResetPacketPredicate(connection_id, packet_buffer);
- });
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CheckConnectionIdInTimeWait) {
- EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddConnectionId(connection_id_);
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
- EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddStatelessConnectionId(connection_id_);
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
- std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(connection_id_, false,
- AllSupportedVersions()));
- EXPECT_CALL(writer_, WritePacket(_, packet->length(), server_address_.host(),
- client_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- time_wait_list_manager_.SendVersionNegotiationPacket(
- connection_id_, false, AllSupportedVersions(), server_address_,
- client_address_);
- EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) {
- const size_t kConnectionCloseLength = 100;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- AddConnectionId(connection_id_, QuicVersionMax(),
- /*connection_rejected_statelessly=*/false,
- &termination_packets);
- EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- server_address_.host(), client_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) {
- const size_t kConnectionCloseLength = 100;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- AddConnectionId(connection_id_, QuicVersionMax(),
- /*connection_rejected_statelessly=*/false,
- &termination_packets);
- EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- server_address_.host(), client_address_, _))
- .Times(2)
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) {
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddConnectionId(connection_id_);
- EXPECT_CALL(writer_,
- WritePacket(_, _, server_address_.host(), client_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
- ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) {
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddConnectionId(connection_id_);
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
- for (int packet_number = 1; packet_number < 101; ++packet_number) {
- if ((packet_number & (packet_number - 1)) == 0) {
- EXPECT_CALL(writer_, WritePacket(_, _, _, _, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
- }
- ProcessPacket(connection_id_);
- // Send public reset with exponential back off.
- if ((packet_number & (packet_number - 1)) == 0) {
- EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
- &time_wait_list_manager_, packet_number));
- } else {
- EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
- &time_wait_list_manager_, packet_number));
- }
- }
-}
-
-TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) {
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddStatelessConnectionId(connection_id_);
-
- EXPECT_CALL(writer_,
- WritePacket(_, _, server_address_.host(), client_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
- const size_t kConnectionIdCount = 100;
- const size_t kOldConnectionIdCount = 31;
-
- // Add connection_ids such that their expiry time is time_wait_period_.
- epoll_server_.set_now_in_usec(0);
- for (size_t connection_id = 1; connection_id <= kOldConnectionIdCount;
- ++connection_id) {
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
- AddConnectionId(connection_id);
- }
- EXPECT_EQ(kOldConnectionIdCount, time_wait_list_manager_.num_connections());
-
- // Add remaining connection_ids such that their add time is
- // 2 * time_wait_period_.
- const QuicTime::Delta time_wait_period =
- QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
- epoll_server_.set_now_in_usec(time_wait_period.ToMicroseconds());
- for (size_t connection_id = kOldConnectionIdCount + 1;
- connection_id <= kConnectionIdCount; ++connection_id) {
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
- AddConnectionId(connection_id);
- }
- EXPECT_EQ(kConnectionIdCount, time_wait_list_manager_.num_connections());
-
- QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
- // Now set the current time as time_wait_period + offset usecs.
- epoll_server_.set_now_in_usec((time_wait_period + offset).ToMicroseconds());
- // After all the old connection_ids are cleaned up, check the next alarm
- // interval.
- int64_t next_alarm_time = epoll_server_.ApproximateNowInUsec() +
- (time_wait_period - offset).ToMicroseconds();
- EXPECT_CALL(epoll_server_, RegisterAlarm(next_alarm_time, _));
-
- time_wait_list_manager_.CleanUpOldConnectionIds();
- for (size_t connection_id = 1; connection_id <= kConnectionIdCount;
- ++connection_id) {
- EXPECT_EQ(connection_id > kOldConnectionIdCount,
- IsConnectionIdInTimeWait(connection_id))
- << "kOldConnectionIdCount: " << kOldConnectionIdCount
- << " connection_id: " << connection_id;
- }
- EXPECT_EQ(kConnectionIdCount - kOldConnectionIdCount,
- time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
- QuicConnectionId connection_id = 1;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
- AddConnectionId(connection_id);
- QuicPacketNumber packet_number = 234;
- std::unique_ptr<QuicEncryptedPacket> packet(
- ConstructEncryptedPacket(connection_id, packet_number));
- // Let first write through.
- EXPECT_CALL(writer_,
- WritePacket(_, _, server_address_.host(), client_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
- ProcessPacket(connection_id);
-
- // write block for the next packet.
- EXPECT_CALL(writer_,
- WritePacket(_, _, server_address_.host(), client_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
- .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
- Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
- EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
- ProcessPacket(connection_id);
- // 3rd packet. No public reset should be sent;
- ProcessPacket(connection_id);
-
- // write packet should not be called since we are write blocked but the
- // should be queued.
- QuicConnectionId other_connection_id = 2;
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
- AddConnectionId(other_connection_id);
- QuicPacketNumber other_packet_number = 23423;
- std::unique_ptr<QuicEncryptedPacket> other_packet(
- ConstructEncryptedPacket(other_connection_id, other_packet_number));
- EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0);
- EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
- ProcessPacket(other_connection_id);
- EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
-
- // Now expect all the write blocked public reset packets to be sent again.
- writer_is_blocked_ = false;
- EXPECT_CALL(writer_,
- WritePacket(_, _, server_address_.host(), client_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
- EXPECT_CALL(writer_,
- WritePacket(_, _, server_address_.host(), client_address_, _))
- .With(Args<0, 1>(PublicResetPacketEq(other_connection_id)))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, other_packet->length())));
- time_wait_list_manager_.OnBlockedWriterCanWrite();
-}
-
-TEST_F(QuicTimeWaitListManagerTest, GetQuicVersionFromMap) {
- const int kConnectionId1 = 123;
- const int kConnectionId2 = 456;
- const int kConnectionId3 = 789;
-
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(kConnectionId1));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(kConnectionId2));
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(kConnectionId3));
- AddConnectionId(kConnectionId1, QuicVersionMin(),
- /*connection_rejected_statelessly=*/false, nullptr);
- AddConnectionId(kConnectionId2, QuicVersionMax(),
- /*connection_rejected_statelessly=*/false, nullptr);
- AddConnectionId(kConnectionId3, QuicVersionMax(),
- /*connection_rejected_statelessly=*/false, nullptr);
-
- EXPECT_EQ(QuicTransportVersionMin(),
- QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
- &time_wait_list_manager_, kConnectionId1));
- EXPECT_EQ(QuicTransportVersionMax(),
- QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
- &time_wait_list_manager_, kConnectionId2));
- EXPECT_EQ(QuicTransportVersionMax(),
- QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
- &time_wait_list_manager_, kConnectionId3));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
- // Add connection_ids such that their expiry time is time_wait_period_.
- epoll_server_.set_now_in_usec(0);
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
- AddConnectionId(connection_id_);
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
- const size_t kConnectionCloseLength = 100;
- std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
- termination_packets.push_back(
- std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
- new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- AddConnectionId(connection_id_, QuicVersionMax(),
- /*connection_rejected_statelessly=*/false,
- &termination_packets);
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-
- EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- server_address_.host(), client_address_, _))
- .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
- ProcessPacket(connection_id_);
-
- const QuicTime::Delta time_wait_period =
- QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
-
- QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
- // Now set the current time as time_wait_period + offset usecs.
- epoll_server_.set_now_in_usec((time_wait_period + offset).ToMicroseconds());
- // After the connection_ids are cleaned up, check the next alarm interval.
- int64_t next_alarm_time =
- epoll_server_.ApproximateNowInUsec() + time_wait_period.ToMicroseconds();
-
- EXPECT_CALL(epoll_server_, RegisterAlarm(next_alarm_time, _));
- time_wait_list_manager_.CleanUpOldConnectionIds();
- EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
- EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, ConnectionIdsOrderedByTime) {
- // Simple randomization: the values of connection_ids are randomly swapped.
- // If the container is broken, the test will be 50% flaky.
- const QuicConnectionId connection_id1 =
- QuicRandom::GetInstance()->RandUint64() % 2;
- const QuicConnectionId connection_id2 = 1 - connection_id1;
-
- // 1 will hash lower than 2, but we add it later. They should come out in the
- // add order, not hash order.
- epoll_server_.set_now_in_usec(0);
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id1));
- AddConnectionId(connection_id1);
- epoll_server_.set_now_in_usec(10);
- EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id2));
- AddConnectionId(connection_id2);
- EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
-
- const QuicTime::Delta time_wait_period =
- QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
- epoll_server_.set_now_in_usec(time_wait_period.ToMicroseconds() + 1);
-
- EXPECT_CALL(epoll_server_, RegisterAlarm(_, _));
-
- time_wait_list_manager_.CleanUpOldConnectionIds();
- EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1));
- EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id2));
- EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
- // Basically, shut off time-based eviction.
- FLAGS_quic_time_wait_list_seconds = 10000000000;
- FLAGS_quic_time_wait_list_max_connections = 5;
-
- QuicConnectionId current_connection_id = 0;
- // Add exactly the maximum number of connections
- for (int64_t i = 0; i < FLAGS_quic_time_wait_list_max_connections; ++i) {
- ++current_connection_id;
- EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
- EXPECT_CALL(visitor_,
- OnConnectionAddedToTimeWaitList(current_connection_id));
- AddConnectionId(current_connection_id);
- EXPECT_EQ(current_connection_id, time_wait_list_manager_.num_connections());
- EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
- }
-
- // Now keep adding. Since we're already at the max, every new connection-id
- // will evict the oldest one.
- for (int64_t i = 0; i < FLAGS_quic_time_wait_list_max_connections; ++i) {
- ++current_connection_id;
- const QuicConnectionId id_to_evict =
- current_connection_id - FLAGS_quic_time_wait_list_max_connections;
- EXPECT_TRUE(IsConnectionIdInTimeWait(id_to_evict));
- EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
- EXPECT_CALL(visitor_,
- OnConnectionAddedToTimeWaitList(current_connection_id));
- AddConnectionId(current_connection_id);
- EXPECT_EQ(static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections),
- time_wait_list_manager_.num_connections());
- EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict));
- EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/stateless_rejector.cc b/chromium/net/tools/quic/stateless_rejector.cc
deleted file mode 100644
index 8ae3e851494..00000000000
--- a/chromium/net/tools/quic/stateless_rejector.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2016 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/tools/quic/stateless_rejector.h"
-
-#include "net/quic/core/quic_crypto_server_stream.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_string.h"
-
-namespace net {
-
-class StatelessRejector::ValidateCallback
- : public ValidateClientHelloResultCallback {
- public:
- explicit ValidateCallback(
- std::unique_ptr<StatelessRejector> rejector,
- std::unique_ptr<StatelessRejector::ProcessDoneCallback> cb)
- : rejector_(std::move(rejector)), cb_(std::move(cb)) {}
-
- ~ValidateCallback() override = default;
-
- void Run(QuicReferenceCountedPointer<Result> result,
- std::unique_ptr<ProofSource::Details> /* proof_source_details */)
- override {
- StatelessRejector* rejector_ptr = rejector_.get();
- rejector_ptr->ProcessClientHello(std::move(result), std::move(rejector_),
- std::move(cb_));
- }
-
- private:
- std::unique_ptr<StatelessRejector> rejector_;
- std::unique_ptr<StatelessRejector::ProcessDoneCallback> cb_;
-};
-
-StatelessRejector::StatelessRejector(
- QuicTransportVersion version,
- const QuicTransportVersionVector& versions,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- const QuicClock* clock,
- QuicRandom* random,
- QuicByteCount chlo_packet_size,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& server_address)
- : state_(UNKNOWN),
- error_(QUIC_INTERNAL_ERROR),
- version_(version),
- versions_(versions),
- connection_id_(0),
- chlo_packet_size_(chlo_packet_size),
- client_address_(client_address),
- server_address_(server_address),
- clock_(clock),
- random_(random),
- crypto_config_(crypto_config),
- compressed_certs_cache_(compressed_certs_cache),
- signed_config_(new QuicSignedServerConfig),
- params_(new QuicCryptoNegotiatedParameters) {}
-
-StatelessRejector::~StatelessRejector() = default;
-
-void StatelessRejector::OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
- QuicConnectionId server_designated_connection_id,
- const CryptoHandshakeMessage& message) {
- DCHECK_EQ(kCHLO, message.tag());
- DCHECK_NE(connection_id, server_designated_connection_id);
- DCHECK_EQ(state_, UNKNOWN);
-
- if (!GetQuicReloadableFlag(enable_quic_stateless_reject_support) ||
- !GetQuicReloadableFlag(quic_use_cheap_stateless_rejects) ||
- !QuicCryptoServerStream::DoesPeerSupportStatelessRejects(message)) {
- state_ = UNSUPPORTED;
- return;
- }
-
- connection_id_ = connection_id;
- server_designated_connection_id_ = server_designated_connection_id;
- chlo_ = message; // Note: copies the message
-}
-
-void StatelessRejector::Process(std::unique_ptr<StatelessRejector> rejector,
- std::unique_ptr<ProcessDoneCallback> done_cb) {
- QUIC_BUG_IF(rejector->state() != UNKNOWN) << "StatelessRejector::Process "
- "called for a rejector which "
- "has already made a decision";
- StatelessRejector* rejector_ptr = rejector.get();
- rejector_ptr->crypto_config_->ValidateClientHello(
- rejector_ptr->chlo_, rejector_ptr->client_address_.host(),
- rejector_ptr->server_address_, rejector_ptr->version_,
- rejector_ptr->clock_, rejector_ptr->signed_config_,
- std::unique_ptr<ValidateCallback>(
- new ValidateCallback(std::move(rejector), std::move(done_cb))));
-}
-
-class StatelessRejector::ProcessClientHelloCallback
- : public ProcessClientHelloResultCallback {
- public:
- ProcessClientHelloCallback(
- std::unique_ptr<StatelessRejector> rejector,
- std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb)
- : rejector_(std::move(rejector)), done_cb_(std::move(done_cb)) {}
-
- void Run(QuicErrorCode error,
- const QuicString& error_details,
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<DiversificationNonce> diversification_nonce,
- std::unique_ptr<ProofSource::Details> /* proof_source_details */)
- override {
- StatelessRejector* rejector_ptr = rejector_.get();
- rejector_ptr->ProcessClientHelloDone(
- error, error_details, std::move(message), std::move(rejector_),
- std::move(done_cb_));
- }
-
- private:
- std::unique_ptr<StatelessRejector> rejector_;
- std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb_;
-};
-
-void StatelessRejector::ProcessClientHello(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result,
- std::unique_ptr<StatelessRejector> rejector,
- std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb) {
- std::unique_ptr<ProcessClientHelloCallback> cb(
- new ProcessClientHelloCallback(std::move(rejector), std::move(done_cb)));
- crypto_config_->ProcessClientHello(
- result,
- /*reject_only=*/true, connection_id_, server_address_, client_address_,
- version_, versions_,
- /*use_stateless_rejects=*/true, server_designated_connection_id_, clock_,
- random_, compressed_certs_cache_, params_, signed_config_,
- QuicCryptoStream::CryptoMessageFramingOverhead(version_),
- chlo_packet_size_, std::move(cb));
-}
-
-void StatelessRejector::ProcessClientHelloDone(
- QuicErrorCode error,
- const QuicString& error_details,
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<StatelessRejector> rejector,
- std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb) {
- reply_ = std::move(message);
-
- if (error != QUIC_NO_ERROR) {
- error_ = error;
- error_details_ = error_details;
- state_ = FAILED;
- } else if (reply_->tag() == kSREJ) {
- state_ = REJECTED;
- } else {
- state_ = ACCEPTED;
- }
- done_cb->Run(std::move(rejector));
-}
-
-} // namespace net
diff --git a/chromium/net/tools/quic/stateless_rejector.h b/chromium/net/tools/quic/stateless_rejector.h
deleted file mode 100644
index ac04e402665..00000000000
--- a/chromium/net/tools/quic/stateless_rejector.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2016 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_TOOLS_QUIC_STATELESS_REJECTOR_H_
-#define NET_TOOLS_QUIC_STATELESS_REJECTOR_H_
-
-#include "net/quic/core/crypto/crypto_framer.h"
-#include "net/quic/core/crypto/quic_crypto_server_config.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/platform/api/quic_string.h"
-
-namespace net {
-
-// The StatelessRejector receives CHLO messages and generates an SREJ
-// message in response, if the CHLO can be statelessly rejected.
-class StatelessRejector {
- public:
- enum State {
- UNKNOWN, // State has not yet been determined
- UNSUPPORTED, // Stateless rejects are not supported
- FAILED, // There was an error processing the CHLO.
- ACCEPTED, // The CHLO was accepted
- REJECTED, // The CHLO was rejected.
- };
-
- StatelessRejector(QuicTransportVersion version,
- const QuicTransportVersionVector& versions,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- const QuicClock* clock,
- QuicRandom* random,
- QuicByteCount chlo_packet_size,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& server_address);
-
- ~StatelessRejector();
-
- // Called when |chlo| is received for |connection_id|.
- void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
- QuicConnectionId server_designated_connection_id,
- const CryptoHandshakeMessage& chlo);
-
- class ProcessDoneCallback {
- public:
- virtual ~ProcessDoneCallback() = default;
- virtual void Run(std::unique_ptr<StatelessRejector> rejector) = 0;
- };
-
- // Perform processing to determine whether the CHLO received in OnChlo should
- // be statelessly rejected, and invoke the callback once a decision has been
- // made.
- static void Process(std::unique_ptr<StatelessRejector> rejector,
- std::unique_ptr<ProcessDoneCallback> done_cb);
-
- // Returns the state of the rejector after OnChlo() has been called.
- State state() const { return state_; }
-
- // Returns the error code when state() returns FAILED.
- QuicErrorCode error() const { return error_; }
-
- // Returns the error details when state() returns FAILED.
- QuicString error_details() const { return error_details_; }
-
- // Returns the connection ID.
- QuicConnectionId connection_id() const { return connection_id_; }
-
- // Returns the SREJ message when state() returns REJECTED.
- const CryptoHandshakeMessage& reply() const { return *reply_; }
-
- private:
- // Helper class which is passed in to
- // QuicCryptoServerConfig::ValidateClientHello.
- class ValidateCallback;
- friend class ValidateCallback;
-
- class ProcessClientHelloCallback;
- friend class ProcessClientHelloCallback;
-
- void ProcessClientHello(
- QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
- result,
- std::unique_ptr<StatelessRejector> rejector,
- std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb);
-
- void ProcessClientHelloDone(
- QuicErrorCode error,
- const QuicString& error_details,
- std::unique_ptr<CryptoHandshakeMessage> message,
- std::unique_ptr<StatelessRejector> rejector,
- std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb);
-
- State state_;
- QuicErrorCode error_;
- QuicString error_details_;
- QuicTransportVersion version_;
- QuicTransportVersionVector versions_;
- QuicConnectionId connection_id_;
- QuicConnectionId server_designated_connection_id_;
- QuicByteCount chlo_packet_size_;
- QuicSocketAddress client_address_;
- QuicSocketAddress server_address_;
- const QuicClock* clock_;
- QuicRandom* random_;
- const QuicCryptoServerConfig* crypto_config_;
- QuicCompressedCertsCache* compressed_certs_cache_;
- CryptoHandshakeMessage chlo_;
- std::unique_ptr<CryptoHandshakeMessage> reply_;
- CryptoFramer crypto_framer_;
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
- QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-
- DISALLOW_COPY_AND_ASSIGN(StatelessRejector);
-};
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_STATELESS_REJECTOR_H_
diff --git a/chromium/net/tools/quic/stateless_rejector_test.cc b/chromium/net/tools/quic/stateless_rejector_test.cc
deleted file mode 100644
index 62e741b7a8b..00000000000
--- a/chromium/net/tools/quic/stateless_rejector_test.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright 2016 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/tools/quic/stateless_rejector.h"
-
-#include <memory>
-#include <vector>
-
-#include "net/quic/core/crypto/crypto_handshake_message.h"
-#include "net/quic/core/crypto/proof_source.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/core/tls_server_handshaker.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_str_cat.h"
-#include "net/quic/platform/api/quic_string.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_crypto_server_config_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-
-
-namespace net {
-namespace test {
-namespace {
-
-const QuicConnectionId kConnectionId = 42;
-const QuicConnectionId kServerDesignateConnectionId = 24;
-
-// All four combinations of the two flags involved.
-enum FlagsMode { ENABLED, STATELESS_DISABLED, CHEAP_DISABLED, BOTH_DISABLED };
-
-const char* FlagsModeToString(FlagsMode mode) {
- switch (mode) {
- case ENABLED:
- return "ENABLED";
- case STATELESS_DISABLED:
- return "STATELESS_DISABLED";
- case CHEAP_DISABLED:
- return "CHEAP_DISABLED";
- case BOTH_DISABLED:
- return "BOTH_DISABLED";
- default:
- QUIC_DLOG(FATAL) << "Unexpected FlagsMode";
- return nullptr;
- }
-}
-
-// Test various combinations of QUIC version and flag state.
-struct TestParams {
- QuicTransportVersion version;
- FlagsMode flags;
-};
-
-QuicString TestParamToString(const testing::TestParamInfo<TestParams>& params) {
- return QuicStrCat("v", params.param.version, "_",
- FlagsModeToString(params.param.flags));
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (FlagsMode flags :
- {ENABLED, STATELESS_DISABLED, CHEAP_DISABLED, BOTH_DISABLED}) {
- for (QuicTransportVersion version : AllSupportedTransportVersions()) {
- TestParams param;
- param.version = version;
- param.flags = flags;
- params.push_back(param);
- }
- }
- return params;
-}
-
-class StatelessRejectorTest : public QuicTestWithParam<TestParams> {
- public:
- StatelessRejectorTest()
- : proof_source_(crypto_test_utils::ProofSourceForTesting()),
- config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- TlsServerHandshaker::CreateSslCtx()),
- config_peer_(&config_),
- compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- rejector_(QuicMakeUnique<StatelessRejector>(
- GetParam().version,
- AllSupportedTransportVersions(),
- &config_,
- &compressed_certs_cache_,
- &clock_,
- QuicRandom::GetInstance(),
- kDefaultMaxPacketSize,
- QuicSocketAddress(QuicIpAddress::Loopback4(), 12345),
- QuicSocketAddress(QuicIpAddress::Loopback4(), 443))) {
- SetQuicReloadableFlag(
- enable_quic_stateless_reject_support,
- GetParam().flags == ENABLED || GetParam().flags == CHEAP_DISABLED);
- SetQuicReloadableFlag(
- quic_use_cheap_stateless_rejects,
- GetParam().flags == ENABLED || GetParam().flags == STATELESS_DISABLED);
-
- // Add a new primary config.
- std::unique_ptr<CryptoHandshakeMessage> msg(config_.AddDefaultConfig(
- QuicRandom::GetInstance(), &clock_, config_options_));
-
- // Save the server config.
- scid_hex_ =
- "#" + QuicTextUtils::HexEncode(config_peer_.GetPrimaryConfig()->id);
-
- // Encode the QUIC version.
- ver_hex_ = QuicVersionLabelToString(
- QuicVersionToQuicVersionLabel(GetParam().version));
-
- // Generate a public value.
- char public_value[32];
- memset(public_value, 42, sizeof(public_value));
- pubs_hex_ =
- "#" + QuicTextUtils::HexEncode(public_value, sizeof(public_value));
-
- // Generate a client nonce.
- QuicString nonce;
- CryptoUtils::GenerateNonce(
- clock_.WallNow(), QuicRandom::GetInstance(),
- QuicStringPiece(
- reinterpret_cast<char*>(config_peer_.GetPrimaryConfig()->orbit),
- kOrbitSize),
- &nonce);
- nonc_hex_ = "#" + QuicTextUtils::HexEncode(nonce);
-
- // Generate a source address token.
- SourceAddressTokens previous_tokens;
- QuicIpAddress ip = QuicIpAddress::Loopback4();
- MockRandom rand;
- QuicString stk = config_peer_.NewSourceAddressToken(
- config_peer_.GetPrimaryConfig()->id, previous_tokens, ip, &rand,
- clock_.WallNow(), nullptr);
- stk_hex_ = "#" + QuicTextUtils::HexEncode(stk);
- }
-
- protected:
- class ProcessDoneCallback : public StatelessRejector::ProcessDoneCallback {
- public:
- explicit ProcessDoneCallback(StatelessRejectorTest* test) : test_(test) {}
- void Run(std::unique_ptr<StatelessRejector> rejector) override {
- test_->rejector_ = std::move(rejector);
- }
-
- private:
- StatelessRejectorTest* test_;
- };
-
- std::unique_ptr<ProofSource> proof_source_;
- MockClock clock_;
- QuicCryptoServerConfig config_;
- QuicCryptoServerConfigPeer config_peer_;
- QuicCompressedCertsCache compressed_certs_cache_;
- QuicCryptoServerConfig::ConfigOptions config_options_;
- std::unique_ptr<StatelessRejector> rejector_;
-
- // Values used in CHLO messages
- QuicString scid_hex_;
- QuicString nonc_hex_;
- QuicString pubs_hex_;
- QuicString ver_hex_;
- QuicString stk_hex_;
-};
-
-INSTANTIATE_TEST_CASE_P(Flags,
- StatelessRejectorTest,
- ::testing::ValuesIn(GetTestParams()),
- TestParamToString);
-
-TEST_P(StatelessRejectorTest, InvalidChlo) {
- // clang-format off
- const CryptoHandshakeMessage client_hello = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"COPT", "SREJ"}});
- // clang-format on
- rejector_->OnChlo(GetParam().version, kConnectionId,
- kServerDesignateConnectionId, client_hello);
-
- if (GetParam().flags != ENABLED) {
- EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_->state());
- return;
- }
-
- // The StatelessRejector is undecided - proceed with async processing
- ASSERT_EQ(StatelessRejector::UNKNOWN, rejector_->state());
- StatelessRejector::Process(std::move(rejector_),
- QuicMakeUnique<ProcessDoneCallback>(this));
-
- EXPECT_EQ(StatelessRejector::FAILED, rejector_->state());
- EXPECT_EQ(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, rejector_->error());
-}
-
-TEST_P(StatelessRejectorTest, ValidChloWithoutSrejSupport) {
- // clang-format off
- const CryptoHandshakeMessage client_hello = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"PUBS", pubs_hex_},
- {"NONC", nonc_hex_},
- {"VER\0", ver_hex_}},
- kClientHelloMinimumSize);
- // clang-format on
-
- rejector_->OnChlo(GetParam().version, kConnectionId,
- kServerDesignateConnectionId, client_hello);
- EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_->state());
-}
-
-TEST_P(StatelessRejectorTest, RejectChlo) {
- // clang-format off
- const CryptoHandshakeMessage client_hello = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"COPT", "SREJ"},
- {"SCID", scid_hex_},
- {"PUBS", pubs_hex_},
- {"NONC", nonc_hex_},
- {"#004b5453", stk_hex_},
- {"VER\0", ver_hex_}},
- kClientHelloMinimumSize);
- // clang-format on
-
- rejector_->OnChlo(GetParam().version, kConnectionId,
- kServerDesignateConnectionId, client_hello);
- if (GetParam().flags != ENABLED) {
- EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_->state());
- return;
- }
-
- // The StatelessRejector is undecided - proceed with async processing
- ASSERT_EQ(StatelessRejector::UNKNOWN, rejector_->state());
- StatelessRejector::Process(std::move(rejector_),
- QuicMakeUnique<ProcessDoneCallback>(this));
-
- ASSERT_EQ(StatelessRejector::REJECTED, rejector_->state());
- const CryptoHandshakeMessage& reply = rejector_->reply();
- EXPECT_EQ(kSREJ, reply.tag());
- QuicTagVector reject_reasons;
- EXPECT_EQ(QUIC_NO_ERROR, reply.GetTaglist(kRREJ, &reject_reasons));
- EXPECT_EQ(1u, reject_reasons.size());
- EXPECT_EQ(INVALID_EXPECTED_LEAF_CERTIFICATE,
- static_cast<HandshakeFailureReason>(reject_reasons[0]));
-}
-
-TEST_P(StatelessRejectorTest, AcceptChlo) {
- const uint64_t xlct = crypto_test_utils::LeafCertHashForTesting();
- const QuicString xlct_hex =
- "#" + QuicTextUtils::HexEncode(reinterpret_cast<const char*>(&xlct),
- sizeof(xlct));
- // clang-format off
- const CryptoHandshakeMessage client_hello = crypto_test_utils::CreateCHLO(
- {{"PDMD", "X509"},
- {"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"COPT", "SREJ"},
- {"SCID", scid_hex_},
- {"PUBS", pubs_hex_},
- {"NONC", nonc_hex_},
- {"#004b5453", stk_hex_},
- {"VER\0", ver_hex_},
- {"XLCT", xlct_hex}},
- kClientHelloMinimumSize);
- // clang-format on
-
- rejector_->OnChlo(GetParam().version, kConnectionId,
- kServerDesignateConnectionId, client_hello);
- if (GetParam().flags != ENABLED) {
- EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_->state());
- return;
- }
-
- // The StatelessRejector is undecided - proceed with async processing
- ASSERT_EQ(StatelessRejector::UNKNOWN, rejector_->state());
- StatelessRejector::Process(std::move(rejector_),
- QuicMakeUnique<ProcessDoneCallback>(this));
-
- EXPECT_EQ(StatelessRejector::ACCEPTED, rejector_->state());
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/synchronous_host_resolver.cc b/chromium/net/tools/quic/synchronous_host_resolver.cc
index e9423a25ea9..bcb2b7617b3 100644
--- a/chromium/net/tools/quic/synchronous_host_resolver.cc
+++ b/chromium/net/tools/quic/synchronous_host_resolver.cc
@@ -91,7 +91,7 @@ int ResolverThread::Resolve(const std::string& host, AddressList* addresses) {
void ResolverThread::OnResolutionComplete(int rv) {
rv_ = rv;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
+ FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
}
} // namespace
diff --git a/chromium/net/tools/quic/test_tools/bad_packet_writer.cc b/chromium/net/tools/quic/test_tools/bad_packet_writer.cc
deleted file mode 100644
index 91d5fe50bca..00000000000
--- a/chromium/net/tools/quic/test_tools/bad_packet_writer.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 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/tools/quic/test_tools/bad_packet_writer.h"
-
-namespace net {
-namespace test {
-
-BadPacketWriter::BadPacketWriter(size_t packet_causing_write_error,
- int error_code)
- : packet_causing_write_error_(packet_causing_write_error),
- error_code_(error_code) {}
-
-BadPacketWriter::~BadPacketWriter() {}
-
-WriteResult BadPacketWriter::WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- if (error_code_ == 0 || packet_causing_write_error_ > 0) {
- if (packet_causing_write_error_ > 0) {
- --packet_causing_write_error_;
- }
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
- }
- // It's time to cause write error.
- int error_code = error_code_;
- error_code_ = 0;
- return WriteResult(WRITE_STATUS_ERROR, error_code);
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/bad_packet_writer.h b/chromium/net/tools/quic/test_tools/bad_packet_writer.h
deleted file mode 100644
index e8d6d4ead06..00000000000
--- a/chromium/net/tools/quic/test_tools/bad_packet_writer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 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_TOOLS_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
-
-#include "net/tools/quic/quic_packet_writer_wrapper.h"
-
-namespace net {
-
-namespace test {
-// This packet writer allows causing packet write error with specified error
-// code when writing a particular packet.
-class BadPacketWriter : public QuicPacketWriterWrapper {
- public:
- BadPacketWriter(size_t packet_causing_write_error, int error_code);
-
- ~BadPacketWriter() override;
-
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- private:
- size_t packet_causing_write_error_;
- int error_code_;
-};
-
-} // namespace test
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
diff --git a/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.cc b/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.cc
deleted file mode 100644
index f37ace74feb..00000000000
--- a/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2015 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/tools/quic/test_tools/limited_mtu_test_writer.h"
-
-namespace net {
-namespace test {
-
-LimitedMtuTestWriter::LimitedMtuTestWriter(QuicByteCount mtu) : mtu_(mtu) {}
-
-LimitedMtuTestWriter::~LimitedMtuTestWriter() = default;
-
-WriteResult LimitedMtuTestWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- if (buf_len > mtu_) {
- // Drop the packet.
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h b/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h
deleted file mode 100644
index 3d2e2fd8f40..00000000000
--- a/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2015 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_TOOLS_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
-
-#include "base/macros.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/tools/quic/quic_packet_writer_wrapper.h"
-
-namespace net {
-namespace test {
-
-// Simulates a connection over a link with fixed MTU. Drops packets which
-// exceed the MTU and passes the rest of them as-is.
-class LimitedMtuTestWriter : public QuicPacketWriterWrapper {
- public:
- explicit LimitedMtuTestWriter(QuicByteCount mtu);
- ~LimitedMtuTestWriter() override;
-
- // Inherited from QuicPacketWriterWrapper.
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- private:
- QuicByteCount mtu_;
-
- DISALLOW_COPY_AND_ASSIGN(LimitedMtuTestWriter);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
diff --git a/chromium/net/tools/quic/test_tools/mock_epoll_server.cc b/chromium/net/tools/quic/test_tools/mock_epoll_server.cc
deleted file mode 100644
index ffca8d98d9a..00000000000
--- a/chromium/net/tools/quic/test_tools/mock_epoll_server.cc
+++ /dev/null
@@ -1,60 +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/tools/quic/test_tools/mock_epoll_server.h"
-
-namespace net {
-namespace test {
-
-FakeTimeEpollServer::FakeTimeEpollServer() : now_in_usec_(0) {}
-
-FakeTimeEpollServer::~FakeTimeEpollServer() = default;
-
-int64_t FakeTimeEpollServer::NowInUsec() const {
- return now_in_usec_;
-}
-
-MockEpollServer::MockEpollServer() : until_in_usec_(-1) {}
-
-MockEpollServer::~MockEpollServer() = default;
-
-int MockEpollServer::epoll_wait_impl(int epfd,
- struct epoll_event* events,
- int max_events,
- int timeout_in_ms) {
- int num_events = 0;
- while (!event_queue_.empty() && num_events < max_events &&
- event_queue_.begin()->first <= NowInUsec() &&
- ((until_in_usec_ == -1) ||
- (event_queue_.begin()->first < until_in_usec_))) {
- int64_t event_time_in_usec = event_queue_.begin()->first;
- events[num_events] = event_queue_.begin()->second;
- if (event_time_in_usec > NowInUsec()) {
- set_now_in_usec(event_time_in_usec);
- }
- event_queue_.erase(event_queue_.begin());
- ++num_events;
- }
- if (num_events == 0) { // then we'd have waited 'till the timeout.
- if (until_in_usec_ < 0) { // then we don't care what the final time is.
- if (timeout_in_ms > 0) {
- AdvanceBy(timeout_in_ms * 1000);
- }
- } else { // except we assume that we don't wait for the timeout
- // period if until_in_usec_ is a positive number.
- set_now_in_usec(until_in_usec_);
- // And reset until_in_usec_ to signal no waiting (as
- // the AdvanceByExactly* stuff is meant to be one-shot,
- // as are all similar EpollServer functions)
- until_in_usec_ = -1;
- }
- }
- if (until_in_usec_ >= 0) {
- CHECK(until_in_usec_ >= NowInUsec());
- }
- return num_events;
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/mock_epoll_server.h b/chromium/net/tools/quic/test_tools/mock_epoll_server.h
deleted file mode 100644
index 9eac59403bc..00000000000
--- a/chromium/net/tools/quic/test_tools/mock_epoll_server.h
+++ /dev/null
@@ -1,115 +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_TOOLS_QUIC_TEST_TOOLS_MOCK_EPOLL_SERVER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_MOCK_EPOLL_SERVER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <unordered_map>
-#include <unordered_set>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace net {
-namespace test {
-
-// Unlike the full MockEpollServer, this only lies about the time but lets
-// fd events operate normally. Usefully when interacting with real backends
-// but wanting to skip forward in time to trigger timeouts.
-class FakeTimeEpollServer : public EpollServer {
- public:
- FakeTimeEpollServer();
- ~FakeTimeEpollServer() override;
-
- // Replaces the EpollServer NowInUsec.
- int64_t NowInUsec() const override;
-
- void set_now_in_usec(int64_t nius) { now_in_usec_ = nius; }
-
- // Advances the virtual 'now' by advancement_usec.
- void AdvanceBy(int64_t advancement_usec) {
- set_now_in_usec(NowInUsec() + advancement_usec);
- }
-
- // Advances the virtual 'now' by advancement_usec, and
- // calls WaitForEventAndExecteCallbacks.
- // Note that the WaitForEventsAndExecuteCallbacks invocation
- // may cause NowInUs to advance beyond what was specified here.
- // If that is not desired, use the AdvanceByExactly calls.
- void AdvanceByAndWaitForEventsAndExecuteCallbacks(int64_t advancement_usec) {
- AdvanceBy(advancement_usec);
- WaitForEventsAndExecuteCallbacks();
- }
-
- private:
- int64_t now_in_usec_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeTimeEpollServer);
-};
-
-class MockEpollServer : public FakeTimeEpollServer {
- public: // type definitions
- using EventQueue = std::unordered_multimap<int64_t, struct epoll_event>;
-
- MockEpollServer();
- ~MockEpollServer() override;
-
- // time_in_usec is the time at which the event specified
- // by 'ee' will be delivered. Note that it -is- possible
- // to add an event for a time which has already been passed..
- // .. upon the next time that the callbacks are invoked,
- // all events which are in the 'past' will be delivered.
- void AddEvent(int64_t time_in_usec, const struct epoll_event& ee) {
- event_queue_.insert(std::make_pair(time_in_usec, ee));
- }
-
- // Advances the virtual 'now' by advancement_usec,
- // and ensure that the next invocation of
- // WaitForEventsAndExecuteCallbacks goes no farther than
- // advancement_usec from the current time.
- void AdvanceByExactly(int64_t advancement_usec) {
- until_in_usec_ = NowInUsec() + advancement_usec;
- set_now_in_usec(NowInUsec() + advancement_usec);
- }
-
- // As above, except calls WaitForEventsAndExecuteCallbacks.
- void AdvanceByExactlyAndCallCallbacks(int64_t advancement_usec) {
- AdvanceByExactly(advancement_usec);
- WaitForEventsAndExecuteCallbacks();
- }
-
- std::unordered_set<AlarmCB*>::size_type NumberOfAlarms() const {
- return all_alarms_.size();
- }
-
- protected: // functions
- // These functions do nothing here, as we're not actually
- // using the epoll_* syscalls.
- void DelFD(int fd) const override {}
- void AddFD(int fd, int event_mask) const override {}
- void ModFD(int fd, int event_mask) const override {}
-
- // Replaces the epoll_server's epoll_wait_impl.
- int epoll_wait_impl(int epfd,
- struct epoll_event* events,
- int max_events,
- int timeout_in_ms) override;
- void SetNonblocking(int fd) override {}
-
- private: // members
- EventQueue event_queue_;
- int64_t until_in_usec_;
-
- DISALLOW_COPY_AND_ASSIGN(MockEpollServer);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_MOCK_EPOLL_SERVER_H_
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_session_visitor.cc b/chromium/net/tools/quic/test_tools/mock_quic_session_visitor.cc
deleted file mode 100644
index 8bca2752da5..00000000000
--- a/chromium/net/tools/quic/test_tools/mock_quic_session_visitor.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2016 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/tools/quic/test_tools/mock_quic_session_visitor.h"
-
-namespace net {
-namespace test {
-
-MockQuicSessionVisitor::MockQuicSessionVisitor() = default;
-
-MockQuicSessionVisitor::~MockQuicSessionVisitor() = default;
-
-MockQuicCryptoServerStreamHelper::MockQuicCryptoServerStreamHelper() = default;
-
-MockQuicCryptoServerStreamHelper::~MockQuicCryptoServerStreamHelper() = default;
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_session_visitor.h b/chromium/net/tools/quic/test_tools/mock_quic_session_visitor.h
deleted file mode 100644
index 793be8d42dd..00000000000
--- a/chromium/net/tools/quic/test_tools/mock_quic_session_visitor.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2016 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_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
-
-#include "base/macros.h"
-#include "net/quic/core/quic_crypto_server_stream.h"
-#include "net/tools/quic/quic_time_wait_list_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace net {
-namespace test {
-
-class MockQuicSessionVisitor : public QuicTimeWaitListManager::Visitor {
- public:
- MockQuicSessionVisitor();
- ~MockQuicSessionVisitor() override;
- MOCK_METHOD3(OnConnectionClosed,
- void(QuicConnectionId connection_id,
- QuicErrorCode error,
- const std::string& error_details));
- MOCK_METHOD1(OnWriteBlocked,
- void(QuicBlockedWriterInterface* blocked_writer));
- MOCK_METHOD1(OnRstStreamReceived, void(const QuicRstStreamFrame& frame));
- MOCK_METHOD1(OnConnectionAddedToTimeWaitList,
- void(QuicConnectionId connection_id));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockQuicSessionVisitor);
-};
-
-class MockQuicCryptoServerStreamHelper : public QuicCryptoServerStream::Helper {
- public:
- MockQuicCryptoServerStreamHelper();
- ~MockQuicCryptoServerStreamHelper() override;
- MOCK_CONST_METHOD1(GenerateConnectionIdForReject,
- QuicConnectionId(QuicConnectionId connection_id));
- MOCK_CONST_METHOD3(CanAcceptClientHello,
- bool(const CryptoHandshakeMessage& message,
- const QuicSocketAddress& self_address,
- std::string* error_details));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStreamHelper);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc b/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
deleted file mode 100644
index 451d7ac9450..00000000000
--- a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
+++ /dev/null
@@ -1,32 +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/tools/quic/test_tools/mock_quic_time_wait_list_manager.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace net {
-namespace test {
-
-MockTimeWaitListManager::MockTimeWaitListManager(
- QuicPacketWriter* writer,
- Visitor* visitor,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory)
- : QuicTimeWaitListManager(writer, visitor, helper, alarm_factory) {
- // Though AddConnectionIdToTimeWait is mocked, we want to retain its
- // functionality.
- EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _, _))
- .Times(testing::AnyNumber());
- ON_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _, _))
- .WillByDefault(
- Invoke(this, &MockTimeWaitListManager::
- QuicTimeWaitListManager_AddConnectionIdToTimeWait));
-}
-
-MockTimeWaitListManager::~MockTimeWaitListManager() = default;
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h b/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h
deleted file mode 100644
index e893b0f9736..00000000000
--- a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h
+++ /dev/null
@@ -1,57 +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_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
-
-#include "net/tools/quic/quic_time_wait_list_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace net {
-namespace test {
-
-class MockTimeWaitListManager : public QuicTimeWaitListManager {
- public:
- MockTimeWaitListManager(QuicPacketWriter* writer,
- Visitor* visitor,
- QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory);
- ~MockTimeWaitListManager() override;
-
- MOCK_METHOD5(AddConnectionIdToTimeWait,
- void(QuicConnectionId connection_id,
- ParsedQuicVersion version,
- bool ietf_quic,
- bool connection_rejected_statelessly,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>*
- termination_packets));
-
- void QuicTimeWaitListManager_AddConnectionIdToTimeWait(
- QuicConnectionId connection_id,
- ParsedQuicVersion version,
- bool ietf_quic,
- bool connection_rejected_statelessly,
- std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) {
- QuicTimeWaitListManager::AddConnectionIdToTimeWait(
- connection_id, version, ietf_quic, connection_rejected_statelessly,
- termination_packets);
- }
-
- MOCK_METHOD3(ProcessPacket,
- void(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- QuicConnectionId connection_id));
-
- MOCK_METHOD5(SendVersionNegotiationPacket,
- void(QuicConnectionId connection_id,
- bool ietf_quic,
- const ParsedQuicVersionVector& supported_versions,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address));
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc b/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc
deleted file mode 100644
index a5c2a1ded7b..00000000000
--- a/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2013 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/tools/quic/test_tools/packet_dropping_test_writer.h"
-
-#include <limits>
-
-#include "base/rand_util.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/tools/quic/platform/impl/quic_socket_utils.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-
-namespace net {
-namespace test {
-
-// An alarm that is scheduled if a blocked socket is simulated to indicate
-// it's writable again.
-class WriteUnblockedAlarm : public QuicAlarm::Delegate {
- public:
- explicit WriteUnblockedAlarm(PacketDroppingTestWriter* writer)
- : writer_(writer) {}
-
- void OnAlarm() override {
- QUIC_DLOG(INFO) << "Unblocking socket.";
- writer_->OnCanWrite();
- }
-
- private:
- PacketDroppingTestWriter* writer_;
-};
-
-// An alarm that is scheduled every time a new packet is to be written at a
-// later point.
-class DelayAlarm : public QuicAlarm::Delegate {
- public:
- explicit DelayAlarm(PacketDroppingTestWriter* writer) : writer_(writer) {}
-
- void OnAlarm() override {
- QuicTime new_deadline = writer_->ReleaseOldPackets();
- if (new_deadline.IsInitialized()) {
- writer_->SetDelayAlarm(new_deadline);
- }
- }
-
- private:
- PacketDroppingTestWriter* writer_;
-};
-
-PacketDroppingTestWriter::PacketDroppingTestWriter()
- : clock_(nullptr),
- cur_buffer_size_(0),
- num_calls_to_write_(0),
- config_mutex_(),
- fake_packet_loss_percentage_(0),
- fake_drop_first_n_packets_(0),
- fake_blocked_socket_percentage_(0),
- fake_packet_reorder_percentage_(0),
- fake_packet_delay_(QuicTime::Delta::Zero()),
- fake_bandwidth_(QuicBandwidth::Zero()),
- buffer_size_(0) {
- uint32_t seed = base::RandInt(0, std::numeric_limits<int32_t>::max());
- QUIC_LOG(INFO) << "Seeding packet loss with " << seed;
- simple_random_.set_seed(seed);
-}
-
-PacketDroppingTestWriter::~PacketDroppingTestWriter() = default;
-
-void PacketDroppingTestWriter::Initialize(QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- Delegate* on_can_write) {
- clock_ = helper->GetClock();
- write_unblocked_alarm_.reset(
- alarm_factory->CreateAlarm(new WriteUnblockedAlarm(this)));
- delay_alarm_.reset(alarm_factory->CreateAlarm(new DelayAlarm(this)));
- on_can_write_.reset(on_can_write);
-}
-
-WriteResult PacketDroppingTestWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- ++num_calls_to_write_;
- ReleaseOldPackets();
-
- QuicReaderMutexLock lock(&config_mutex_);
- if (fake_drop_first_n_packets_ > 0 &&
- num_calls_to_write_ <=
- static_cast<uint64_t>(fake_drop_first_n_packets_)) {
- QUIC_DVLOG(1) << "Dropping first " << fake_drop_first_n_packets_
- << " packets (packet number " << num_calls_to_write_ << ")";
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
- if (fake_packet_loss_percentage_ > 0 &&
- simple_random_.RandUint64() % 100 <
- static_cast<uint64_t>(fake_packet_loss_percentage_)) {
- QUIC_DVLOG(1) << "Dropping packet.";
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
- if (fake_blocked_socket_percentage_ > 0 &&
- simple_random_.RandUint64() % 100 <
- static_cast<uint64_t>(fake_blocked_socket_percentage_)) {
- CHECK(on_can_write_ != nullptr);
- QUIC_DVLOG(1) << "Blocking socket.";
- if (!write_unblocked_alarm_->IsSet()) {
- // Set the alarm to fire immediately.
- write_unblocked_alarm_->Set(clock_->ApproximateNow());
- }
- return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN);
- }
-
- if (!fake_packet_delay_.IsZero() || !fake_bandwidth_.IsZero()) {
- if (buffer_size_ > 0 && buf_len + cur_buffer_size_ > buffer_size_) {
- // Drop packets which do not fit into the buffer.
- QUIC_DVLOG(1) << "Dropping packet because the buffer is full.";
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- // Queue it to be sent.
- QuicTime send_time = clock_->ApproximateNow() + fake_packet_delay_;
- if (!fake_bandwidth_.IsZero()) {
- // Calculate a time the bandwidth limit would impose.
- QuicTime::Delta bandwidth_delay = QuicTime::Delta::FromMicroseconds(
- (buf_len * kNumMicrosPerSecond) / fake_bandwidth_.ToBytesPerSecond());
- send_time = delayed_packets_.empty()
- ? send_time + bandwidth_delay
- : delayed_packets_.back().send_time + bandwidth_delay;
- }
- std::unique_ptr<PerPacketOptions> delayed_options;
- if (options != nullptr) {
- delayed_options.reset(options->Clone());
- }
- delayed_packets_.push_back(
- DelayedWrite(buffer, buf_len, self_address, peer_address,
- std::move(delayed_options), send_time));
- cur_buffer_size_ += buf_len;
-
- // Set the alarm if it's not yet set.
- if (!delay_alarm_->IsSet()) {
- delay_alarm_->Set(send_time);
- }
-
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
-
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
-}
-
-bool PacketDroppingTestWriter::IsWriteBlocked() const {
- if (write_unblocked_alarm_ != nullptr && write_unblocked_alarm_->IsSet()) {
- return true;
- }
- return QuicPacketWriterWrapper::IsWriteBlocked();
-}
-
-void PacketDroppingTestWriter::SetWritable() {
- if (write_unblocked_alarm_ != nullptr && write_unblocked_alarm_->IsSet()) {
- write_unblocked_alarm_->Cancel();
- }
- QuicPacketWriterWrapper::SetWritable();
-}
-
-QuicTime PacketDroppingTestWriter::ReleaseNextPacket() {
- if (delayed_packets_.empty()) {
- return QuicTime::Zero();
- }
- QuicReaderMutexLock lock(&config_mutex_);
- DelayedPacketList::iterator iter = delayed_packets_.begin();
- // Determine if we should re-order.
- if (delayed_packets_.size() > 1 && fake_packet_reorder_percentage_ > 0 &&
- simple_random_.RandUint64() % 100 <
- static_cast<uint64_t>(fake_packet_reorder_percentage_)) {
- QUIC_DLOG(INFO) << "Reordering packets.";
- ++iter;
- // Swap the send times when re-ordering packets.
- delayed_packets_.begin()->send_time = iter->send_time;
- }
-
- QUIC_DVLOG(1) << "Releasing packet. " << (delayed_packets_.size() - 1)
- << " remaining.";
- // Grab the next one off the queue and send it.
- QuicPacketWriterWrapper::WritePacket(
- iter->buffer.data(), iter->buffer.length(), iter->self_address,
- iter->peer_address, iter->options.get());
- DCHECK_GE(cur_buffer_size_, iter->buffer.length());
- cur_buffer_size_ -= iter->buffer.length();
- delayed_packets_.erase(iter);
-
- // If there are others, find the time for the next to be sent.
- if (delayed_packets_.empty()) {
- return QuicTime::Zero();
- }
- return delayed_packets_.begin()->send_time;
-}
-
-QuicTime PacketDroppingTestWriter::ReleaseOldPackets() {
- while (!delayed_packets_.empty()) {
- QuicTime next_send_time = delayed_packets_.front().send_time;
- if (next_send_time > clock_->Now()) {
- return next_send_time;
- }
- ReleaseNextPacket();
- }
- return QuicTime::Zero();
-}
-
-void PacketDroppingTestWriter::SetDelayAlarm(QuicTime new_deadline) {
- delay_alarm_->Set(new_deadline);
-}
-
-void PacketDroppingTestWriter::OnCanWrite() {
- on_can_write_->OnCanWrite();
-}
-
-PacketDroppingTestWriter::DelayedWrite::DelayedWrite(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- std::unique_ptr<PerPacketOptions> options,
- QuicTime send_time)
- : buffer(buffer, buf_len),
- self_address(self_address),
- peer_address(peer_address),
- options(std::move(options)),
- send_time(send_time) {}
-
-// TODO(rtenneti): on windows RValue reference gives errors.
-PacketDroppingTestWriter::DelayedWrite::DelayedWrite(
- PacketDroppingTestWriter::DelayedWrite&& other) = default;
-
-// TODO(rtenneti): on windows RValue reference gives errors.
-// IPAddress has no move assignment operator.
-//
-// PacketDroppingTestWriter::DelayedWrite&
-// PacketDroppingTestWriter::DelayedWrite::operator=(
-// PacketDroppingTestWriter::DelayedWrite&& other) = default;
-
-PacketDroppingTestWriter::DelayedWrite::~DelayedWrite() = default;
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h b/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h
deleted file mode 100644
index c4c28b6f1ba..00000000000
--- a/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2013 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_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <list>
-#include <memory>
-#include <string>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "net/base/ip_address.h"
-#include "net/quic/core/quic_alarm.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/tools/quic/platform/impl/quic_epoll_clock.h"
-#include "net/tools/quic/quic_packet_writer_wrapper.h"
-#include "net/tools/quic/test_tools/quic_test_client.h"
-
-namespace net {
-namespace test {
-
-// Simulates a connection that drops packets a configured percentage of the time
-// and has a blocked socket a configured percentage of the time. Also provides
-// the options to delay packets and reorder packets if delay is enabled.
-class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
- public:
- class Delegate {
- public:
- virtual ~Delegate() {}
- virtual void OnCanWrite() = 0;
- };
-
- PacketDroppingTestWriter();
-
- ~PacketDroppingTestWriter() override;
-
- // Must be called before blocking, reordering or delaying (loss is OK). May be
- // called after connecting if the helper is not available before.
- // |on_can_write| will be triggered when fake-unblocking; ownership will be
- // assumed.
- void Initialize(QuicConnectionHelperInterface* helper,
- QuicAlarmFactory* alarm_factory,
- Delegate* on_can_write);
-
- // QuicPacketWriter methods:
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- bool IsWriteBlocked() const override;
-
- void SetWritable() override;
-
- // Writes out any packet which should have been sent by now
- // to the contained writer and returns the time
- // for the next delayed packet to be written.
- QuicTime ReleaseOldPackets();
-
- // Sets |delay_alarm_| to fire at |new_deadline|.
- void SetDelayAlarm(QuicTime new_deadline);
-
- void OnCanWrite();
-
- // The percent of time a packet is simulated as being lost.
- void set_fake_packet_loss_percentage(int32_t fake_packet_loss_percentage) {
- QuicWriterMutexLock lock(&config_mutex_);
- fake_packet_loss_percentage_ = fake_packet_loss_percentage;
- }
-
- // Simulate dropping the first n packets unconditionally.
- // Subsequent packets will be lost at fake_packet_loss_percentage_ if set.
- void set_fake_drop_first_n_packets(int32_t fake_drop_first_n_packets) {
- QuicWriterMutexLock lock(&config_mutex_);
- fake_drop_first_n_packets_ = fake_drop_first_n_packets;
- }
-
- // The percent of time WritePacket will block and set WriteResult's status
- // to WRITE_STATUS_BLOCKED.
- void set_fake_blocked_socket_percentage(
- int32_t fake_blocked_socket_percentage) {
- DCHECK(clock_);
- QuicWriterMutexLock lock(&config_mutex_);
- fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
- }
-
- // The percent of time a packet is simulated as being reordered.
- void set_fake_reorder_percentage(int32_t fake_packet_reorder_percentage) {
- DCHECK(clock_);
- QuicWriterMutexLock lock(&config_mutex_);
- DCHECK(!fake_packet_delay_.IsZero());
- fake_packet_reorder_percentage_ = fake_packet_reorder_percentage;
- }
-
- // The delay before writing this packet.
- void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
- DCHECK(clock_);
- QuicWriterMutexLock lock(&config_mutex_);
- fake_packet_delay_ = fake_packet_delay;
- }
-
- // The maximum bandwidth and buffer size of the connection. When these are
- // set, packets will be delayed until a connection with that bandwidth would
- // transmit it. Once the |buffer_size| is reached, all new packets are
- // dropped.
- void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth,
- QuicByteCount buffer_size) {
- DCHECK(clock_);
- QuicWriterMutexLock lock(&config_mutex_);
- fake_bandwidth_ = fake_bandwidth;
- buffer_size_ = buffer_size;
- }
-
- // Useful for reproducing very flaky issues.
- void set_seed(uint64_t seed) { simple_random_.set_seed(seed); }
-
- private:
- // Writes out the next packet to the contained writer and returns the time
- // for the next delayed packet to be written.
- QuicTime ReleaseNextPacket();
-
- // A single packet which will be sent at the supplied send_time.
- struct DelayedWrite {
- public:
- DelayedWrite(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- std::unique_ptr<PerPacketOptions> options,
- QuicTime send_time);
- // TODO(rtenneti): on windows RValue reference gives errors.
- DelayedWrite(DelayedWrite&& other);
- // TODO(rtenneti): on windows RValue reference gives errors.
- // DelayedWrite& operator=(DelayedWrite&& other);
- ~DelayedWrite();
-
- std::string buffer;
- const QuicIpAddress self_address;
- const QuicSocketAddress peer_address;
- std::unique_ptr<PerPacketOptions> options;
- QuicTime send_time;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DelayedWrite);
- };
-
- typedef std::list<DelayedWrite> DelayedPacketList;
-
- const QuicClock* clock_;
- std::unique_ptr<QuicAlarm> write_unblocked_alarm_;
- std::unique_ptr<QuicAlarm> delay_alarm_;
- std::unique_ptr<Delegate> on_can_write_;
- net::test::SimpleRandom simple_random_;
- // Stored packets delayed by fake packet delay or bandwidth restrictions.
- DelayedPacketList delayed_packets_;
- QuicByteCount cur_buffer_size_;
- uint64_t num_calls_to_write_;
-
- QuicMutex config_mutex_;
- int32_t fake_packet_loss_percentage_ GUARDED_BY(config_mutex_);
- int32_t fake_drop_first_n_packets_ GUARDED_BY(config_mutex_);
- int32_t fake_blocked_socket_percentage_ GUARDED_BY(config_mutex_);
- int32_t fake_packet_reorder_percentage_ GUARDED_BY(config_mutex_);
- QuicTime::Delta fake_packet_delay_ GUARDED_BY(config_mutex_);
- QuicBandwidth fake_bandwidth_ GUARDED_BY(config_mutex_);
- QuicByteCount buffer_size_ GUARDED_BY(config_mutex_);
-
- DISALLOW_COPY_AND_ASSIGN(PacketDroppingTestWriter);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
diff --git a/chromium/net/tools/quic/test_tools/packet_reordering_writer.cc b/chromium/net/tools/quic/test_tools/packet_reordering_writer.cc
deleted file mode 100644
index 992b9eb07f5..00000000000
--- a/chromium/net/tools/quic/test_tools/packet_reordering_writer.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 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/tools/quic/test_tools/packet_reordering_writer.h"
-
-namespace net {
-namespace test {
-
-PacketReorderingWriter::PacketReorderingWriter() = default;
-
-PacketReorderingWriter::~PacketReorderingWriter() = default;
-
-WriteResult PacketReorderingWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
- if (!delay_next_) {
- VLOG(2) << "Writing a non-delayed packet";
- WriteResult wr = QuicPacketWriterWrapper::WritePacket(
- buffer, buf_len, self_address, peer_address, options);
- --num_packets_to_wait_;
- if (num_packets_to_wait_ == 0) {
- VLOG(2) << "Writing a delayed packet";
- // It's time to write the delayed packet.
- QuicPacketWriterWrapper::WritePacket(
- delayed_data_.data(), delayed_data_.length(), delayed_self_address_,
- delayed_peer_address_, delayed_options_.get());
- }
- return wr;
- }
- // Still have packet to wait.
- DCHECK_LT(0u, num_packets_to_wait_) << "Only allow one packet to be delayed";
- delayed_data_ = std::string(buffer, buf_len);
- delayed_self_address_ = self_address;
- delayed_peer_address_ = peer_address;
- if (options != nullptr) {
- delayed_options_.reset(options->Clone());
- }
- delay_next_ = false;
- return WriteResult(WRITE_STATUS_OK, buf_len);
-}
-
-void PacketReorderingWriter::SetDelay(size_t num_packets_to_wait) {
- DCHECK_GT(num_packets_to_wait, 0u);
- num_packets_to_wait_ = num_packets_to_wait;
- delay_next_ = true;
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/packet_reordering_writer.h b/chromium/net/tools/quic/test_tools/packet_reordering_writer.h
deleted file mode 100644
index 2ac8c35be7d..00000000000
--- a/chromium/net/tools/quic/test_tools/packet_reordering_writer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 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_TOOLS_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
-
-#include "net/tools/quic/quic_packet_writer_wrapper.h"
-
-namespace net {
-
-namespace test {
-
-// This packet writer allows delaying writing the next packet after
-// SetDelay(num_packets_to_wait)
-// is called and buffer this packet and write it after it writes next
-// |num_packets_to_wait| packets. It doesn't support delaying a packet while
-// there is already a packet delayed.
-class PacketReorderingWriter : public QuicPacketWriterWrapper {
- public:
- PacketReorderingWriter();
-
- ~PacketReorderingWriter() override;
-
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- void SetDelay(size_t num_packets_to_wait);
-
- private:
- bool delay_next_ = false;
- size_t num_packets_to_wait_ = 0;
- std::string delayed_data_;
- QuicIpAddress delayed_self_address_;
- QuicSocketAddress delayed_peer_address_;
- std::unique_ptr<PerPacketOptions> delayed_options_;
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_client_peer.cc b/chromium/net/tools/quic/test_tools/quic_client_peer.cc
deleted file mode 100644
index 14627bf24ac..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_client_peer.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2013 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/tools/quic/test_tools/quic_client_peer.h"
-
-#include "net/tools/quic/quic_client.h"
-
-namespace net {
-namespace test {
-
-// static
-bool QuicClientPeer::CreateUDPSocketAndBind(QuicClient* client) {
- return client->network_helper()->CreateUDPSocketAndBind(
- client->server_address(), client->bind_to_address(),
- client->local_port());
-}
-
-// static
-void QuicClientPeer::CleanUpUDPSocket(QuicClient* client, int fd) {
- client->epoll_network_helper()->CleanUpUDPSocket(fd);
-}
-
-// static
-void QuicClientPeer::SetClientPort(QuicClient* client, int port) {
- client->epoll_network_helper()->SetClientPort(port);
-}
-
-// static
-void QuicClientPeer::SetWriter(QuicClient* client, QuicPacketWriter* writer) {
- client->set_writer(writer);
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_client_peer.h b/chromium/net/tools/quic/test_tools/quic_client_peer.h
deleted file mode 100644
index 47c918eeeab..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_client_peer.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2013 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_TOOLS_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
-
-#include "base/macros.h"
-
-namespace net {
-
-class QuicClient;
-class QuicPacketWriter;
-
-namespace test {
-
-class QuicClientPeer {
- public:
- static bool CreateUDPSocketAndBind(QuicClient* client);
- static void CleanUpUDPSocket(QuicClient* client, int fd);
- static void SetClientPort(QuicClient* client, int port);
- static void SetWriter(QuicClient* client, QuicPacketWriter* writer);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(QuicClientPeer);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc b/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc
deleted file mode 100644
index 7f693c6d525..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2013 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/tools/quic/test_tools/quic_dispatcher_peer.h"
-
-#include "net/tools/quic/quic_dispatcher.h"
-#include "net/tools/quic/quic_packet_writer_wrapper.h"
-
-namespace net {
-namespace test {
-
-// static
-void QuicDispatcherPeer::SetTimeWaitListManager(
- QuicDispatcher* dispatcher,
- QuicTimeWaitListManager* time_wait_list_manager) {
- dispatcher->time_wait_list_manager_.reset(time_wait_list_manager);
-}
-
-// static
-void QuicDispatcherPeer::UseWriter(QuicDispatcher* dispatcher,
- QuicPacketWriterWrapper* writer) {
- writer->set_writer(dispatcher->writer_.release());
- dispatcher->writer_.reset(writer);
-}
-
-// static
-QuicPacketWriter* QuicDispatcherPeer::GetWriter(QuicDispatcher* dispatcher) {
- return dispatcher->writer_.get();
-}
-
-// static
-QuicCompressedCertsCache* QuicDispatcherPeer::GetCache(
- QuicDispatcher* dispatcher) {
- return dispatcher->compressed_certs_cache();
-}
-
-// static
-QuicConnectionHelperInterface* QuicDispatcherPeer::GetHelper(
- QuicDispatcher* dispatcher) {
- return dispatcher->helper_.get();
-}
-
-// static
-QuicAlarmFactory* QuicDispatcherPeer::GetAlarmFactory(
- QuicDispatcher* dispatcher) {
- return dispatcher->alarm_factory_.get();
-}
-
-// static
-QuicDispatcher::WriteBlockedList* QuicDispatcherPeer::GetWriteBlockedList(
- QuicDispatcher* dispatcher) {
- return &dispatcher->write_blocked_list_;
-}
-
-// static
-QuicErrorCode QuicDispatcherPeer::GetAndClearLastError(
- QuicDispatcher* dispatcher) {
- QuicErrorCode ret = dispatcher->last_error_;
- dispatcher->last_error_ = QUIC_NO_ERROR;
- return ret;
-}
-
-// static
-QuicBufferedPacketStore* QuicDispatcherPeer::GetBufferedPackets(
- QuicDispatcher* dispatcher) {
- return &(dispatcher->buffered_packets_);
-}
-
-// static
-const QuicDispatcher::SessionMap& QuicDispatcherPeer::session_map(
- QuicDispatcher* dispatcher) {
- return dispatcher->session_map();
-}
-
-// static
-void QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
- QuicDispatcher* dispatcher,
- size_t num_session_allowed) {
- return dispatcher->set_new_sessions_allowed_per_event_loop(
- num_session_allowed);
-}
-
-// static
-void QuicDispatcherPeer::SendPublicReset(
- QuicDispatcher* dispatcher,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- QuicConnectionId connection_id) {
- dispatcher->time_wait_list_manager()->SendPublicReset(
- server_address, client_address, connection_id);
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h b/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h
deleted file mode 100644
index 9353a60aaa5..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2013 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_TOOLS_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
-
-#include "base/macros.h"
-#include "net/tools/quic/quic_dispatcher.h"
-
-namespace net {
-
-class QuicPacketWriterWrapper;
-
-namespace test {
-
-class QuicDispatcherPeer {
- public:
- static void SetTimeWaitListManager(
- QuicDispatcher* dispatcher,
- QuicTimeWaitListManager* time_wait_list_manager);
-
- // Injects |writer| into |dispatcher| as the shared writer.
- static void UseWriter(QuicDispatcher* dispatcher,
- QuicPacketWriterWrapper* writer);
-
- static QuicPacketWriter* GetWriter(QuicDispatcher* dispatcher);
-
- static QuicCompressedCertsCache* GetCache(QuicDispatcher* dispatcher);
-
- static QuicConnectionHelperInterface* GetHelper(QuicDispatcher* dispatcher);
-
- static QuicAlarmFactory* GetAlarmFactory(QuicDispatcher* dispatcher);
-
- static QuicDispatcher::WriteBlockedList* GetWriteBlockedList(
- QuicDispatcher* dispatcher);
-
- // Get the dispatcher's record of the last error reported to its framer
- // visitor's OnError() method. Then set that record to QUIC_NO_ERROR.
- static QuicErrorCode GetAndClearLastError(QuicDispatcher* dispatcher);
-
- static QuicBufferedPacketStore* GetBufferedPackets(
- QuicDispatcher* dispatcher);
-
- static const QuicDispatcher::SessionMap& session_map(
- QuicDispatcher* dispatcher);
-
- static void set_new_sessions_allowed_per_event_loop(
- QuicDispatcher* dispatcher,
- size_t num_session_allowed);
-
- static void SendPublicReset(QuicDispatcher* dispatcher,
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- QuicConnectionId connection_id);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(QuicDispatcherPeer);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_server_peer.cc b/chromium/net/tools/quic/test_tools/quic_server_peer.cc
deleted file mode 100644
index 892c6922785..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_server_peer.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 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/tools/quic/test_tools/quic_server_peer.h"
-
-#include "net/tools/quic/quic_dispatcher.h"
-#include "net/tools/quic/quic_packet_reader.h"
-#include "net/tools/quic/quic_server.h"
-
-namespace net {
-namespace test {
-
-// static
-bool QuicServerPeer::SetSmallSocket(QuicServer* server) {
- int size = 1024 * 10;
- return setsockopt(server->fd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) !=
- -1;
-}
-
-// static
-QuicDispatcher* QuicServerPeer::GetDispatcher(QuicServer* server) {
- return server->dispatcher_.get();
-}
-
-// static
-void QuicServerPeer::SetReader(QuicServer* server, QuicPacketReader* reader) {
- server->packet_reader_.reset(reader);
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_server_peer.h b/chromium/net/tools/quic/test_tools/quic_server_peer.h
deleted file mode 100644
index e3d5d1e4a3b..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_server_peer.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 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_TOOLS_QUIC_TEST_TOOLS_QUIC_SERVER_PEER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_SERVER_PEER_H_
-
-#include "base/macros.h"
-
-namespace net {
-
-class QuicDispatcher;
-class QuicServer;
-class QuicPacketReader;
-
-namespace test {
-
-class QuicServerPeer {
- public:
- static bool SetSmallSocket(QuicServer* server);
- static QuicDispatcher* GetDispatcher(QuicServer* server);
- static void SetReader(QuicServer* server, QuicPacketReader* reader);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(QuicServerPeer);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_SERVER_PEER_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_test_client.cc b/chromium/net/tools/quic/test_tools/quic_test_client.cc
deleted file mode 100644
index e44ccc39820..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_test_client.cc
+++ /dev/null
@@ -1,876 +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/tools/quic/test_tools/quic_test_client.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "net/quic/core/crypto/proof_verifier.h"
-#include "net/quic/core/quic_server_id.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/core/spdy_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/platform/api/quic_stack_trace.h"
-#include "net/quic/platform/api/quic_text_utils.h"
-#include "net/quic/platform/api/quic_url.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/quic/test_tools/quic_connection_peer.h"
-#include "net/quic/test_tools/quic_spdy_session_peer.h"
-#include "net/quic/test_tools/quic_stream_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-#include "net/tools/quic/quic_packet_writer_wrapper.h"
-#include "net/tools/quic/quic_spdy_client_stream.h"
-#include "net/tools/quic/test_tools/quic_client_peer.h"
-
-using std::string;
-
-namespace net {
-namespace test {
-namespace {
-
-// RecordingProofVerifier accepts any certificate chain and records the common
-// name of the leaf and then delegates the actual verfication to an actual
-// verifier. If no optional verifier is provided, then VerifyProof will return
-// success.
-class RecordingProofVerifier : public ProofVerifier {
- public:
- explicit RecordingProofVerifier(std::unique_ptr<ProofVerifier> verifier)
- : verifier_(std::move(verifier)) {}
-
- // ProofVerifier interface.
- QuicAsyncStatus VerifyProof(
- const string& hostname,
- const uint16_t port,
- const string& server_config,
- QuicTransportVersion transport_version,
- QuicStringPiece chlo_hash,
- const std::vector<string>& certs,
- const string& cert_sct,
- const string& signature,
- const ProofVerifyContext* context,
- string* error_details,
- std::unique_ptr<ProofVerifyDetails>* details,
- std::unique_ptr<ProofVerifierCallback> callback) override {
- common_name_.clear();
- if (certs.empty()) {
- return QUIC_FAILURE;
- }
-
- // Convert certs to X509Certificate.
- std::vector<QuicStringPiece> cert_pieces(certs.size());
- for (unsigned i = 0; i < certs.size(); i++) {
- cert_pieces[i] = QuicStringPiece(certs[i]);
- }
- // TODO(rtenneti): Fix after adding support for real certs. Currently,
- // cert_pieces are "leaf" and "intermediate" and CreateFromDERCertChain
- // fails to return cert from these cert_pieces.
- // bssl::UniquePtr<X509> cert(d2i_X509(nullptr, &data, certs[0].size()));
- // if (!cert.get()) {
- // return QUIC_FAILURE;
- // }
- //
- // common_name_ = cert->subject().GetDisplayName();
- cert_sct_ = cert_sct;
-
- if (!verifier_) {
- return QUIC_SUCCESS;
- }
-
- return verifier_->VerifyProof(hostname, port, server_config,
- transport_version, chlo_hash, certs, cert_sct,
- signature, context, error_details, details,
- std::move(callback));
- }
-
- QuicAsyncStatus VerifyCertChain(
- const std::string& hostname,
- const std::vector<std::string>& certs,
- const ProofVerifyContext* context,
- std::string* error_details,
- std::unique_ptr<ProofVerifyDetails>* details,
- std::unique_ptr<ProofVerifierCallback> callback) override {
- return QUIC_SUCCESS;
- }
-
- const string& common_name() const { return common_name_; }
-
- const string& cert_sct() const { return cert_sct_; }
-
- private:
- std::unique_ptr<ProofVerifier> verifier_;
- string common_name_;
- string cert_sct_;
-};
-} // namespace
-
-class MockableQuicClientEpollNetworkHelper
- : public QuicClientEpollNetworkHelper {
- public:
- using QuicClientEpollNetworkHelper::QuicClientEpollNetworkHelper;
- ~MockableQuicClientEpollNetworkHelper() override = default;
-
- void ProcessPacket(const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address,
- const QuicReceivedPacket& packet) override {
- QuicClientEpollNetworkHelper::ProcessPacket(self_address, peer_address,
- packet);
- if (track_last_incoming_packet_) {
- last_incoming_packet_ = packet.Clone();
- }
- }
-
- QuicPacketWriter* CreateQuicPacketWriter() override {
- QuicPacketWriter* writer =
- QuicClientEpollNetworkHelper::CreateQuicPacketWriter();
- if (!test_writer_) {
- return writer;
- }
- test_writer_->set_writer(writer);
- return test_writer_;
- }
-
- const QuicReceivedPacket* last_incoming_packet() {
- return last_incoming_packet_.get();
- }
-
- void set_track_last_incoming_packet(bool track) {
- track_last_incoming_packet_ = track;
- }
-
- void UseWriter(QuicPacketWriterWrapper* writer) {
- CHECK(test_writer_ == nullptr);
- test_writer_ = writer;
- }
-
- void set_peer_address(const QuicSocketAddress& address) {
- CHECK(test_writer_ != nullptr);
- test_writer_->set_peer_address(address);
- }
-
- private:
- QuicPacketWriterWrapper* test_writer_ = nullptr;
- // The last incoming packet, iff |track_last_incoming_packet_| is true.
- std::unique_ptr<QuicReceivedPacket> last_incoming_packet_;
- // If true, copy each packet from ProcessPacket into |last_incoming_packet_|
- bool track_last_incoming_packet_ = false;
-};
-
-MockableQuicClient::MockableQuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server)
- : MockableQuicClient(server_address,
- server_id,
- QuicConfig(),
- supported_versions,
- epoll_server) {}
-
-MockableQuicClient::MockableQuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server)
- : MockableQuicClient(server_address,
- server_id,
- config,
- supported_versions,
- epoll_server,
- nullptr) {}
-
-MockableQuicClient::MockableQuicClient(
- QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : QuicClient(
- server_address,
- server_id,
- supported_versions,
- config,
- epoll_server,
- QuicMakeUnique<MockableQuicClientEpollNetworkHelper>(epoll_server,
- this),
- QuicWrapUnique(
- new RecordingProofVerifier(std::move(proof_verifier)))),
- override_connection_id_(0) {}
-
-MockableQuicClient::~MockableQuicClient() {
- if (connected()) {
- Disconnect();
- }
-}
-
-MockableQuicClientEpollNetworkHelper*
-MockableQuicClient::mockable_network_helper() {
- return static_cast<MockableQuicClientEpollNetworkHelper*>(
- epoll_network_helper());
-}
-
-const MockableQuicClientEpollNetworkHelper*
-MockableQuicClient::mockable_network_helper() const {
- return static_cast<const MockableQuicClientEpollNetworkHelper*>(
- epoll_network_helper());
-}
-
-QuicConnectionId MockableQuicClient::GenerateNewConnectionId() {
- return override_connection_id_ ? override_connection_id_
- : QuicClient::GenerateNewConnectionId();
-}
-
-void MockableQuicClient::UseConnectionId(QuicConnectionId connection_id) {
- override_connection_id_ = connection_id;
-}
-
-void MockableQuicClient::UseWriter(QuicPacketWriterWrapper* writer) {
- mockable_network_helper()->UseWriter(writer);
-}
-
-void MockableQuicClient::set_peer_address(const QuicSocketAddress& address) {
- mockable_network_helper()->set_peer_address(address);
-}
-
-const QuicReceivedPacket* MockableQuicClient::last_incoming_packet() {
- return mockable_network_helper()->last_incoming_packet();
-}
-
-void MockableQuicClient::set_track_last_incoming_packet(bool track) {
- mockable_network_helper()->set_track_last_incoming_packet(track);
-}
-
-QuicTestClient::QuicTestClient(
- QuicSocketAddress server_address,
- const string& server_hostname,
- const ParsedQuicVersionVector& supported_versions)
- : QuicTestClient(server_address,
- server_hostname,
- QuicConfig(),
- supported_versions) {}
-
-QuicTestClient::QuicTestClient(
- QuicSocketAddress server_address,
- const string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions)
- : client_(new MockableQuicClient(server_address,
- QuicServerId(server_hostname,
- server_address.port(),
- PRIVACY_MODE_DISABLED),
- config,
- supported_versions,
- &epoll_server_)) {
- Initialize();
-}
-
-QuicTestClient::QuicTestClient(
- QuicSocketAddress server_address,
- const string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- std::unique_ptr<ProofVerifier> proof_verifier)
- : client_(new MockableQuicClient(server_address,
- QuicServerId(server_hostname,
- server_address.port(),
- PRIVACY_MODE_DISABLED),
- config,
- supported_versions,
- &epoll_server_,
- std::move(proof_verifier))) {
- Initialize();
-}
-
-QuicTestClient::QuicTestClient() = default;
-
-QuicTestClient::~QuicTestClient() {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- stream.second->set_visitor(nullptr);
- }
-}
-
-void QuicTestClient::Initialize() {
- priority_ = 3;
- connect_attempted_ = false;
- auto_reconnect_ = false;
- buffer_body_ = true;
- num_requests_ = 0;
- num_responses_ = 0;
- ClearPerConnectionState();
- // As chrome will generally do this, we want it to be the default when it's
- // not overridden.
- if (!client_->config()->HasSetBytesForConnectionIdToSend()) {
- client_->config()->SetBytesForConnectionIdToSend(0);
- }
-}
-
-void QuicTestClient::SetUserAgentID(const string& user_agent_id) {
- client_->SetUserAgentID(user_agent_id);
-}
-
-ssize_t QuicTestClient::SendRequest(const string& uri) {
- SpdyHeaderBlock headers;
- if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
- return 0;
- }
- return SendMessage(headers, "");
-}
-
-void QuicTestClient::SendRequestsAndWaitForResponses(
- const std::vector<string>& url_list) {
- for (const string& url : url_list) {
- SendRequest(url);
- }
- while (client()->WaitForEvents()) {
- }
-}
-
-ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
- const SpdyHeaderBlock* headers,
- QuicStringPiece body,
- bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- if (headers) {
- QuicClientPushPromiseIndex::TryHandle* handle;
- QuicAsyncStatus rv =
- client()->push_promise_index()->Try(*headers, this, &handle);
- if (rv == QUIC_SUCCESS)
- return 1;
- if (rv == QUIC_PENDING) {
- // May need to retry request if asynchronous rendezvous fails.
- std::unique_ptr<SpdyHeaderBlock> new_headers(
- new SpdyHeaderBlock(headers->Clone()));
- push_promise_data_to_resend_ = QuicMakeUnique<TestClientDataToResend>(
- std::move(new_headers), body, fin, this, std::move(ack_listener));
- return 1;
- }
- }
-
- // Maybe it's better just to overload this. it's just that we need
- // for the GetOrCreateStream function to call something else...which
- // is icky and complicated, but maybe not worse than this.
- QuicSpdyClientStream* stream = GetOrCreateStream();
- if (stream == nullptr) {
- return 0;
- }
- QuicStreamPeer::set_ack_listener(stream, ack_listener);
-
- ssize_t ret = 0;
- if (headers != nullptr) {
- SpdyHeaderBlock spdy_headers(headers->Clone());
- if (spdy_headers[":authority"].as_string().empty()) {
- spdy_headers[":authority"] = client_->server_id().host();
- }
- ret = stream->SendRequest(std::move(spdy_headers), body, fin);
- ++num_requests_;
- } else {
- stream->WriteOrBufferBody(string(body), fin, ack_listener);
- ret = body.length();
- }
- if (GetQuicReloadableFlag(enable_quic_stateless_reject_support)) {
- std::unique_ptr<SpdyHeaderBlock> new_headers;
- if (headers) {
- new_headers = QuicMakeUnique<SpdyHeaderBlock>(headers->Clone());
- }
- std::unique_ptr<QuicSpdyClientBase::QuicDataToResend> data_to_resend(
- new TestClientDataToResend(std::move(new_headers), body, fin, this,
- ack_listener));
- client()->MaybeAddQuicDataToResend(std::move(data_to_resend));
- }
- return ret;
-}
-
-ssize_t QuicTestClient::SendMessage(const SpdyHeaderBlock& headers,
- QuicStringPiece body) {
- return SendMessage(headers, body, /*fin=*/true);
-}
-
-ssize_t QuicTestClient::SendMessage(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin) {
- // Always force creation of a stream for SendMessage.
- latest_created_stream_ = nullptr;
-
- ssize_t ret = GetOrCreateStreamAndSendRequest(&headers, body, fin, nullptr);
- WaitForWriteToFlush();
- return ret;
-}
-
-ssize_t QuicTestClient::SendData(const string& data, bool last_data) {
- return SendData(data, last_data, nullptr);
-}
-
-ssize_t QuicTestClient::SendData(
- const string& data,
- bool last_data,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
- return GetOrCreateStreamAndSendRequest(nullptr, QuicStringPiece(data),
- last_data, std::move(ack_listener));
-}
-
-bool QuicTestClient::response_complete() const {
- return response_complete_;
-}
-
-int64_t QuicTestClient::response_body_size() const {
- return response_body_size_;
-}
-
-bool QuicTestClient::buffer_body() const {
- return buffer_body_;
-}
-
-void QuicTestClient::set_buffer_body(bool buffer_body) {
- buffer_body_ = buffer_body;
-}
-
-const string& QuicTestClient::response_body() const {
- return response_;
-}
-
-string QuicTestClient::SendCustomSynchronousRequest(
- const SpdyHeaderBlock& headers,
- const string& body) {
- // Clear connection state here and only track this synchronous request.
- ClearPerConnectionState();
- if (SendMessage(headers, body) == 0) {
- QUIC_DLOG(ERROR) << "Failed the request for: " << headers.DebugString();
- // Set the response_ explicitly. Otherwise response_ will contain the
- // response from the previously successful request.
- response_ = "";
- } else {
- WaitForResponse();
- }
- return response_;
-}
-
-string QuicTestClient::SendSynchronousRequest(const string& uri) {
- SpdyHeaderBlock headers;
- if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
- return "";
- }
- return SendCustomSynchronousRequest(headers, "");
-}
-
-void QuicTestClient::SendConnectivityProbing() {
- QuicConnection* connection = client()->client_session()->connection();
- connection->SendConnectivityProbingPacket(connection->writer(),
- connection->peer_address());
-}
-
-void QuicTestClient::SetLatestCreatedStream(QuicSpdyClientStream* stream) {
- latest_created_stream_ = stream;
- if (latest_created_stream_ != nullptr) {
- open_streams_[stream->id()] = stream;
- stream->set_visitor(this);
- }
-}
-
-QuicSpdyClientStream* QuicTestClient::GetOrCreateStream() {
- if (!connect_attempted_ || auto_reconnect_) {
- if (!connected()) {
- Connect();
- }
- if (!connected()) {
- return nullptr;
- }
- }
- if (open_streams_.empty()) {
- ClearPerConnectionState();
- }
- if (!latest_created_stream_) {
- SetLatestCreatedStream(client_->CreateClientStream());
- if (latest_created_stream_) {
- latest_created_stream_->SetPriority(priority_);
- }
- }
-
- return latest_created_stream_;
-}
-
-QuicErrorCode QuicTestClient::connection_error() {
- return client()->connection_error();
-}
-
-MockableQuicClient* QuicTestClient::client() {
- return client_.get();
-}
-
-const string& QuicTestClient::cert_common_name() const {
- return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
- ->common_name();
-}
-
-const string& QuicTestClient::cert_sct() const {
- return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
- ->cert_sct();
-}
-
-QuicTagValueMap QuicTestClient::GetServerConfig() const {
- QuicCryptoClientConfig* config = client_->crypto_config();
- QuicCryptoClientConfig::CachedState* state =
- config->LookupOrCreate(client_->server_id());
- const CryptoHandshakeMessage* handshake_msg = state->GetServerConfig();
- if (handshake_msg != nullptr) {
- return handshake_msg->tag_value_map();
- } else {
- return QuicTagValueMap();
- }
-}
-
-bool QuicTestClient::connected() const {
- return client_->connected();
-}
-
-void QuicTestClient::Connect() {
- DCHECK(!connected());
- if (!connect_attempted_) {
- client_->Initialize();
- }
-
- // If we've been asked to override SNI, set it now
- if (override_sni_set_) {
- client_->set_server_id(
- QuicServerId(override_sni_, address().port(), PRIVACY_MODE_DISABLED));
- }
-
- client_->Connect();
- connect_attempted_ = true;
-}
-
-void QuicTestClient::ResetConnection() {
- Disconnect();
- Connect();
-}
-
-void QuicTestClient::Disconnect() {
- ClearPerConnectionState();
- client_->Disconnect();
- connect_attempted_ = false;
-}
-
-QuicSocketAddress QuicTestClient::local_address() const {
- return client_->network_helper()->GetLatestClientAddress();
-}
-
-void QuicTestClient::ClearPerRequestState() {
- stream_error_ = QUIC_STREAM_NO_ERROR;
- response_ = "";
- response_complete_ = false;
- response_headers_complete_ = false;
- preliminary_headers_.clear();
- response_headers_.clear();
- response_trailers_.clear();
- bytes_read_ = 0;
- bytes_written_ = 0;
- response_body_size_ = 0;
-}
-
-bool QuicTestClient::HaveActiveStream() {
- return push_promise_data_to_resend_.get() || !open_streams_.empty();
-}
-
-bool QuicTestClient::WaitUntil(int timeout_ms, std::function<bool()> trigger) {
- int64_t timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
- int64_t old_timeout_us = epoll_server()->timeout_in_us();
- if (timeout_us > 0) {
- epoll_server()->set_timeout_in_us(timeout_us);
- }
- const QuicClock* clock =
- QuicConnectionPeer::GetHelper(client()->session()->connection())
- ->GetClock();
- QuicTime end_waiting_time =
- clock->Now() + QuicTime::Delta::FromMicroseconds(timeout_us);
- while (HaveActiveStream() && !(trigger && trigger()) &&
- (timeout_us < 0 || clock->Now() < end_waiting_time)) {
- client_->WaitForEvents();
- }
- ReadNextResponse();
- if (timeout_us > 0) {
- epoll_server()->set_timeout_in_us(old_timeout_us);
- }
- if (trigger && !trigger()) {
- VLOG(1) << "Client WaitUntil returning with trigger returning false."
- << QuicStackTrace();
- return false;
- }
- return true;
-}
-
-ssize_t QuicTestClient::Send(const void* buffer, size_t size) {
- return SendData(string(static_cast<const char*>(buffer), size), false);
-}
-
-bool QuicTestClient::response_headers_complete() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- if (stream.second->headers_decompressed()) {
- return true;
- }
- }
- return response_headers_complete_;
-}
-
-const SpdyHeaderBlock* QuicTestClient::response_headers() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- size_t bytes_read =
- stream.second->stream_bytes_read() + stream.second->header_bytes_read();
- if (bytes_read > 0) {
- response_headers_ = stream.second->response_headers().Clone();
- break;
- }
- }
- return &response_headers_;
-}
-
-const SpdyHeaderBlock* QuicTestClient::preliminary_headers() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- size_t bytes_read =
- stream.second->stream_bytes_read() + stream.second->header_bytes_read();
- if (bytes_read > 0) {
- preliminary_headers_ = stream.second->preliminary_headers().Clone();
- break;
- }
- }
- return &preliminary_headers_;
-}
-
-const SpdyHeaderBlock& QuicTestClient::response_trailers() const {
- return response_trailers_;
-}
-
-int64_t QuicTestClient::response_size() const {
- return bytes_read();
-}
-
-size_t QuicTestClient::bytes_read() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- size_t bytes_read =
- stream.second->stream_bytes_read() + stream.second->header_bytes_read();
- if (bytes_read > 0) {
- return bytes_read;
- }
- }
- return bytes_read_;
-}
-
-size_t QuicTestClient::bytes_written() const {
- for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
- size_t bytes_written = stream.second->stream_bytes_written() +
- stream.second->header_bytes_written();
- if (bytes_written > 0) {
- return bytes_written;
- }
- }
- return bytes_written_;
-}
-
-void QuicTestClient::OnClose(QuicSpdyStream* stream) {
- if (stream == nullptr) {
- return;
- }
- // Always close the stream, regardless of whether it was the last stream
- // written.
- client()->OnClose(stream);
- ++num_responses_;
- if (!QuicContainsKey(open_streams_, stream->id())) {
- return;
- }
- if (latest_created_stream_ == stream) {
- latest_created_stream_ = nullptr;
- }
- QuicSpdyClientStream* client_stream =
- static_cast<QuicSpdyClientStream*>(stream);
- QuicStreamId id = client_stream->id();
- closed_stream_states_.insert(std::make_pair(
- id,
- PerStreamState(
- client_stream->stream_error(), true,
- client_stream->headers_decompressed(),
- client_stream->response_headers(),
- client_stream->preliminary_headers(),
- (buffer_body() ? client_stream->data() : ""),
- client_stream->received_trailers(),
- // Use NumBytesConsumed to avoid counting retransmitted stream frames.
- QuicStreamPeer::sequencer(client_stream)->NumBytesConsumed() +
- client_stream->header_bytes_read(),
- client_stream->stream_bytes_written() +
- client_stream->header_bytes_written(),
- client_stream->data().size())));
- open_streams_.erase(id);
-}
-
-bool QuicTestClient::CheckVary(const SpdyHeaderBlock& client_request,
- const SpdyHeaderBlock& promise_request,
- const SpdyHeaderBlock& promise_response) {
- return true;
-}
-
-void QuicTestClient::OnRendezvousResult(QuicSpdyStream* stream) {
- std::unique_ptr<TestClientDataToResend> data_to_resend =
- std::move(push_promise_data_to_resend_);
- SetLatestCreatedStream(static_cast<QuicSpdyClientStream*>(stream));
- if (stream) {
- stream->OnDataAvailable();
- } else if (data_to_resend) {
- data_to_resend->Resend();
- }
-}
-
-void QuicTestClient::UseWriter(QuicPacketWriterWrapper* writer) {
- client_->UseWriter(writer);
-}
-
-void QuicTestClient::UseConnectionId(QuicConnectionId connection_id) {
- DCHECK(!connected());
- client_->UseConnectionId(connection_id);
-}
-
-bool QuicTestClient::MigrateSocket(const QuicIpAddress& new_host) {
- return client_->MigrateSocket(new_host);
-}
-
-bool QuicTestClient::MigrateSocketWithSpecifiedPort(
- const QuicIpAddress& new_host,
- int port) {
- client_->set_local_port(port);
- return client_->MigrateSocket(new_host);
-}
-
-QuicIpAddress QuicTestClient::bind_to_address() const {
- return client_->bind_to_address();
-}
-
-void QuicTestClient::set_bind_to_address(QuicIpAddress address) {
- client_->set_bind_to_address(address);
-}
-
-const QuicSocketAddress& QuicTestClient::address() const {
- return client_->server_address();
-}
-
-void QuicTestClient::WaitForWriteToFlush() {
- while (connected() && client()->session()->HasDataToWrite()) {
- client_->WaitForEvents();
- }
-}
-
-QuicTestClient::TestClientDataToResend::TestClientDataToResend(
- std::unique_ptr<SpdyHeaderBlock> headers,
- QuicStringPiece body,
- bool fin,
- QuicTestClient* test_client,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener)
- : QuicClient::QuicDataToResend(std::move(headers), body, fin),
- test_client_(test_client),
- ack_listener_(std::move(ack_listener)) {}
-
-QuicTestClient::TestClientDataToResend::~TestClientDataToResend() = default;
-
-void QuicTestClient::TestClientDataToResend::Resend() {
- test_client_->GetOrCreateStreamAndSendRequest(headers_.get(), body_, fin_,
- ack_listener_);
- headers_.reset();
-}
-
-QuicTestClient::PerStreamState::PerStreamState(const PerStreamState& other)
- : stream_error(other.stream_error),
- response_complete(other.response_complete),
- response_headers_complete(other.response_headers_complete),
- response_headers(other.response_headers.Clone()),
- preliminary_headers(other.preliminary_headers.Clone()),
- response(other.response),
- response_trailers(other.response_trailers.Clone()),
- bytes_read(other.bytes_read),
- bytes_written(other.bytes_written),
- response_body_size(other.response_body_size) {}
-
-QuicTestClient::PerStreamState::PerStreamState(
- QuicRstStreamErrorCode stream_error,
- bool response_complete,
- bool response_headers_complete,
- const SpdyHeaderBlock& response_headers,
- const SpdyHeaderBlock& preliminary_headers,
- const string& response,
- const SpdyHeaderBlock& response_trailers,
- uint64_t bytes_read,
- uint64_t bytes_written,
- int64_t response_body_size)
- : stream_error(stream_error),
- response_complete(response_complete),
- response_headers_complete(response_headers_complete),
- response_headers(response_headers.Clone()),
- preliminary_headers(preliminary_headers.Clone()),
- response(response),
- response_trailers(response_trailers.Clone()),
- bytes_read(bytes_read),
- bytes_written(bytes_written),
- response_body_size(response_body_size) {}
-
-QuicTestClient::PerStreamState::~PerStreamState() = default;
-
-bool QuicTestClient::PopulateHeaderBlockFromUrl(const string& uri,
- SpdyHeaderBlock* headers) {
- string url;
- if (QuicTextUtils::StartsWith(uri, "https://") ||
- QuicTextUtils::StartsWith(uri, "http://")) {
- url = uri;
- } else if (uri[0] == '/') {
- url = "https://" + client_->server_id().host() + uri;
- } else {
- url = "https://" + uri;
- }
- return SpdyUtils::PopulateHeaderBlockFromUrl(url, headers);
-}
-
-void QuicTestClient::ReadNextResponse() {
- if (closed_stream_states_.empty()) {
- return;
- }
-
- PerStreamState state(closed_stream_states_.front().second);
-
- stream_error_ = state.stream_error;
- response_ = state.response;
- response_complete_ = state.response_complete;
- response_headers_complete_ = state.response_headers_complete;
- preliminary_headers_ = state.preliminary_headers.Clone();
- response_headers_ = state.response_headers.Clone();
- response_trailers_ = state.response_trailers.Clone();
- bytes_read_ = state.bytes_read;
- bytes_written_ = state.bytes_written;
- response_body_size_ = state.response_body_size;
-
- closed_stream_states_.pop_front();
-}
-
-void QuicTestClient::ClearPerConnectionState() {
- ClearPerRequestState();
- open_streams_.clear();
- closed_stream_states_.clear();
- latest_created_stream_ = nullptr;
-}
-
-void QuicTestClient::WaitForDelayedAcks() {
- // kWaitDuration is a period of time that is long enough for all delayed
- // acks to be sent and received on the other end.
- const QuicTime::Delta kWaitDuration =
- 4 * QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
- const QuicClock* clock = client()->client_session()->connection()->clock();
-
- QuicTime wait_until = clock->ApproximateNow() + kWaitDuration;
- while (clock->ApproximateNow() < wait_until) {
- // This waits for up to 50 ms.
- client()->WaitForEvents();
- }
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_test_client.h b/chromium/net/tools/quic/test_tools/quic_test_client.h
deleted file mode 100644
index 99a78f13421..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_test_client.h
+++ /dev/null
@@ -1,396 +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_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "net/quic/core/proto/cached_network_parameters.pb.h"
-#include "net/quic/core/quic_framer.h"
-#include "net/quic/core/quic_packet_creator.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/quic/platform/api/quic_map_util.h"
-#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/tools/quic/quic_client.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace net {
-
-class ProofVerifier;
-class QuicPacketWriterWrapper;
-
-namespace test {
-
-class MockableQuicClientEpollNetworkHelper;
-
-// A quic client which allows mocking out reads and writes.
-class MockableQuicClient : public QuicClient {
- public:
- MockableQuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server);
-
- MockableQuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server);
-
- MockableQuicClient(QuicSocketAddress server_address,
- const QuicServerId& server_id,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- EpollServer* epoll_server,
- std::unique_ptr<ProofVerifier> proof_verifier);
-
- ~MockableQuicClient() override;
-
- QuicConnectionId GenerateNewConnectionId() override;
- void UseConnectionId(QuicConnectionId connection_id);
-
- void UseWriter(QuicPacketWriterWrapper* writer);
- void set_peer_address(const QuicSocketAddress& address);
- // The last incoming packet, iff |track_last_incoming_packet| is true.
- const QuicReceivedPacket* last_incoming_packet();
- // If true, copy each packet from ProcessPacket into |last_incoming_packet|
- void set_track_last_incoming_packet(bool track);
-
- // Casts the network helper to a MockableQuicClientEpollNetworkHelper.
- MockableQuicClientEpollNetworkHelper* mockable_network_helper();
- const MockableQuicClientEpollNetworkHelper* mockable_network_helper() const;
-
- private:
- QuicConnectionId override_connection_id_; // ConnectionId to use, if nonzero
- CachedNetworkParameters cached_network_paramaters_;
-
- DISALLOW_COPY_AND_ASSIGN(MockableQuicClient);
-};
-
-// A toy QUIC client used for testing.
-class QuicTestClient : public QuicSpdyStream::Visitor,
- public QuicClientPushPromiseIndex::Delegate {
- public:
- QuicTestClient(QuicSocketAddress server_address,
- const std::string& server_hostname,
- const ParsedQuicVersionVector& supported_versions);
- QuicTestClient(QuicSocketAddress server_address,
- const std::string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions);
- QuicTestClient(QuicSocketAddress server_address,
- const std::string& server_hostname,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- std::unique_ptr<ProofVerifier> proof_verifier);
-
- ~QuicTestClient() override;
-
- // Sets the |user_agent_id| of the |client_|.
- void SetUserAgentID(const std::string& user_agent_id);
-
- // Wraps data in a quic packet and sends it.
- ssize_t SendData(const std::string& data, bool last_data);
- // As above, but |delegate| will be notified when |data| is ACKed.
- ssize_t SendData(
- const std::string& data,
- bool last_data,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- // Clears any outstanding state and sends a simple GET of 'uri' to the
- // server. Returns 0 if the request failed and no bytes were written.
- ssize_t SendRequest(const std::string& uri);
- // Sends requests for all the urls and waits for the responses. To process
- // the individual responses as they are returned, the caller should use the
- // set the response_listener on the client().
- void SendRequestsAndWaitForResponses(
- const std::vector<std::string>& url_list);
- // Sends a request containing |headers| and |body| and returns the number of
- // bytes sent (the size of the serialized request headers and body).
- ssize_t SendMessage(const SpdyHeaderBlock& headers, QuicStringPiece body);
- // Sends a request containing |headers| and |body| with the fin bit set to
- // |fin| and returns the number of bytes sent (the size of the serialized
- // request headers and body).
- ssize_t SendMessage(const SpdyHeaderBlock& headers,
- QuicStringPiece body,
- bool fin);
- // Sends a request containing |headers| and |body|, waits for the response,
- // and returns the response body.
- std::string SendCustomSynchronousRequest(const SpdyHeaderBlock& headers,
- const std::string& body);
- // Sends a GET request for |uri|, waits for the response, and returns the
- // response body.
- std::string SendSynchronousRequest(const std::string& uri);
- void SendConnectivityProbing();
- void Connect();
- void ResetConnection();
- void Disconnect();
- QuicSocketAddress local_address() const;
- void ClearPerRequestState();
- bool WaitUntil(int timeout_ms, std::function<bool()> trigger);
- ssize_t Send(const void* buffer, size_t size);
- bool connected() const;
- bool buffer_body() const;
- void set_buffer_body(bool buffer_body);
-
- // Getters for stream state. Please note, these getters are divided into two
- // groups. 1) returns state which only get updated once a complete response
- // is received. 2) returns state of the oldest active stream which have
- // received partial response (if any).
- // Group 1.
- const SpdyHeaderBlock& response_trailers() const;
- bool response_complete() const;
- int64_t response_body_size() const;
- const std::string& response_body() const;
- // Group 2.
- bool response_headers_complete() const;
- const SpdyHeaderBlock* response_headers() const;
- const SpdyHeaderBlock* preliminary_headers() const;
- int64_t response_size() const;
- size_t bytes_read() const;
- size_t bytes_written() const;
-
- // Returns once at least one complete response or a connection close has been
- // received from the server. If responses are received for multiple (say 2)
- // streams, next WaitForResponse will return immediately.
- void WaitForResponse() { WaitForResponseForMs(-1); }
-
- // Returns once some data is received on any open streams or at least one
- // complete response is received from the server.
- void WaitForInitialResponse() { WaitForInitialResponseForMs(-1); }
-
- // Returns once at least one complete response or a connection close has been
- // received from the server, or once the timeout expires. -1 means no timeout.
- // If responses are received for multiple (say 2) streams, next
- // WaitForResponseForMs will return immediately.
- void WaitForResponseForMs(int timeout_ms) {
- WaitUntil(timeout_ms, [this]() { return !closed_stream_states_.empty(); });
- if (response_complete()) {
- VLOG(1) << "Client received response:"
- << response_headers()->DebugString() << response_body();
- }
- }
-
- // Returns once some data is received on any open streams or at least one
- // complete response is received from the server, or once the timeout
- // expires. -1 means no timeout.
- void WaitForInitialResponseForMs(int timeout_ms) {
- WaitUntil(timeout_ms, [this]() { return response_size() != 0; });
- }
-
- // Migrate local address to <|new_host|, a random port>.
- // Return whether the migration succeeded.
- bool MigrateSocket(const QuicIpAddress& new_host);
- // Migrate local address to <|new_host|, |port|>.
- // Return whether the migration succeeded.
- bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port);
- QuicIpAddress bind_to_address() const;
- void set_bind_to_address(QuicIpAddress address);
- const QuicSocketAddress& address() const;
-
- // From QuicSpdyStream::Visitor
- void OnClose(QuicSpdyStream* stream) override;
-
- // From QuicClientPushPromiseIndex::Delegate
- bool CheckVary(const SpdyHeaderBlock& client_request,
- const SpdyHeaderBlock& promise_request,
- const SpdyHeaderBlock& promise_response) override;
- void OnRendezvousResult(QuicSpdyStream*) override;
-
- // Configures client_ to take ownership of and use the writer.
- // Must be called before initial connect.
- void UseWriter(QuicPacketWriterWrapper* writer);
- // If the given ConnectionId is nonzero, configures client_ to use a specific
- // ConnectionId instead of a random one.
- void UseConnectionId(QuicConnectionId connection_id);
-
- // Returns nullptr if the maximum number of streams have already been created.
- QuicSpdyClientStream* GetOrCreateStream();
-
- // Calls GetOrCreateStream(), sends the request on the stream, and
- // stores the request in case it needs to be resent. If |headers| is
- // null, only the body will be sent on the stream.
- ssize_t GetOrCreateStreamAndSendRequest(
- const SpdyHeaderBlock* headers,
- QuicStringPiece body,
- bool fin,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- QuicRstStreamErrorCode stream_error() { return stream_error_; }
- QuicErrorCode connection_error();
-
- MockableQuicClient* client();
-
- // cert_common_name returns the common name value of the server's certificate,
- // or the empty string if no certificate was presented.
- const std::string& cert_common_name() const;
-
- // cert_sct returns the signed timestamp of the server's certificate,
- // or the empty string if no signed timestamp was presented.
- const std::string& cert_sct() const;
-
- // Get the server config map.
- QuicTagValueMap GetServerConfig() const;
-
- void set_auto_reconnect(bool reconnect) { auto_reconnect_ = reconnect; }
-
- void set_priority(SpdyPriority priority) { priority_ = priority; }
-
- void WaitForWriteToFlush();
-
- EpollServer* epoll_server() { return &epoll_server_; }
-
- size_t num_requests() const { return num_requests_; }
-
- size_t num_responses() const { return num_responses_; }
-
- void set_server_address(const QuicSocketAddress& server_address) {
- client_->set_server_address(server_address);
- }
-
- void set_peer_address(const QuicSocketAddress& address) {
- client_->set_peer_address(address);
- }
-
- // Explicitly set the SNI value for this client, overriding the default
- // behavior which extracts the SNI value from the request URL.
- void OverrideSni(const std::string& sni) {
- override_sni_set_ = true;
- override_sni_ = sni;
- }
-
- void Initialize();
-
- void set_client(MockableQuicClient* client) { client_.reset(client); }
-
- // PerStreamState of a stream is updated when it is closed.
- struct PerStreamState {
- PerStreamState(const PerStreamState& other);
- PerStreamState(QuicRstStreamErrorCode stream_error,
- bool response_complete,
- bool response_headers_complete,
- const SpdyHeaderBlock& response_headers,
- const SpdyHeaderBlock& preliminary_headers,
- const std::string& response,
- const SpdyHeaderBlock& response_trailers,
- uint64_t bytes_read,
- uint64_t bytes_written,
- int64_t response_body_size);
- ~PerStreamState();
-
- QuicRstStreamErrorCode stream_error;
- bool response_complete;
- bool response_headers_complete;
- SpdyHeaderBlock response_headers;
- SpdyHeaderBlock preliminary_headers;
- std::string response;
- SpdyHeaderBlock response_trailers;
- uint64_t bytes_read;
- uint64_t bytes_written;
- int64_t response_body_size;
- };
-
- // Given |uri|, populates the fields in |headers| for a simple GET
- // request. If |uri| is a relative URL, the QuicServerId will be
- // use to specify the authority.
- bool PopulateHeaderBlockFromUrl(const std::string& uri,
- SpdyHeaderBlock* headers);
-
- // Waits for a period of time that is long enough to receive all delayed acks
- // sent by peer.
- void WaitForDelayedAcks();
-
- protected:
- QuicTestClient();
-
- private:
- class TestClientDataToResend : public QuicClient::QuicDataToResend {
- public:
- TestClientDataToResend(
- std::unique_ptr<SpdyHeaderBlock> headers,
- QuicStringPiece body,
- bool fin,
- QuicTestClient* test_client,
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
-
- ~TestClientDataToResend() override;
-
- void Resend() override;
-
- protected:
- QuicTestClient* test_client_;
- QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;
- };
-
- bool HaveActiveStream();
-
- // Read oldest received response and remove it from closed_stream_states_.
- void ReadNextResponse();
-
- // Clear open_streams_, closed_stream_states_ and reset
- // latest_created_stream_.
- void ClearPerConnectionState();
-
- // Update latest_created_stream_, add |stream| to open_streams_ and starts
- // tracking its state.
- void SetLatestCreatedStream(QuicSpdyClientStream* stream);
-
- EpollServer epoll_server_;
- std::unique_ptr<MockableQuicClient> client_; // The actual client
- QuicSpdyClientStream* latest_created_stream_;
- std::map<QuicStreamId, QuicSpdyClientStream*> open_streams_;
- // Received responses of closed streams.
- QuicLinkedHashMap<QuicStreamId, PerStreamState> closed_stream_states_;
-
- QuicRstStreamErrorCode stream_error_;
-
- bool response_complete_;
- bool response_headers_complete_;
- mutable SpdyHeaderBlock preliminary_headers_;
- mutable SpdyHeaderBlock response_headers_;
-
- // Parsed response trailers (if present), copied from the stream in OnClose.
- SpdyHeaderBlock response_trailers_;
-
- SpdyPriority priority_;
- std::string response_;
- // bytes_read_ and bytes_written_ are updated only when stream_ is released;
- // prefer bytes_read() and bytes_written() member functions.
- uint64_t bytes_read_;
- uint64_t bytes_written_;
- // The number of HTTP body bytes received.
- int64_t response_body_size_;
- // True if we tried to connect already since the last call to Disconnect().
- bool connect_attempted_;
- // The client will auto-connect exactly once before sending data. If
- // something causes a connection reset, it will not automatically reconnect
- // unless auto_reconnect_ is true.
- bool auto_reconnect_;
- // Should we buffer the response body? Defaults to true.
- bool buffer_body_;
- // For async push promise rendezvous, validation may fail in which
- // case the request should be retried.
- std::unique_ptr<TestClientDataToResend> push_promise_data_to_resend_;
- // Number of requests/responses this client has sent/received.
- size_t num_requests_;
- size_t num_responses_;
-
- // If set, this value is used for the connection SNI, overriding the usual
- // logic which extracts the SNI from the request URL.
- bool override_sni_set_ = false;
- std::string override_sni_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicTestClient);
-};
-
-} // namespace test
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_test_server.cc b/chromium/net/tools/quic/test_tools/quic_test_server.cc
deleted file mode 100644
index ac90e7f39d5..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_test_server.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2015 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/tools/quic/test_tools/quic_test_server.h"
-
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/tools/quic/quic_epoll_alarm_factory.h"
-#include "net/tools/quic/quic_epoll_connection_helper.h"
-#include "net/tools/quic/quic_simple_crypto_server_stream_helper.h"
-#include "net/tools/quic/quic_simple_dispatcher.h"
-#include "net/tools/quic/quic_simple_server_session.h"
-
-namespace net {
-
-namespace test {
-
-class CustomStreamSession : public QuicSimpleServerSession {
- public:
- CustomStreamSession(
- const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStream::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicTestServer::StreamFactory* stream_factory,
- QuicTestServer::CryptoStreamFactory* crypto_stream_factory,
- QuicHttpResponseCache* response_cache)
- : QuicSimpleServerSession(config,
- connection,
- visitor,
- helper,
- crypto_config,
- compressed_certs_cache,
- response_cache),
- stream_factory_(stream_factory),
- crypto_stream_factory_(crypto_stream_factory) {}
-
- QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override {
- if (!ShouldCreateIncomingDynamicStream(id)) {
- return nullptr;
- }
- if (stream_factory_) {
- QuicSpdyStream* stream =
- stream_factory_->CreateStream(id, this, response_cache());
- ActivateStream(QuicWrapUnique(stream));
- return stream;
- }
- return QuicSimpleServerSession::CreateIncomingDynamicStream(id);
- }
-
- QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache) override {
- if (crypto_stream_factory_) {
- return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
- }
- return QuicSimpleServerSession::CreateQuicCryptoServerStream(
- crypto_config, compressed_certs_cache);
- }
-
- private:
- QuicTestServer::StreamFactory* stream_factory_; // Not owned.
- QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
-};
-
-class QuicTestDispatcher : public QuicSimpleDispatcher {
- public:
- QuicTestDispatcher(
- const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- QuicHttpResponseCache* response_cache)
- : QuicSimpleDispatcher(config,
- crypto_config,
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- response_cache),
- session_factory_(nullptr),
- stream_factory_(nullptr),
- crypto_stream_factory_(nullptr) {}
-
- QuicServerSessionBase* CreateQuicSession(QuicConnectionId id,
- const QuicSocketAddress& client,
- QuicStringPiece alpn) override {
- QuicReaderMutexLock lock(&factory_lock_);
- if (session_factory_ == nullptr && stream_factory_ == nullptr &&
- crypto_stream_factory_ == nullptr) {
- return QuicSimpleDispatcher::CreateQuicSession(id, client, alpn);
- }
- QuicConnection* connection = new QuicConnection(
- id, client, helper(), alarm_factory(), CreatePerConnectionWriter(),
- /* owns_writer= */ true, Perspective::IS_SERVER,
- GetSupportedVersions());
-
- QuicServerSessionBase* session = nullptr;
- if (stream_factory_ != nullptr || crypto_stream_factory_ != nullptr) {
- session = new CustomStreamSession(
- config(), connection, this, session_helper(), crypto_config(),
- compressed_certs_cache(), stream_factory_, crypto_stream_factory_,
- response_cache());
- } else {
- session = session_factory_->CreateSession(
- config(), connection, this, session_helper(), crypto_config(),
- compressed_certs_cache(), response_cache());
- }
- session->Initialize();
- return session;
- }
-
- void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
- QuicWriterMutexLock lock(&factory_lock_);
- DCHECK(session_factory_ == nullptr);
- DCHECK(stream_factory_ == nullptr);
- DCHECK(crypto_stream_factory_ == nullptr);
- session_factory_ = factory;
- }
-
- void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
- QuicWriterMutexLock lock(&factory_lock_);
- DCHECK(session_factory_ == nullptr);
- DCHECK(stream_factory_ == nullptr);
- stream_factory_ = factory;
- }
-
- void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
- QuicWriterMutexLock lock(&factory_lock_);
- DCHECK(session_factory_ == nullptr);
- DCHECK(crypto_stream_factory_ == nullptr);
- crypto_stream_factory_ = factory;
- }
-
- private:
- QuicMutex factory_lock_;
- QuicTestServer::SessionFactory* session_factory_; // Not owned.
- QuicTestServer::StreamFactory* stream_factory_; // Not owned.
- QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
-};
-
-QuicTestServer::QuicTestServer(std::unique_ptr<ProofSource> proof_source,
- QuicHttpResponseCache* response_cache)
- : QuicServer(std::move(proof_source), response_cache) {}
-
-QuicTestServer::QuicTestServer(
- std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicHttpResponseCache* response_cache)
- : QuicServer(std::move(proof_source),
- config,
- QuicCryptoServerConfig::ConfigOptions(),
- supported_versions,
- response_cache) {}
-
-QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
- return new QuicTestDispatcher(
- config(), &crypto_config(), version_manager(),
- QuicMakeUnique<QuicEpollConnectionHelper>(epoll_server(),
- QuicAllocator::BUFFER_POOL),
- std::unique_ptr<QuicCryptoServerStream::Helper>(
- new QuicSimpleCryptoServerStreamHelper(QuicRandom::GetInstance())),
- QuicMakeUnique<QuicEpollAlarmFactory>(epoll_server()), response_cache());
-}
-
-void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
- DCHECK(dispatcher());
- static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
-}
-
-void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
- static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
-}
-
-void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
- static_cast<QuicTestDispatcher*>(dispatcher())
- ->SetCryptoStreamFactory(factory);
-}
-
-/////////////////////////// TEST SESSIONS ///////////////////////////////
-
-ImmediateGoAwaySession::ImmediateGoAwaySession(
- const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStream::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicHttpResponseCache* response_cache)
- : QuicSimpleServerSession(config,
- connection,
- visitor,
- helper,
- crypto_config,
- compressed_certs_cache,
- response_cache) {}
-
-void ImmediateGoAwaySession::OnStreamFrame(const QuicStreamFrame& frame) {
- SendGoAway(QUIC_PEER_GOING_AWAY, "");
- QuicSimpleServerSession::OnStreamFrame(frame);
-}
-
-} // namespace test
-
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_test_server.h b/chromium/net/tools/quic/test_tools/quic_test_server.h
deleted file mode 100644
index 13ffc4ca6a0..00000000000
--- a/chromium/net/tools/quic/test_tools/quic_test_server.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2015 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_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
-
-#include "net/quic/core/quic_session.h"
-#include "net/tools/quic/quic_dispatcher.h"
-#include "net/tools/quic/quic_server.h"
-#include "net/tools/quic/quic_simple_server_session.h"
-#include "net/tools/quic/quic_simple_server_stream.h"
-
-namespace net {
-
-namespace test {
-
-// A test server which enables easy creation of custom QuicServerSessions
-//
-// Eventually this may be extended to allow custom QuicConnections etc.
-class QuicTestServer : public QuicServer {
- public:
- // Factory for creating QuicServerSessions.
- class SessionFactory {
- public:
- virtual ~SessionFactory() {}
-
- // Returns a new session owned by the caller.
- virtual QuicServerSessionBase* CreateSession(
- const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStream::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicHttpResponseCache* response_cache) = 0;
- };
-
- // Factory for creating QuicSimpleServerStreams.
- class StreamFactory {
- public:
- virtual ~StreamFactory() {}
-
- // Returns a new stream owned by the caller.
- virtual QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicHttpResponseCache* response_cache) = 0;
- };
-
- class CryptoStreamFactory {
- public:
- virtual ~CryptoStreamFactory() {}
-
- // Returns a new QuicCryptoServerStreamBase owned by the caller
- virtual QuicCryptoServerStreamBase* CreateCryptoStream(
- const QuicCryptoServerConfig* crypto_config,
- QuicServerSessionBase* session) = 0;
- };
-
- QuicTestServer(std::unique_ptr<ProofSource> proof_source,
- QuicHttpResponseCache* response_cache);
- QuicTestServer(std::unique_ptr<ProofSource> proof_source,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- QuicHttpResponseCache* response_cache);
-
- // Create a custom dispatcher which creates custom sessions.
- QuicDispatcher* CreateQuicDispatcher() override;
-
- // Sets a custom session factory, owned by the caller, for easy custom
- // session logic. This is incompatible with setting a stream factory or a
- // crypto stream factory.
- void SetSessionFactory(SessionFactory* factory);
-
- // Sets a custom stream factory, owned by the caller, for easy custom
- // stream logic. This is incompatible with setting a session factory.
- void SetSpdyStreamFactory(StreamFactory* factory);
-
- // Sets a custom crypto stream factory, owned by the caller, for easy custom
- // crypto logic. This is incompatible with setting a session factory.
- void SetCryptoStreamFactory(CryptoStreamFactory* factory);
-};
-
-// Useful test sessions for the QuicTestServer.
-
-// Test session which sends a GOAWAY immedaitely on creation, before crypto
-// credentials have even been established.
-class ImmediateGoAwaySession : public QuicSimpleServerSession {
- public:
- ImmediateGoAwaySession(const QuicConfig& config,
- QuicConnection* connection,
- QuicSession::Visitor* visitor,
- QuicCryptoServerStream::Helper* helper,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- QuicHttpResponseCache* response_cache);
-
- // Override to send GoAway.
- void OnStreamFrame(const QuicStreamFrame& frame) override;
-};
-
-} // namespace test
-
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
diff --git a/chromium/net/tools/quic/test_tools/run_all_unittests.cc b/chromium/net/tools/quic/test_tools/run_all_unittests.cc
deleted file mode 100644
index 6d42d33eb8f..00000000000
--- a/chromium/net/tools/quic/test_tools/run_all_unittests.cc
+++ /dev/null
@@ -1,11 +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 "base/test/test_suite.h"
-
-int main(int argc, char** argv) {
- base::TestSuite test_suite(argc, argv);
-
- return test_suite.Run();
-}
diff --git a/chromium/net/tools/quic/test_tools/server_thread.cc b/chromium/net/tools/quic/test_tools/server_thread.cc
deleted file mode 100644
index 641c5fc88d6..00000000000
--- a/chromium/net/tools/quic/test_tools/server_thread.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2013 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/tools/quic/test_tools/server_thread.h"
-
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/quic/test_tools/crypto_test_utils.h"
-#include "net/tools/quic/quic_dispatcher.h"
-#include "net/tools/quic/test_tools/quic_server_peer.h"
-
-namespace net {
-namespace test {
-
-ServerThread::ServerThread(QuicServer* server, const QuicSocketAddress& address)
- : SimpleThread("server_thread"),
- confirmed_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- pause_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- paused_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- resume_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- quit_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- server_(server),
- address_(address),
- port_(0),
- initialized_(false) {}
-
-ServerThread::~ServerThread() = default;
-
-void ServerThread::Initialize() {
- if (initialized_) {
- return;
- }
-
- server_->CreateUDPSocketAndListen(address_);
-
- QuicWriterMutexLock lock(&port_lock_);
- port_ = server_->port();
-
- initialized_ = true;
-}
-
-void ServerThread::Run() {
- if (!initialized_) {
- Initialize();
- }
-
- while (!quit_.IsSignaled()) {
- if (pause_.IsSignaled() && !resume_.IsSignaled()) {
- paused_.Signal();
- resume_.Wait();
- }
- server_->WaitForEvents();
- ExecuteScheduledActions();
- MaybeNotifyOfHandshakeConfirmation();
- }
-
- server_->Shutdown();
-}
-
-int ServerThread::GetPort() {
- QuicReaderMutexLock lock(&port_lock_);
- int rc = port_;
- return rc;
-}
-
-void ServerThread::Schedule(std::function<void()> action) {
- DCHECK(!quit_.IsSignaled());
- QuicWriterMutexLock lock(&scheduled_actions_lock_);
- scheduled_actions_.push_back(std::move(action));
-}
-
-void ServerThread::WaitForCryptoHandshakeConfirmed() {
- confirmed_.Wait();
-}
-
-void ServerThread::Pause() {
- DCHECK(!pause_.IsSignaled());
- pause_.Signal();
- paused_.Wait();
-}
-
-void ServerThread::Resume() {
- DCHECK(!resume_.IsSignaled());
- DCHECK(pause_.IsSignaled());
- resume_.Signal();
-}
-
-void ServerThread::Quit() {
- if (pause_.IsSignaled() && !resume_.IsSignaled()) {
- resume_.Signal();
- }
- quit_.Signal();
-}
-
-void ServerThread::MaybeNotifyOfHandshakeConfirmation() {
- if (confirmed_.IsSignaled()) {
- // Only notify once.
- return;
- }
- QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(server());
- if (dispatcher->session_map().empty()) {
- // Wait for a session to be created.
- return;
- }
- QuicSession* session = dispatcher->session_map().begin()->second.get();
- if (session->IsCryptoHandshakeConfirmed()) {
- confirmed_.Signal();
- }
-}
-
-void ServerThread::ExecuteScheduledActions() {
- QuicDeque<std::function<void()>> actions;
- {
- QuicWriterMutexLock lock(&scheduled_actions_lock_);
- actions.swap(scheduled_actions_);
- }
- while (!actions.empty()) {
- actions.front()();
- actions.pop_front();
- }
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/server_thread.h b/chromium/net/tools/quic/test_tools/server_thread.h
deleted file mode 100644
index 7ebb5f5992d..00000000000
--- a/chromium/net/tools/quic/test_tools/server_thread.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2013 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_TOOLS_QUIC_TEST_TOOLS_SERVER_THREAD_H_
-#define NET_TOOLS_QUIC_TEST_TOOLS_SERVER_THREAD_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/simple_thread.h"
-#include "net/quic/core/quic_config.h"
-#include "net/quic/platform/api/quic_containers.h"
-#include "net/quic/platform/api/quic_mutex.h"
-#include "net/quic/platform/api/quic_socket_address.h"
-#include "net/tools/quic/quic_server.h"
-
-namespace net {
-namespace test {
-
-// Simple wrapper class to run QuicServer in a dedicated thread.
-class ServerThread : public base::SimpleThread {
- public:
- ServerThread(QuicServer* server, const QuicSocketAddress& address);
-
- ~ServerThread() override;
-
- // Prepares the server, but does not start accepting connections. Useful for
- // injecting mocks.
- void Initialize();
-
- // Runs the event loop. Will initialize if necessary.
- void Run() override;
-
- // Schedules the given action for execution in the event loop.
- void Schedule(std::function<void()> action);
-
- // Waits for the handshake to be confirmed for the first session created.
- void WaitForCryptoHandshakeConfirmed();
-
- // Pauses execution of the server until Resume() is called. May only be
- // called once.
- void Pause();
-
- // Resumes execution of the server after Pause() has been called. May only
- // be called once.
- void Resume();
-
- // Stops the server from executing and shuts it down, destroying all
- // server objects.
- void Quit();
-
- // Returns the underlying server. Care must be taken to avoid data races
- // when accessing the server. It is always safe to access the server
- // after calling Pause() and before calling Resume().
- QuicServer* server() { return server_.get(); }
-
- // Returns the port that the server is listening on.
- int GetPort();
-
- private:
- void MaybeNotifyOfHandshakeConfirmation();
- void ExecuteScheduledActions();
-
- base::WaitableEvent
- confirmed_; // Notified when the first handshake is confirmed.
- base::WaitableEvent pause_; // Notified when the server should pause.
- base::WaitableEvent paused_; // Notitied when the server has paused
- base::WaitableEvent resume_; // Notified when the server should resume.
- base::WaitableEvent quit_; // Notified when the server should quit.
-
- std::unique_ptr<QuicServer> server_;
- QuicSocketAddress address_;
- mutable QuicMutex port_lock_;
- int port_ GUARDED_BY(port_lock_);
-
- bool initialized_;
-
- QuicMutex scheduled_actions_lock_;
- QuicDeque<std::function<void()>> scheduled_actions_
- GUARDED_BY(scheduled_actions_lock_);
-
- DISALLOW_COPY_AND_ASSIGN(ServerThread);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_TEST_TOOLS_SERVER_THREAD_H_