Delete Quartc PiperOrigin-RevId: 314325903 Change-Id: I9ed9fb1cf309b9ba7d5cb90bfe37571f424b056a
diff --git a/quic/quartc/counting_packet_filter.h b/quic/quartc/counting_packet_filter.h deleted file mode 100644 index 4c7c270..0000000 --- a/quic/quartc/counting_packet_filter.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright (c) 2018 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 QUICHE_QUIC_QUARTC_COUNTING_PACKET_FILTER_H_ -#define QUICHE_QUIC_QUARTC_COUNTING_PACKET_FILTER_H_ - -#include <string> - -#include "net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/port.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" - -namespace quic { -namespace simulator { - -// Simple packet filter which drops the first N packets it observes. -class CountingPacketFilter : public simulator::PacketFilter { - public: - CountingPacketFilter(simulator::Simulator* simulator, - const std::string& name, - simulator::Endpoint* endpoint) - : PacketFilter(simulator, name, endpoint) {} - - void set_packets_to_drop(int count) { packets_to_drop_ = count; } - - protected: - bool FilterPacket(const simulator::Packet& /*packet*/) override { - if (packets_to_drop_ > 0) { - --packets_to_drop_; - return false; - } - return true; - } - - private: - int packets_to_drop_ = 0; -}; - -} // namespace simulator -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_COUNTING_PACKET_FILTER_H_
diff --git a/quic/quartc/quartc_connection_helper.cc b/quic/quartc/quartc_connection_helper.cc deleted file mode 100644 index da74858..0000000 --- a/quic/quartc/quartc_connection_helper.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_connection_helper.h" - -namespace quic { - -QuartcConnectionHelper::QuartcConnectionHelper(const QuicClock* clock, - QuicRandom* random) - : clock_(clock), random_(random) {} - -const QuicClock* QuartcConnectionHelper::GetClock() const { - return clock_; -} - -QuicRandom* QuartcConnectionHelper::GetRandomGenerator() { - return random_; -} - -QuicBufferAllocator* QuartcConnectionHelper::GetStreamSendBufferAllocator() { - return &buffer_allocator_; -} - -} // namespace quic
diff --git a/quic/quartc/quartc_connection_helper.h b/quic/quartc/quartc_connection_helper.h deleted file mode 100644 index 72cc707..0000000 --- a/quic/quartc/quartc_connection_helper.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_CONNECTION_HELPER_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_CONNECTION_HELPER_H_ - -#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" -#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" -#include "net/third_party/quiche/src/quic/core/quic_clock.h" -#include "net/third_party/quiche/src/quic/core/quic_connection.h" -#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" - -namespace quic { - -// Simple implementation of QuicConnectionHelperInterface for Quartc. -class QuartcConnectionHelper : public QuicConnectionHelperInterface { - public: - QuartcConnectionHelper(const QuicClock* clock, QuicRandom* random); - - // QuicConnectionHelperInterface overrides. - const QuicClock* GetClock() const override; - QuicRandom* GetRandomGenerator() override; - QuicBufferAllocator* GetStreamSendBufferAllocator() override; - - private: - const QuicClock* clock_; - QuicRandom* random_; - SimpleBufferAllocator buffer_allocator_; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_CONNECTION_HELPER_H_
diff --git a/quic/quartc/quartc_crypto_helpers.cc b/quic/quartc/quartc_crypto_helpers.cc deleted file mode 100644 index d2be599..0000000 --- a/quic/quartc/quartc_crypto_helpers.cc +++ /dev/null
@@ -1,159 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_utils.h" - -namespace quic { - -void DummyProofSource::GetProof(const QuicSocketAddress& server_address, - const QuicSocketAddress& client_address, - const std::string& hostname, - const std::string& /*server_config*/, - QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece /*chlo_hash*/, - std::unique_ptr<Callback> callback) { - QuicReferenceCountedPointer<ProofSource::Chain> chain = - GetCertChain(server_address, client_address, hostname); - QuicCryptoProof proof; - proof.signature = "Dummy signature"; - proof.leaf_cert_scts = "Dummy timestamp"; - callback->Run(true, chain, proof, nullptr /* details */); -} - -QuicReferenceCountedPointer<DummyProofSource::Chain> -DummyProofSource::GetCertChain(const QuicSocketAddress& /*server_address*/, - const QuicSocketAddress& /*client_address*/, - const std::string& /*hostname*/) { - std::vector<std::string> certs; - certs.push_back(kDummyCertName); - return QuicReferenceCountedPointer<ProofSource::Chain>( - new ProofSource::Chain(certs)); -} - -void DummyProofSource::ComputeTlsSignature( - const QuicSocketAddress& /*server_address*/, - const QuicSocketAddress& /*client_address*/, - const std::string& /*hostname*/, - uint16_t /*signature_algorithm*/, - quiche::QuicheStringPiece /*in*/, - std::unique_ptr<SignatureCallback> callback) { - callback->Run(true, "Dummy signature", /*details=*/nullptr); -} - -QuicAsyncStatus InsecureProofVerifier::VerifyProof( - const std::string& /*hostname*/, - const uint16_t /*port*/, - const std::string& /*server_config*/, - QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece /*chlo_hash*/, - const std::vector<std::string>& /*certs*/, - const std::string& /*cert_sct*/, - const std::string& /*signature*/, - const ProofVerifyContext* /*context*/, - std::string* /*error_details*/, - std::unique_ptr<ProofVerifyDetails>* /*verify_details*/, - std::unique_ptr<ProofVerifierCallback> /*callback*/) { - return QUIC_SUCCESS; -} - -QuicAsyncStatus InsecureProofVerifier::VerifyCertChain( - const std::string& /*hostname*/, - const std::vector<std::string>& /*certs*/, - const std::string& /*ocsp_response*/, - const std::string& /*cert_sct*/, - const ProofVerifyContext* /*context*/, - std::string* /*error_details*/, - std::unique_ptr<ProofVerifyDetails>* /*details*/, - std::unique_ptr<ProofVerifierCallback> /*callback*/) { - return QUIC_SUCCESS; -} - -std::unique_ptr<ProofVerifyContext> -InsecureProofVerifier::CreateDefaultContext() { - return nullptr; -} - -bool QuartcCryptoServerStreamHelper::CanAcceptClientHello( - const CryptoHandshakeMessage& /*message*/, - const QuicSocketAddress& /*client_address*/, - const QuicSocketAddress& /*peer_address*/, - const QuicSocketAddress& /*self_address*/, - std::string* /*error_details*/) const { - return true; -} - -std::unique_ptr<QuicCryptoClientConfig> CreateCryptoClientConfig( - quiche::QuicheStringPiece pre_shared_key) { - auto config = std::make_unique<QuicCryptoClientConfig>( - std::make_unique<InsecureProofVerifier>()); - config->set_pad_inchoate_hello(false); - config->set_pad_full_hello(false); - if (!pre_shared_key.empty()) { - config->set_pre_shared_key(pre_shared_key); - } - return config; -} - -CryptoServerConfig CreateCryptoServerConfig( - QuicRandom* random, - const QuicClock* clock, - quiche::QuicheStringPiece pre_shared_key) { - CryptoServerConfig crypto_server_config; - - // Generate a random source address token secret. For long-running servers - // it's better to not regenerate it for each connection to enable zero-RTT - // handshakes, but for transient clients it does not matter. - char source_address_token_secret[kInputKeyingMaterialLength]; - random->RandBytes(source_address_token_secret, kInputKeyingMaterialLength); - auto config = std::make_unique<QuicCryptoServerConfig>( - std::string(source_address_token_secret, kInputKeyingMaterialLength), - random, std::make_unique<DummyProofSource>(), - KeyExchangeSource::Default()); - - // We run QUIC over ICE, and ICE is verifying remote side with STUN pings. - // We disable source address token validation in order to allow for 0-rtt - // setup (plus source ip addresses are changing even during the connection - // when ICE is used). - config->set_validate_source_address_token(false); - - // Effectively disables the anti-amplification measures (we don't need - // them because we use ICE, and we need to disable them because we disable - // padding of crypto packets). - // This multiplier must be large enough so that the crypto handshake packet - // (approx. 300 bytes) multiplied by this multiplier is larger than a fully - // sized packet (currently 1200 bytes). - // 1500 is a bit extreme: if you can imagine sending a 1 byte packet, and - // your largest MTU would be below 1500 bytes, 1500*1 >= - // any_packet_that_you_can_imagine_sending. - // (again, we hardcode packet size to 1200, so we are not dealing with jumbo - // frames). - config->set_chlo_multiplier(1500); - - // We are sending small client hello, we must not validate its size. - config->set_validate_chlo_size(false); - - // Provide server with serialized config string to prove ownership. - QuicCryptoServerConfig::ConfigOptions options; - // The |message| is used to handle the return value of AddDefaultConfig - // which is raw pointer of the CryptoHandshakeMessage. - std::unique_ptr<CryptoHandshakeMessage> message( - config->AddDefaultConfig(random, clock, options)); - config->set_pad_rej(false); - config->set_pad_shlo(false); - if (!pre_shared_key.empty()) { - config->set_pre_shared_key(pre_shared_key); - } - crypto_server_config.config = std::move(config); - const QuicData& data = message->GetSerialized(); - - crypto_server_config.serialized_crypto_config = - std::string(data.data(), data.length()); - return crypto_server_config; -} - -} // namespace quic
diff --git a/quic/quartc/quartc_crypto_helpers.h b/quic/quartc/quartc_crypto_helpers.h deleted file mode 100644 index 544b783..0000000 --- a/quic/quartc/quartc_crypto_helpers.h +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_CRYPTO_HELPERS_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_CRYPTO_HELPERS_H_ - -#include <string> - -#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" -#include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" -#include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" -#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" -#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" -#include "net/third_party/quiche/src/quic/core/quic_connection_id.h" -#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h" -#include "net/third_party/quiche/src/quic/core/quic_versions.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -// Never, ever, change this certificate name. You will break 0-rtt handshake if -// you do. -static constexpr char kDummyCertName[] = "Dummy cert"; - -struct CryptoServerConfig { - std::unique_ptr<QuicCryptoServerConfig> config; - std::string serialized_crypto_config; -}; - -// Length of HKDF input keying material, equal to its number of bytes. -// https://tools.ietf.org/html/rfc5869#section-2.2. -// TODO(zhihuang): Verify that input keying material length is correct. -constexpr size_t kInputKeyingMaterialLength = 32; - -// Used by QuicCryptoServerConfig to provide dummy proof credentials. -// TODO(zhihuang): Remove when secure P2P QUIC handshake is possible. -class DummyProofSource : public ProofSource { - public: - DummyProofSource() {} - ~DummyProofSource() override {} - - // ProofSource overrides. - void GetProof(const QuicSocketAddress& server_address, - const QuicSocketAddress& client_address, - const std::string& hostname, - const std::string& server_config, - QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, - std::unique_ptr<Callback> callback) override; - - QuicReferenceCountedPointer<Chain> GetCertChain( - const QuicSocketAddress& server_address, - const QuicSocketAddress& client_address, - const std::string& hostname) override; - - void ComputeTlsSignature( - const QuicSocketAddress& server_address, - const QuicSocketAddress& client_address, - const std::string& hostname, - uint16_t signature_algorithm, - quiche::QuicheStringPiece in, - std::unique_ptr<SignatureCallback> callback) override; - - TicketCrypter* GetTicketCrypter() override { return nullptr; } -}; - -// Used by QuicCryptoClientConfig to ignore the peer's credentials -// and establish an insecure QUIC connection. -// TODO(zhihuang): Remove when secure P2P QUIC handshake is possible. -class InsecureProofVerifier : public ProofVerifier { - public: - InsecureProofVerifier() {} - ~InsecureProofVerifier() override {} - - // ProofVerifier overrides. - QuicAsyncStatus VerifyProof( - const std::string& hostname, - const uint16_t port, - const std::string& server_config, - QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, - const std::vector<std::string>& certs, - const std::string& cert_sct, - const std::string& signature, - const ProofVerifyContext* context, - std::string* error_details, - std::unique_ptr<ProofVerifyDetails>* verify_details, - std::unique_ptr<ProofVerifierCallback> callback) override; - - QuicAsyncStatus VerifyCertChain( - const std::string& hostname, - const std::vector<std::string>& certs, - const std::string& ocsp_response, - const std::string& cert_sct, - const ProofVerifyContext* context, - std::string* error_details, - std::unique_ptr<ProofVerifyDetails>* details, - std::unique_ptr<ProofVerifierCallback> callback) override; - - std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override; -}; - -// Implementation of the server-side crypto stream helper. -class QuartcCryptoServerStreamHelper - : public QuicCryptoServerStreamBase::Helper { - public: - bool CanAcceptClientHello(const CryptoHandshakeMessage& message, - const QuicSocketAddress& client_address, - const QuicSocketAddress& peer_address, - const QuicSocketAddress& self_address, - std::string* error_details) const override; -}; - -std::unique_ptr<QuicCryptoClientConfig> CreateCryptoClientConfig( - quiche::QuicheStringPiece pre_shared_key); - -CryptoServerConfig CreateCryptoServerConfig( - QuicRandom* random, - const QuicClock* clock, - quiche::QuicheStringPiece pre_shared_key); - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_CRYPTO_HELPERS_H_
diff --git a/quic/quartc/quartc_dispatcher.cc b/quic/quartc/quartc_dispatcher.cc deleted file mode 100644 index c5c4c4a..0000000 --- a/quic/quartc/quartc_dispatcher.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_dispatcher.h" - -#include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/core/quic_versions.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_factory.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -QuartcDispatcher::QuartcDispatcher( - std::unique_ptr<QuicConfig> config, - std::unique_ptr<QuicCryptoServerConfig> crypto_config, - QuicVersionManager* version_manager, - std::unique_ptr<QuicConnectionHelperInterface> helper, - std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper, - std::unique_ptr<QuicAlarmFactory> alarm_factory, - std::unique_ptr<QuartcPacketWriter> packet_writer, - Delegate* delegate) - : QuicDispatcher( - config.get(), - crypto_config.get(), - version_manager, - std::move(helper), - std::move(session_helper), - std::move(alarm_factory), - QuicUtils::CreateZeroConnectionId( - version_manager->GetSupportedVersions()[0].transport_version) - .length()), - owned_quic_config_(std::move(config)), - owned_crypto_config_(std::move(crypto_config)), - delegate_(delegate), - packet_writer_(packet_writer.get()) { - // Allow incoming packets to set our expected connection ID length. - SetShouldUpdateExpectedServerConnectionIdLength(true); - // Allow incoming packets with connection ID lengths shorter than allowed. - SetAllowShortInitialServerConnectionIds(true); - // QuicDispatcher takes ownership of the writer. - QuicDispatcher::InitializeWithWriter(packet_writer.release()); - // NB: This must happen *after* InitializeWithWriter. It can call us back - // with OnTransportCanWrite() immediately, and the dispatcher needs to be - // fully initialized to handle that. - packet_writer_->SetPacketTransportDelegate(this); -} - -QuartcDispatcher::~QuartcDispatcher() { - packet_writer_->SetPacketTransportDelegate(nullptr); -} - -std::unique_ptr<QuicSession> QuartcDispatcher::CreateQuicSession( - QuicConnectionId connection_id, - const QuicSocketAddress& client_address, - quiche::QuicheStringPiece /*alpn*/, - const ParsedQuicVersion& version) { - // Make our expected connection ID non-mutable since we have a connection. - SetShouldUpdateExpectedServerConnectionIdLength(false); - std::unique_ptr<QuicConnection> connection = CreateQuicConnection( - connection_id, client_address, helper(), alarm_factory(), writer(), - Perspective::IS_SERVER, ParsedQuicVersionVector{version}); - auto session = std::make_unique<QuartcServerSession>( - std::move(connection), /*visitor=*/this, config(), GetSupportedVersions(), - helper()->GetClock(), crypto_config(), compressed_certs_cache(), - session_helper()); - delegate_->OnSessionCreated(session.get()); - return session; -} - -void QuartcDispatcher::OnTransportCanWrite() { - OnCanWrite(); -} - -void QuartcDispatcher::OnTransportReceived(const char* data, size_t data_len) { - // QuartcPacketTransport does not surface real peer addresses, so the - // dispatcher uses a dummy address when processing incoming packets. Note that - // the dispatcher refuses to process anything with port 0. - static const QuicSocketAddress* dummy_address = - new QuicSocketAddress(QuicIpAddress::Any4(), /*port=*/1); - - QuicReceivedPacket packet(data, data_len, helper()->GetClock()->Now()); - ProcessPacket(/*self_address=*/*dummy_address, - /*peer_address=*/*dummy_address, packet); -} - -} // namespace quic
diff --git a/quic/quartc/quartc_dispatcher.h b/quic/quartc/quartc_dispatcher.h deleted file mode 100644 index b7605f9..0000000 --- a/quic/quartc/quartc_dispatcher.h +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_DISPATCHER_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_DISPATCHER_H_ - -#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" -#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" -#include "net/third_party/quiche/src/quic/core/quic_config.h" -#include "net/third_party/quiche/src/quic/core/quic_connection.h" -#include "net/third_party/quiche/src/quic/core/quic_connection_id.h" -#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h" -#include "net/third_party/quiche/src/quic/core/quic_dispatcher.h" -#include "net/third_party/quiche/src/quic/core/quic_version_manager.h" -#include "net/third_party/quiche/src/quic/core/quic_versions.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -class QuartcDispatcher : public QuicDispatcher, - QuartcPacketTransport::Delegate { - public: - class Delegate { - public: - virtual ~Delegate() = default; - virtual void OnSessionCreated(QuartcSession* session) = 0; - }; - - QuartcDispatcher( - std::unique_ptr<QuicConfig> config, - std::unique_ptr<QuicCryptoServerConfig> crypto_config, - QuicVersionManager* version_manager, - std::unique_ptr<QuicConnectionHelperInterface> helper, - std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper, - std::unique_ptr<QuicAlarmFactory> alarm_factory, - std::unique_ptr<QuartcPacketWriter> packet_writer, - Delegate* delegate); - ~QuartcDispatcher() override; - - std::unique_ptr<QuicSession> CreateQuicSession( - QuicConnectionId server_connection_id, - const QuicSocketAddress& client_address, - quiche::QuicheStringPiece alpn, - const ParsedQuicVersion& version) override; - - // QuartcPacketTransport::Delegate overrides. - void OnTransportCanWrite() override; - void OnTransportReceived(const char* data, size_t data_len) override; - - private: - // Members owned by QuartcDispatcher but not QuicDispatcher. - std::unique_ptr<QuicConfig> owned_quic_config_; - std::unique_ptr<QuicCryptoServerConfig> owned_crypto_config_; - - // Delegate invoked when the dispatcher creates a new session. - Delegate* delegate_; - - // The packet writer used by this dispatcher. Owned by the base class, but - // the base class upcasts it to QuicPacketWriter (which prevents detaching the - // transport delegate without a downcast). - QuartcPacketWriter* packet_writer_; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_DISPATCHER_H_
diff --git a/quic/quartc/quartc_endpoint.cc b/quic/quartc/quartc_endpoint.cc deleted file mode 100644 index ca8fad6..0000000 --- a/quic/quartc/quartc_endpoint.cc +++ /dev/null
@@ -1,190 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_endpoint.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_version_manager.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -namespace { - -// Wrapper around a QuicAlarmFactory which delegates to the wrapped factory. -// Usee to convert an unowned pointer into an owned pointer, so that the new -// "owner" does not delete the underlying factory. Note that this is only valid -// when the unowned pointer is already guaranteed to outlive the new "owner". -class QuartcAlarmFactoryWrapper : public QuicAlarmFactory { - public: - explicit QuartcAlarmFactoryWrapper(QuicAlarmFactory* impl) : impl_(impl) {} - - QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override; - QuicArenaScopedPtr<QuicAlarm> CreateAlarm( - QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, - QuicConnectionArena* arena) override; - - private: - QuicAlarmFactory* impl_; -}; - -QuicAlarm* QuartcAlarmFactoryWrapper::CreateAlarm( - QuicAlarm::Delegate* delegate) { - return impl_->CreateAlarm(delegate); -} - -QuicArenaScopedPtr<QuicAlarm> QuartcAlarmFactoryWrapper::CreateAlarm( - QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, - QuicConnectionArena* arena) { - return impl_->CreateAlarm(std::move(delegate), arena); -} - -} // namespace - -QuartcClientEndpoint::QuartcClientEndpoint( - QuicAlarmFactory* alarm_factory, - const QuicClock* clock, - QuicRandom* random, - QuartcEndpoint::Delegate* delegate, - const QuartcSessionConfig& config, - quiche::QuicheStringPiece serialized_server_config, - std::unique_ptr<QuicVersionManager> version_manager) - : alarm_factory_(alarm_factory), - clock_(clock), - delegate_(delegate), - serialized_server_config_(serialized_server_config), - version_manager_(version_manager ? std::move(version_manager) - : std::make_unique<QuicVersionManager>( - AllSupportedVersions())), - create_session_alarm_(QuicWrapUnique( - alarm_factory_->CreateAlarm(new CreateSessionDelegate(this)))), - connection_helper_( - std::make_unique<QuartcConnectionHelper>(clock_, random)), - config_(config) {} - -void QuartcClientEndpoint::Connect(QuartcPacketTransport* packet_transport) { - packet_transport_ = packet_transport; - // For the first attempt to connect, use any version that the client supports. - current_versions_ = version_manager_->GetSupportedVersions(); - create_session_alarm_->Set(clock_->Now()); -} - -void QuartcClientEndpoint::OnCreateSessionAlarm() { - session_ = CreateQuartcClientSession( - config_, clock_, alarm_factory_, connection_helper_.get(), - current_versions_, serialized_server_config_, packet_transport_); - session_->SetDelegate(this); - delegate_->OnSessionCreated(session_.get()); -} - -void QuartcClientEndpoint::OnCryptoHandshakeComplete() { - delegate_->OnCryptoHandshakeComplete(); -} - -void QuartcClientEndpoint::OnConnectionWritable() { - delegate_->OnConnectionWritable(); -} - -void QuartcClientEndpoint::OnIncomingStream(QuartcStream* stream) { - delegate_->OnIncomingStream(stream); -} - -void QuartcClientEndpoint::OnCongestionControlChange( - QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) { - delegate_->OnCongestionControlChange(bandwidth_estimate, pacing_rate, - latest_rtt); -} - -void QuartcClientEndpoint::OnConnectionClosed( - const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) { - // First, see if we can restart the session with a mutually-supported version. - if (frame.quic_error_code == QUIC_INVALID_VERSION && session_ && - session_->connection() && - !session_->connection()->server_supported_versions().empty()) { - for (const auto& client_version : - version_manager_->GetSupportedVersions()) { - if (QuicContainsValue(session_->connection()->server_supported_versions(), - client_version)) { - // Found a mutually-supported version. Reconnect using that version. - current_versions_.clear(); - current_versions_.push_back(client_version); - create_session_alarm_->Set(clock_->Now()); - return; - } - } - } - - // Permanent version negotiation errors are forwarded to the |delegate_|, - // along with all other errors. - delegate_->OnConnectionClosed(frame, source); -} - -void QuartcClientEndpoint::OnMessageReceived( - quiche::QuicheStringPiece message) { - delegate_->OnMessageReceived(message); -} - -void QuartcClientEndpoint::OnMessageSent(int64_t datagram_id) { - delegate_->OnMessageSent(datagram_id); -} - -void QuartcClientEndpoint::OnMessageAcked(int64_t datagram_id, - QuicTime receive_timestamp) { - delegate_->OnMessageAcked(datagram_id, receive_timestamp); -} - -void QuartcClientEndpoint::OnMessageLost(int64_t datagram_id) { - delegate_->OnMessageLost(datagram_id); -} - -QuartcServerEndpoint::QuartcServerEndpoint( - QuicAlarmFactory* alarm_factory, - const QuicClock* clock, - QuicRandom* random, - QuartcEndpoint::Delegate* delegate, - const QuartcSessionConfig& config, - std::unique_ptr<QuicVersionManager> version_manager) - : alarm_factory_(alarm_factory), - delegate_(delegate), - config_(config), - version_manager_(version_manager ? std::move(version_manager) - : std::make_unique<QuicVersionManager>( - AllSupportedVersions())), - pre_connection_helper_( - std::make_unique<QuartcConnectionHelper>(clock, random)), - crypto_config_( - CreateCryptoServerConfig(pre_connection_helper_->GetRandomGenerator(), - clock, - config.pre_shared_key)) {} - -void QuartcServerEndpoint::Connect(QuartcPacketTransport* packet_transport) { - DCHECK(pre_connection_helper_ != nullptr); - dispatcher_ = std::make_unique<QuartcDispatcher>( - std::make_unique<QuicConfig>(CreateQuicConfig(config_)), - std::move(crypto_config_.config), version_manager_.get(), - std::move(pre_connection_helper_), - std::make_unique<QuartcCryptoServerStreamHelper>(), - std::make_unique<QuartcAlarmFactoryWrapper>(alarm_factory_), - std::make_unique<QuartcPacketWriter>(packet_transport, - config_.max_packet_size), - this); - // The dispatcher requires at least one call to |ProcessBufferedChlos| to - // set the number of connections it is allowed to create. - dispatcher_->ProcessBufferedChlos(/*max_connections_to_create=*/1); -} - -void QuartcServerEndpoint::OnSessionCreated(QuartcSession* session) { - session->SetDelegate(delegate_); - delegate_->OnSessionCreated(session); -} - -} // namespace quic
diff --git a/quic/quartc/quartc_endpoint.h b/quic/quartc/quartc_endpoint.h deleted file mode 100644 index ea1a63f..0000000 --- a/quic/quartc/quartc_endpoint.h +++ /dev/null
@@ -1,203 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_ENDPOINT_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_ENDPOINT_H_ - -#include <string> - -#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" -#include "net/third_party/quiche/src/quic/core/quic_clock.h" -#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_factory.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -// Endpoint (client or server) in a peer-to-peer Quartc connection. -class QuartcEndpoint { - public: - class Delegate : public QuartcSession::Delegate { - public: - virtual ~Delegate() = default; - - // Called when an endpoint creates a new session, before any packets are - // processed or sent. The callee should perform any additional - // configuration required, such as setting up congestion control, before - // returning. |session| is owned by the endpoint, but remains safe to use - // until another call to |OnSessionCreated| or |OnConnectionClosed| occurs, - // at which point previous session may be destroyed. - // - // Callees must not change the |session|'s delegate. The Endpoint itself - // manages the delegate and will forward calls. - // - // New calls to |OnSessionCreated| will only occur prior to - // |OnConnectionWritable|, during initial connection negotiation. - virtual void OnSessionCreated(QuartcSession* session) = 0; - }; - - virtual ~QuartcEndpoint() = default; - - // Connects the endpoint using the given session config. After |Connect| is - // called, the endpoint will asynchronously create a session, then call - // |Delegate::OnSessionCreated|. - virtual void Connect(QuartcPacketTransport* packet_transport) = 0; -}; - -// Implementation of QuartcEndpoint which immediately (but asynchronously) -// creates a session by scheduling a QuicAlarm. Only suitable for use with the -// client perspective. -class QuartcClientEndpoint : public QuartcEndpoint, - public QuartcSession::Delegate { - public: - // |alarm_factory|, |clock|, and |delegate| are owned by the caller and must - // outlive the endpoint. - QuartcClientEndpoint( - QuicAlarmFactory* alarm_factory, - const QuicClock* clock, - QuicRandom* random, - QuartcEndpoint::Delegate* delegate, - const QuartcSessionConfig& config, - quiche::QuicheStringPiece serialized_server_config, - std::unique_ptr<QuicVersionManager> version_manager = nullptr); - - void Connect(QuartcPacketTransport* packet_transport) override; - - // QuartcSession::Delegate overrides. - void OnCryptoHandshakeComplete() override; - void OnConnectionWritable() override; - void OnIncomingStream(QuartcStream* stream) override; - void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) override; - void OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) override; - void OnMessageReceived(quiche::QuicheStringPiece message) override; - void OnMessageSent(int64_t datagram_id) override; - void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp) override; - void OnMessageLost(int64_t datagram_id) override; - - private: - friend class CreateSessionDelegate; - class CreateSessionDelegate : public QuicAlarm::Delegate { - public: - CreateSessionDelegate(QuartcClientEndpoint* endpoint) - : endpoint_(endpoint) {} - - void OnAlarm() override { endpoint_->OnCreateSessionAlarm(); } - - private: - QuartcClientEndpoint* endpoint_; - }; - - // Callback which occurs when |create_session_alarm_| fires. - void OnCreateSessionAlarm(); - - // Implementation of QuicAlarmFactory used by this endpoint. Unowned. - QuicAlarmFactory* alarm_factory_; - - // Implementation of QuicClock used by this endpoint. Unowned. - const QuicClock* clock_; - - // Delegate which receives callbacks for newly created sessions. - QuartcEndpoint::Delegate* delegate_; - - // Server config. If valid, used to perform a 0-RTT connection. - const std::string serialized_server_config_; - - // Version manager. May be injected to control version negotiation in tests. - std::unique_ptr<QuicVersionManager> version_manager_; - - // Versions to be used when the next session is created. The session will - // choose one of these versions for its connection attempt. - // - // If the connection does not succeed, the client session MAY try again using - // another version from this list, or it MAY simply fail with a - // QUIC_INVALID_VERSION error. The latter occurs when it is not possible to - // upgrade a connection in-place (for example, if the way stream ids are - // allocated changes between versions). This failure mode is handled by - // narrowing |current_versions_| to one of that is mutually-supported and - // reconnecting (with a new session). - ParsedQuicVersionVector current_versions_; - - // Alarm for creating sessions asynchronously. The alarm is set when - // Connect() is called. When it fires, the endpoint creates a session and - // calls the delegate. - std::unique_ptr<QuicAlarm> create_session_alarm_; - - // Helper used by QuicConnection. - std::unique_ptr<QuicConnectionHelperInterface> connection_helper_; - - // Config to be used for new sessions. - QuartcSessionConfig config_; - - // The currently-active session. Nullptr until |Connect| and - // |Delegate::OnSessionCreated| are called. - std::unique_ptr<QuartcSession> session_; - - QuartcPacketTransport* packet_transport_; -}; - -// Implementation of QuartcEndpoint which uses a QuartcDispatcher to listen for -// an incoming CHLO and create a session when one arrives. Only suitable for -// use with the server perspective. -class QuartcServerEndpoint : public QuartcEndpoint, - public QuartcDispatcher::Delegate { - public: - QuartcServerEndpoint( - QuicAlarmFactory* alarm_factory, - const QuicClock* clock, - QuicRandom* random, - QuartcEndpoint::Delegate* delegate, - const QuartcSessionConfig& config, - std::unique_ptr<QuicVersionManager> version_manager = nullptr); - - // Implements QuartcEndpoint. - void Connect(QuartcPacketTransport* packet_transport) override; - - // Implements QuartcDispatcher::Delegate. - void OnSessionCreated(QuartcSession* session) override; - - // Accessor to retrieve the server crypto config. May only be called after - // Connect(). - quiche::QuicheStringPiece server_crypto_config() const { - return crypto_config_.serialized_crypto_config; - } - - const std::vector<ParsedQuicVersion> GetSupportedQuicVersions() const { - return version_manager_->GetSupportedVersions(); - } - - private: - // Implementation of QuicAlarmFactory used by this endpoint. Unowned. - QuicAlarmFactory* alarm_factory_; - - // Delegate which receives callbacks for newly created sessions. - QuartcEndpoint::Delegate* delegate_; - - // Config to be used for new sessions. - QuartcSessionConfig config_; - - // Version manager. May be injected to control version negotiation in tests. - std::unique_ptr<QuicVersionManager> version_manager_; - - // QuartcDispatcher waits for an incoming CHLO, then either rejects it or - // creates a session to respond to it. The dispatcher owns all sessions it - // creates. - std::unique_ptr<QuartcDispatcher> dispatcher_; - - // This field is only available before connection was started. - std::unique_ptr<QuartcConnectionHelper> pre_connection_helper_; - - // A configuration, containing public key, that may need to be passed to the - // client to enable 0rtt. - CryptoServerConfig crypto_config_; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_ENDPOINT_H_
diff --git a/quic/quartc/quartc_endpoint_test.cc b/quic/quartc/quartc_endpoint_test.cc deleted file mode 100644 index d2f9420..0000000 --- a/quic/quartc/quartc_endpoint_test.cc +++ /dev/null
@@ -1,251 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_endpoint.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_versions.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h" -#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" - -namespace quic { -namespace { - -class QuartcEndpointTest : public QuicTest { - protected: - QuartcEndpointTest() - : client_transport_(&simulator_, - "client_transport", - "server_transport", - 10 * kDefaultMaxPacketSize), - server_transport_(&simulator_, - "server_transport", - "client_transport", - 10 * kDefaultMaxPacketSize), - client_server_link_(&client_transport_, - &server_transport_, - QuicBandwidth::FromKBitsPerSecond(10000), - QuicTime::Delta::FromMilliseconds(1)), - server_endpoint_delegate_(&server_stream_delegate_, - simulator_.GetClock()), - server_endpoint_(std::make_unique<QuartcServerEndpoint>( - simulator_.GetAlarmFactory(), - simulator_.GetClock(), - simulator_.GetRandomGenerator(), - &server_endpoint_delegate_, - QuartcSessionConfig())), - client_endpoint_delegate_(&client_stream_delegate_, - simulator_.GetClock()), - client_endpoint_(std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), - simulator_.GetClock(), - simulator_.GetRandomGenerator(), - &client_endpoint_delegate_, - QuartcSessionConfig(), - /*serialized_server_config=*/"")) { - // Make sure these versions are enabled since some tests use them. - SetQuicReloadableFlag(quic_disable_version_q043, false); - SetQuicReloadableFlag(quic_disable_version_q046, false); - } - - simulator::Simulator simulator_; - - simulator::SimulatedQuartcPacketTransport client_transport_; - simulator::SimulatedQuartcPacketTransport server_transport_; - simulator::SymmetricLink client_server_link_; - - FakeQuartcStreamDelegate server_stream_delegate_; - FakeQuartcEndpointDelegate server_endpoint_delegate_; - - std::unique_ptr<QuartcServerEndpoint> server_endpoint_; - - FakeQuartcStreamDelegate client_stream_delegate_; - FakeQuartcEndpointDelegate client_endpoint_delegate_; - - std::unique_ptr<QuartcClientEndpoint> client_endpoint_; -}; - -// After calling Connect, the client endpoint must wait for an async callback. -// The callback occurs after a finite amount of time and produces a session. -TEST_F(QuartcEndpointTest, ClientCreatesSessionAsynchronously) { - client_endpoint_->Connect(&client_transport_); - - EXPECT_EQ(client_endpoint_delegate_.session(), nullptr); - - EXPECT_TRUE(simulator_.RunUntil( - [this] { return client_endpoint_delegate_.session() != nullptr; })); -} - -// Tests that the server can negotiate for an older QUIC version if the client -// attempts to connect using a newer version. -TEST_F(QuartcEndpointTest, - QUIC_TEST_DISABLED_IN_CHROME(ServerNegotiatesForOldVersion)) { - // Reset the client endpoint to prefer version 46 but also be capable of - // speaking version 43. - ParsedQuicVersionVector client_versions; - client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46}); - client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43}); - client_endpoint_ = std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), &client_endpoint_delegate_, - QuartcSessionConfig(), - /*serialized_server_config=*/"", - std::make_unique<QuicVersionManager>(client_versions)); - - // Reset the server endpoint to only speak version 43. - ParsedQuicVersionVector server_versions; - server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43}); - server_endpoint_ = std::make_unique<QuartcServerEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), &server_endpoint_delegate_, - QuartcSessionConfig(), - std::make_unique<QuicVersionManager>(server_versions)); - - // The endpoints should be able to establish a connection using version 46. - server_endpoint_->Connect(&server_transport_); - client_endpoint_->Connect(&client_transport_); - - ASSERT_TRUE(simulator_.RunUntil([this] { - return client_endpoint_delegate_.session() != nullptr && - client_endpoint_delegate_.session()->IsEncryptionEstablished() && - server_endpoint_delegate_.session() != nullptr && - server_endpoint_delegate_.session()->IsEncryptionEstablished(); - })); - EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(), - server_versions[0]); - EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(), - server_versions[0]); -} - -// Tests that the server can accept connections from clients that use older -// QUIC versions. -TEST_F(QuartcEndpointTest, - QUIC_TEST_DISABLED_IN_CHROME(ServerAcceptsOldVersion)) { - // Reset the client endpoint to only speak version 43. - ParsedQuicVersionVector client_versions; - client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43}); - client_endpoint_ = std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), &client_endpoint_delegate_, - QuartcSessionConfig(), - /*serialized_server_config=*/"", - std::make_unique<QuicVersionManager>(client_versions)); - - // Reset the server endpoint to prefer version 46 but also be capable of - // speaking version 43. - ParsedQuicVersionVector server_versions; - server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46}); - server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43}); - server_endpoint_ = std::make_unique<QuartcServerEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), &server_endpoint_delegate_, - QuartcSessionConfig(), - std::make_unique<QuicVersionManager>(server_versions)); - - // The endpoints should be able to establish a connection using version 46. - server_endpoint_->Connect(&server_transport_); - client_endpoint_->Connect(&client_transport_); - - ASSERT_TRUE(simulator_.RunUntil([this] { - return client_endpoint_delegate_.session() != nullptr && - client_endpoint_delegate_.session()->IsEncryptionEstablished() && - server_endpoint_delegate_.session() != nullptr && - server_endpoint_delegate_.session()->IsEncryptionEstablished(); - })); - EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(), - client_versions[0]); - EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(), - client_versions[0]); -} - -// Tests that version negotiation fails when the client and server support -// completely disjoint sets of versions. -TEST_F(QuartcEndpointTest, - QUIC_TEST_DISABLED_IN_CHROME(VersionNegotiationWithDisjointVersions)) { - // Reset the client endpoint to only speak version 43. - ParsedQuicVersionVector client_versions; - client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43}); - client_endpoint_ = std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), &client_endpoint_delegate_, - QuartcSessionConfig(), - /*serialized_server_config=*/"", - std::make_unique<QuicVersionManager>(client_versions)); - - // Reset the server endpoint to only speak version 46. - ParsedQuicVersionVector server_versions; - server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46}); - server_endpoint_ = std::make_unique<QuartcServerEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), &server_endpoint_delegate_, - QuartcSessionConfig(), - std::make_unique<QuicVersionManager>(server_versions)); - - // The endpoints should be unable to establish a connection. - server_endpoint_->Connect(&server_transport_); - client_endpoint_->Connect(&client_transport_); - - // Note that the error is reported from the client and *not* the server. The - // server sees an invalid version, sends a version negotiation packet, and - // never gets a response, because the client stops sending when it can't find - // a mutually supported versions. - ASSERT_TRUE(simulator_.RunUntil([this] { - return client_endpoint_delegate_.session() != nullptr && - client_endpoint_delegate_.session()->error() != QUIC_NO_ERROR; - })); - EXPECT_THAT(client_endpoint_delegate_.session()->error(), - test::IsError(QUIC_INVALID_VERSION)); -} - -// Tests that the client endpoint can create a new session in order to continue -// version negotiation. -TEST_F(QuartcEndpointTest, - QUIC_TEST_DISABLED_IN_CHROME(CreatesNewSessionWhenRequired)) { - // Reset the client endpoint to prefer version 46 but also be capable of - // speaking version 43. - ParsedQuicVersionVector client_versions; - client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46}); - client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43}); - client_endpoint_ = std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), &client_endpoint_delegate_, - QuartcSessionConfig(), - /*serialized_server_config=*/"", - std::make_unique<QuicVersionManager>(client_versions)); - - // Reset the server endpoint to only speak version 43. - ParsedQuicVersionVector server_versions; - server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43}); - server_endpoint_ = std::make_unique<QuartcServerEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), &server_endpoint_delegate_, - QuartcSessionConfig(), - std::make_unique<QuicVersionManager>(server_versions)); - - // The endpoints should be able to establish a connection using version 46. - server_endpoint_->Connect(&server_transport_); - client_endpoint_->Connect(&client_transport_); - - ASSERT_TRUE(simulator_.RunUntil([this] { - return client_endpoint_delegate_.session() != nullptr && - client_endpoint_delegate_.session()->IsEncryptionEstablished() && - server_endpoint_delegate_.session() != nullptr && - server_endpoint_delegate_.session()->IsEncryptionEstablished(); - })); - EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(), - server_versions[0]); - EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(), - server_versions[0]); - - EXPECT_EQ(2, client_endpoint_delegate_.num_sessions_created()); -} - -} // namespace -} // namespace quic
diff --git a/quic/quartc/quartc_factory.cc b/quic/quartc/quartc_factory.cc deleted file mode 100644 index 280d936..0000000 --- a/quic/quartc/quartc_factory.cc +++ /dev/null
@@ -1,219 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_factory.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" -#include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h" -#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h" -#include "net/third_party/quiche/src/quic/core/uber_received_packet_manager.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -std::unique_ptr<QuartcSession> CreateQuartcClientSession( - const QuartcSessionConfig& quartc_session_config, - const QuicClock* clock, - QuicAlarmFactory* alarm_factory, - QuicConnectionHelperInterface* connection_helper, - const ParsedQuicVersionVector& supported_versions, - quiche::QuicheStringPiece server_crypto_config, - QuartcPacketTransport* packet_transport) { - DCHECK(packet_transport); - - // QuartcSession will eventually own both |writer| and |quic_connection|. - auto writer = std::make_unique<QuartcPacketWriter>( - packet_transport, quartc_session_config.max_packet_size); - - // While the QuicConfig is not directly used by the connection, creating it - // also sets flag values which must be set before creating the connection. - QuicConfig quic_config = CreateQuicConfig(quartc_session_config); - - // |dummy_id| and |dummy_address| are used because Quartc network layer will - // not use these two. - QuicConnectionId dummy_id = QuicUtils::CreateZeroConnectionId( - supported_versions[0].transport_version); - QuicSocketAddress dummy_address(QuicIpAddress::Any4(), /*port=*/0); - std::unique_ptr<QuicConnection> quic_connection = CreateQuicConnection( - dummy_id, dummy_address, connection_helper, alarm_factory, writer.get(), - Perspective::IS_CLIENT, supported_versions); - - // Quartc sets its own ack delay; get that ack delay and copy it over - // to the QuicConfig so that it can be properly advertised to the peer - // via transport parameter negotiation. - quic_config.SetMaxAckDelayToSendMs(quic_connection->received_packet_manager() - .max_ack_delay() - .ToMilliseconds()); - - return std::make_unique<QuartcClientSession>( - std::move(quic_connection), quic_config, supported_versions, clock, - std::move(writer), - CreateCryptoClientConfig(quartc_session_config.pre_shared_key), - server_crypto_config); -} - -void ConfigureGlobalQuicSettings() { - // Ensure that we don't drop data because QUIC streams refuse to buffer it. - // TODO(b/120099046): Replace this with correct handling of WriteMemSlices(). - SetQuicFlag(FLAGS_quic_buffered_data_threshold, - std::numeric_limits<int>::max()); - - // Enable and request QUIC to include receive timestamps in ACK frames. - SetQuicReloadableFlag(quic_send_timestamps, true); - - // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be - // false. - SetQuicReloadableFlag(quic_enable_ack_decimation, false); - - // Note: flag settings have no effect for Exoblaze builds since - // SetQuicReloadableFlag() gets stubbed out. - SetQuicReloadableFlag(quic_unified_iw_options, true); // Enable IWXX opts. - SetQuicReloadableFlag(quic_bbr_flexible_app_limited, true); // Enable BBR9. -} - -QuicConfig CreateQuicConfig(const QuartcSessionConfig& quartc_session_config) { - // TODO(b/124398962): Figure out a better way to initialize QUIC flags. - // Creating a config shouldn't have global side-effects on flags. However, - // this has the advantage of ensuring that flag values stay in sync with the - // options requested by configs, so simply splitting the config and flag - // settings doesn't seem preferable. - ConfigureGlobalQuicSettings(); - - QuicTagVector copt; - copt.push_back(kNSTP); - - // Enable and request QUIC to include receive timestamps in ACK frames. - copt.push_back(kSTMP); - - // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be - // false. - copt.push_back(kAKD2); - - // Use unlimited decimation in order to reduce number of unbundled ACKs. - copt.push_back(kAKDU); - - // Enable time-based loss detection. - copt.push_back(kTIME); - - copt.push_back(kBBR3); // Stay in low-gain until in-flight < BDP. - copt.push_back(kBBR5); // 40 RTT ack aggregation. - copt.push_back(kBBR9); // Ignore app-limited if enough data is in flight. - copt.push_back(kBBQ1); // 2.773 pacing gain in STARTUP. - copt.push_back(kBBQ2); // 2.0 CWND gain in STARTUP. - copt.push_back(k1RTT); // Exit STARTUP after 1 RTT with no gains. - copt.push_back(kIW10); // 10-packet (14600 byte) initial cwnd. - - if (!quartc_session_config.enable_tail_loss_probe) { - copt.push_back(kNTLP); - } - - // TODO(b/112192153): Test and possible enable slower startup when pipe - // filling is ready to use. Slower startup is kBBRS. - - QuicConfig quic_config; - - // Use the limits for the session & stream flow control. The default 16KB - // limit leads to significantly undersending (not reaching BWE on the outgoing - // bitrate) due to blocked frames, and it leads to high latency (and one-way - // delay). Setting it to its limits is not going to cause issues (our streams - // are small generally, and if we were to buffer 24MB it wouldn't be the end - // of the world). We can consider setting different limits in future (e.g. 1MB - // stream, 1.5MB session). It's worth noting that on 1mbps bitrate, limit of - // 24MB can capture approx 4 minutes of the call, and the default increase in - // size of the window (half of the window size) is approximately 2 minutes of - // the call. - quic_config.SetInitialSessionFlowControlWindowToSend( - kSessionReceiveWindowLimit); - quic_config.SetInitialStreamFlowControlWindowToSend( - kStreamReceiveWindowLimit); - quic_config.SetConnectionOptionsToSend(copt); - quic_config.SetClientConnectionOptions(copt); - if (quartc_session_config.max_time_before_crypto_handshake > - QuicTime::Delta::Zero()) { - quic_config.set_max_time_before_crypto_handshake( - quartc_session_config.max_time_before_crypto_handshake); - } - if (quartc_session_config.max_idle_time_before_crypto_handshake > - QuicTime::Delta::Zero()) { - quic_config.set_max_idle_time_before_crypto_handshake( - quartc_session_config.max_idle_time_before_crypto_handshake); - } - if (quartc_session_config.idle_network_timeout > QuicTime::Delta::Zero()) { - quic_config.SetIdleNetworkTimeout( - quartc_session_config.idle_network_timeout); - } - - // The ICE transport provides a unique 5-tuple for each connection. Save - // overhead by omitting the connection id. - quic_config.SetBytesForConnectionIdToSend(0); - - // Allow up to 1000 incoming streams at once. Quartc streams typically contain - // one audio or video frame and close immediately. However, when a video frame - // becomes larger than one packet, there is some delay between the start and - // end of each stream. The default maximum of 100 only leaves about 1 second - // of headroom (Quartc sends ~30 video frames per second) before QUIC starts - // to refuse incoming streams. Back-pressure should clear backlogs of - // incomplete streams, but targets 1 second for recovery. Increasing the - // number of open streams gives sufficient headroom to recover before QUIC - // refuses new streams. - quic_config.SetMaxBidirectionalStreamsToSend(1000); - - return quic_config; -} - -std::unique_ptr<QuicConnection> CreateQuicConnection( - QuicConnectionId connection_id, - const QuicSocketAddress& peer_address, - QuicConnectionHelperInterface* connection_helper, - QuicAlarmFactory* alarm_factory, - QuicPacketWriter* packet_writer, - Perspective perspective, - ParsedQuicVersionVector supported_versions) { - auto quic_connection = std::make_unique<QuicConnection>( - connection_id, peer_address, connection_helper, alarm_factory, - packet_writer, - /*owns_writer=*/false, perspective, supported_versions); - quic_connection->SetMaxPacketLength( - packet_writer->GetMaxPacketSize(peer_address)); - - QuicSentPacketManager& sent_packet_manager = - quic_connection->sent_packet_manager(); - UberReceivedPacketManager& received_packet_manager = - quic_connection->received_packet_manager(); - - // Default delayed ack time is 25ms. - // If data packets are sent less often (e.g. because p-time was modified), - // we would force acks to be sent every 25ms regardless, increasing - // overhead. Since generally we guarantee a packet every 20ms, changing - // this value should have miniscule effect on quality on good connections, - // but on poor connections, changing this number significantly reduced the - // number of ack-only packets. - // The p-time can go up to as high as 120ms, and when it does, it's - // when the low overhead is the most important thing. Ideally it should be - // above 120ms, but it cannot be higher than 0.5*RTO, which equals to 100ms. - received_packet_manager.set_max_ack_delay( - QuicTime::Delta::FromMilliseconds(100)); - sent_packet_manager.set_peer_max_ack_delay( - QuicTime::Delta::FromMilliseconds(100)); - - quic_connection->set_fill_up_link_during_probing(true); - - // We start ack decimation after 15 packets. Typically, we would see - // 1-2 crypto handshake packets, one media packet, and 10 probing packets. - // We want to get acks for the probing packets as soon as possible, - // but we can start using ack decimation right after first probing completes. - // The default was to not start ack decimation for the first 100 packets. - quic_connection->set_min_received_before_ack_decimation(15); - - return quic_connection; -} - -} // namespace quic
diff --git a/quic/quartc/quartc_factory.h b/quic/quartc/quartc_factory.h deleted file mode 100644 index 665b8e7..0000000 --- a/quic/quartc/quartc_factory.h +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_FACTORY_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_FACTORY_H_ - -#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" -#include "net/third_party/quiche/src/quic/core/quic_connection.h" -#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -struct QuartcSessionConfig { - // If a pre-shared cryptographic key is available for this session, specify it - // here. This value will only be used if non-empty. - std::string pre_shared_key; - - // The maximum size of the packet can be written with the packet writer. - // 1200 bytes by default. - QuicPacketLength max_packet_size = 1200; - - // Timeouts for the crypto handshake. Set them to higher values to - // prevent closing the session before it started on a slow network. - // Zero entries are ignored and QUIC defaults are used in that case. - QuicTime::Delta max_idle_time_before_crypto_handshake = - QuicTime::Delta::Zero(); - QuicTime::Delta max_time_before_crypto_handshake = QuicTime::Delta::Zero(); - QuicTime::Delta idle_network_timeout = QuicTime::Delta::Zero(); - - // Tail loss probes (TLP) are enabled by default, but it may be useful to - // disable them in tests. We can also consider disabling them in production - // if we discover that tail loss probes add overhead in low bitrate audio. - bool enable_tail_loss_probe = true; -}; - -// Creates a new QuartcClientSession using the given configuration. -std::unique_ptr<QuartcSession> CreateQuartcClientSession( - const QuartcSessionConfig& quartc_session_config, - const QuicClock* clock, - QuicAlarmFactory* alarm_factory, - QuicConnectionHelperInterface* connection_helper, - const ParsedQuicVersionVector& supported_versions, - quiche::QuicheStringPiece server_crypto_config, - QuartcPacketTransport* packet_transport); - -// Configures global settings, such as supported quic versions. -// Must execute on QUIC thread. -void ConfigureGlobalQuicSettings(); - -// Must execute on QUIC thread. -QuicConfig CreateQuicConfig(const QuartcSessionConfig& quartc_session_config); - -std::unique_ptr<QuicConnection> CreateQuicConnection( - QuicConnectionId connection_id, - const QuicSocketAddress& peer_address, - QuicConnectionHelperInterface* connection_helper, - QuicAlarmFactory* alarm_factory, - QuicPacketWriter* packet_writer, - Perspective perspective, - ParsedQuicVersionVector supported_versions); - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_FACTORY_H_
diff --git a/quic/quartc/quartc_fakes.h b/quic/quartc/quartc_fakes.h deleted file mode 100644 index 774cd09..0000000 --- a/quic/quartc/quartc_fakes.h +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_FAKES_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_FAKES_H_ - -#include <string> - -#include "net/third_party/quiche/src/quic/core/quic_clock.h" -#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -class FakeQuartcEndpointDelegate : public QuartcEndpoint::Delegate { - public: - explicit FakeQuartcEndpointDelegate(QuartcStream::Delegate* stream_delegate, - const QuicClock* clock) - : stream_delegate_(stream_delegate), clock_(clock) {} - - void OnSessionCreated(QuartcSession* session) override { - CHECK_NE(session, nullptr); - session_ = session; - session_->StartCryptoHandshake(); - ++num_sessions_created_; - } - - void OnConnectionWritable() override { - QUIC_LOG(INFO) << "Connection writable!"; - if (!writable_time_.IsInitialized()) { - writable_time_ = clock_->Now(); - } - } - - // Called when peers have established forward-secure encryption - void OnCryptoHandshakeComplete() override { - QUIC_LOG(INFO) << "Crypto handshake complete!"; - crypto_handshake_time_ = clock_->Now(); - } - - // Called when connection closes locally, or remotely by peer. - void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/, - ConnectionCloseSource /*source*/) override { - connected_ = false; - } - - // Called when an incoming QUIC stream is created. - void OnIncomingStream(QuartcStream* quartc_stream) override { - last_incoming_stream_ = quartc_stream; - last_incoming_stream_->SetDelegate(stream_delegate_); - } - - void OnMessageReceived(quiche::QuicheStringPiece message) override { - incoming_messages_.emplace_back(message); - } - - void OnMessageSent(int64_t datagram_id) override { - sent_datagram_ids_.push_back(datagram_id); - } - - void OnMessageAcked(int64_t datagram_id, - QuicTime receive_timestamp) override { - acked_datagram_id_to_receive_timestamp_.emplace(datagram_id, - receive_timestamp); - } - - void OnMessageLost(int64_t datagram_id) override { - lost_datagram_ids_.push_back(datagram_id); - } - - void OnCongestionControlChange(QuicBandwidth /*bandwidth_estimate*/, - QuicBandwidth /*pacing_rate*/, - QuicTime::Delta /*latest_rtt*/) override {} - - QuartcSession* session() { return session_; } - - int num_sessions_created() const { return num_sessions_created_; } - - QuartcStream* last_incoming_stream() const { return last_incoming_stream_; } - - // Returns all received messages. - const std::vector<std::string>& incoming_messages() const { - return incoming_messages_; - } - - // Returns all sent datagram ids in the order sent. - const std::vector<int64_t>& sent_datagram_ids() const { - return sent_datagram_ids_; - } - - // Returns all ACKEd datagram ids in the order ACKs were received. - const std::map<int64_t, QuicTime>& acked_datagram_id_to_receive_timestamp() - const { - return acked_datagram_id_to_receive_timestamp_; - } - - const std::vector<int64_t>& lost_datagram_ids() const { - return lost_datagram_ids_; - } - - bool connected() const { return connected_; } - QuicTime writable_time() const { return writable_time_; } - QuicTime crypto_handshake_time() const { return crypto_handshake_time_; } - - private: - // Current session. - QuartcSession* session_ = nullptr; - - // Number of new sessions created by the endpoint. - int num_sessions_created_ = 0; - - QuartcStream* last_incoming_stream_; - std::vector<std::string> incoming_messages_; - std::vector<int64_t> sent_datagram_ids_; - std::map<int64_t, QuicTime> acked_datagram_id_to_receive_timestamp_; - std::vector<int64_t> lost_datagram_ids_; - bool connected_ = true; - QuartcStream::Delegate* stream_delegate_; - QuicTime writable_time_ = QuicTime::Zero(); - QuicTime crypto_handshake_time_ = QuicTime::Zero(); - const QuicClock* clock_; -}; - -class FakeQuartcStreamDelegate : public QuartcStream::Delegate { - public: - size_t OnReceived(QuartcStream* stream, - iovec* iov, - size_t iov_length, - bool /*fin*/) override { - size_t bytes_consumed = 0; - for (size_t i = 0; i < iov_length; ++i) { - received_data_[stream->id()] += std::string( - static_cast<const char*>(iov[i].iov_base), iov[i].iov_len); - bytes_consumed += iov[i].iov_len; - } - return bytes_consumed; - } - - void OnClose(QuartcStream* stream) override { - errors_[stream->id()] = stream->stream_error(); - } - - void OnBufferChanged(QuartcStream* /*stream*/) override {} - - bool has_data() { return !received_data_.empty(); } - std::map<QuicStreamId, std::string>& data() { return received_data_; } - - QuicRstStreamErrorCode stream_error(QuicStreamId id) { return errors_[id]; } - - private: - std::map<QuicStreamId, std::string> received_data_; - std::map<QuicStreamId, QuicRstStreamErrorCode> errors_; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_FAKES_H_
diff --git a/quic/quartc/quartc_interval_counter.h b/quic/quartc/quartc_interval_counter.h deleted file mode 100644 index fe3b083..0000000 --- a/quic/quartc/quartc_interval_counter.h +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright (c) 2018 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 QUICHE_QUIC_QUARTC_QUARTC_INTERVAL_COUNTER_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_INTERVAL_COUNTER_H_ - -#include <stddef.h> -#include <vector> - -#include "net/third_party/quiche/src/quic/core/quic_interval.h" -#include "net/third_party/quiche/src/quic/core/quic_interval_set.h" - -namespace quic { - -// QuartcIntervalCounter counts the number of times each value appears within -// a set of potentially overlapping intervals. -// -// QuartcIntervalCounter is not intended for widespread use. Consider replacing -// it with a full interval-map if more use cases arise. -// -// QuartcIntervalCounter is only suitable for cases where the maximum count is -// expected to remain low. (For example, counting the number of times the same -// portions of stream data are lost.) It is inefficient when the maximum count -// becomes high. -template <typename T> -class QuartcIntervalCounter { - public: - // Adds |interval| to the counter. The count associated with each value in - // |interval| is incremented by one. |interval| may overlap with previous - // intervals added to the counter. - // - // For each possible value: - // - If the value is present in both |interval| and the counter, the count - // associated with that value is incremented by one. - // - If the value is present in |interval| but not counter, the count - // associated with that value is set to one (incremented from zero). - // - If the value is absent from |interval|, the count is unchanged. - // - // Time complexity is O(|MaxCount| * the complexity of adding an interval to a - // QuicIntervalSet). - void AddInterval(QuicInterval<T> interval); - - // Removes an interval from the counter. This method may be called to prune - // irrelevant intervals from the counter. This is useful to prevent unbounded - // growth. - // - // Time complexity is O(|MaxCount| * the complexity of removing an interval - // from a QuicIntervalSet). - void RemoveInterval(QuicInterval<T> interval); - - // Returns the maximum number of times any single value has appeared in - // intervals added to the counter. - // - // Time complexity is constant. - size_t MaxCount() const { return intervals_by_count_.size(); } - - // Returns the maximum number of times a particular value has appeared in - // intervals added to the counter. - // - // Time complexity is O(|MaxCount| * log(number of non-contiguous intervals)). - size_t Count(const T& value) const; - - private: - // Each entry in this vector represents the intervals of values counted at - // least i + 1 times, where i is the index of the entry. - // - // Whenever an interval is added to the counter, each value in the interval is - // added to the first entry which does not already contain that value. If - // part of an interval is already present in the last entry, a new entry is - // added containing that part. - // - // Note that this means each value present in one of the interval sets will be - // present in all previous sets. - std::vector<QuicIntervalSet<T>> intervals_by_count_; -}; - -template <typename T> -void QuartcIntervalCounter<T>::AddInterval(QuicInterval<T> interval) { - // After the Nth iteration, |leftover| contains the parts of |interval| that - // are already present in the first N entries. These parts of |interval| have - // been added to the counter more than N times. - QuicIntervalSet<T> leftover(interval); - for (auto& intervals : intervals_by_count_) { - QuicIntervalSet<T> tmp = leftover; - leftover.Intersection(intervals); - intervals.Union(tmp); - } - - // Whatever ranges are still in |leftover| are already in all the entries - // Add a new entry containing |leftover|. - if (!leftover.Empty()) { - intervals_by_count_.push_back(leftover); - } -} - -template <typename T> -void QuartcIntervalCounter<T>::RemoveInterval(QuicInterval<T> interval) { - // Remove the interval from each entry in the vector, popping any entries that - // become empty. - for (size_t i = intervals_by_count_.size(); i > 0; --i) { - intervals_by_count_[i - 1].Difference(interval); - if (intervals_by_count_[i - 1].Empty()) { - intervals_by_count_.pop_back(); - } - } -} - -template <typename T> -size_t QuartcIntervalCounter<T>::Count(const T& value) const { - // The index of the last entry containing |value| gives its count. - for (size_t i = intervals_by_count_.size(); i > 0; --i) { - if (intervals_by_count_[i - 1].Contains(value)) { - return i; - } - } - return 0; -} - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_INTERVAL_COUNTER_H_
diff --git a/quic/quartc/quartc_interval_counter_test.cc b/quic/quartc/quartc_interval_counter_test.cc deleted file mode 100644 index 028aaf2..0000000 --- a/quic/quartc/quartc_interval_counter_test.cc +++ /dev/null
@@ -1,108 +0,0 @@ -// Copyright (c) 2018 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/third_party/quiche/src/quic/quartc/quartc_interval_counter.h" - -#include "net/third_party/quiche/src/quic/core/quic_interval.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" - -namespace quic { -namespace { - -class QuartcIntervalCounterTest : public QuicTest { - protected: - QuartcIntervalCounter<int> counter_; -}; - -void ExpectCount(const QuartcIntervalCounter<int>& counter, - QuicInterval<int> interval, - size_t count) { - for (int i = interval.min(); i < interval.max(); ++i) { - EXPECT_EQ(counter.Count(i), count) << "i=" << i; - } -} - -TEST_F(QuartcIntervalCounterTest, InitiallyEmpty) { - EXPECT_EQ(counter_.MaxCount(), 0u); -} - -TEST_F(QuartcIntervalCounterTest, SameInterval) { - counter_.AddInterval(QuicInterval<int>(0, 6)); - EXPECT_EQ(counter_.MaxCount(), 1u); - ExpectCount(counter_, QuicInterval<int>(0, 6), 1); - - counter_.AddInterval(QuicInterval<int>(0, 6)); - EXPECT_EQ(counter_.MaxCount(), 2u); - ExpectCount(counter_, QuicInterval<int>(0, 6), 2); -} - -TEST_F(QuartcIntervalCounterTest, DisjointIntervals) { - counter_.AddInterval(QuicInterval<int>(0, 5)); - EXPECT_EQ(counter_.MaxCount(), 1u); - ExpectCount(counter_, QuicInterval<int>(0, 5), 1); - ExpectCount(counter_, QuicInterval<int>(5, 10), 0); - - counter_.AddInterval(QuicInterval<int>(5, 10)); - EXPECT_EQ(counter_.MaxCount(), 1u); - ExpectCount(counter_, QuicInterval<int>(0, 5), 1); - ExpectCount(counter_, QuicInterval<int>(5, 10), 1); -} - -TEST_F(QuartcIntervalCounterTest, OverlappingIntervals) { - counter_.AddInterval(QuicInterval<int>(0, 6)); - EXPECT_EQ(counter_.MaxCount(), 1u); - ExpectCount(counter_, QuicInterval<int>(0, 6), 1); - ExpectCount(counter_, QuicInterval<int>(6, 10), 0); - - counter_.AddInterval(QuicInterval<int>(5, 10)); - EXPECT_EQ(counter_.MaxCount(), 2u); - ExpectCount(counter_, QuicInterval<int>(0, 5), 1); - EXPECT_EQ(counter_.Count(5), 2u); - ExpectCount(counter_, QuicInterval<int>(6, 10), 1); -} - -TEST_F(QuartcIntervalCounterTest, IntervalsWithGapThenOverlap) { - counter_.AddInterval(QuicInterval<int>(0, 4)); - EXPECT_EQ(counter_.MaxCount(), 1u); - ExpectCount(counter_, QuicInterval<int>(0, 4), 1); - ExpectCount(counter_, QuicInterval<int>(4, 10), 0); - - counter_.AddInterval(QuicInterval<int>(7, 10)); - EXPECT_EQ(counter_.MaxCount(), 1u); - ExpectCount(counter_, QuicInterval<int>(0, 4), 1); - ExpectCount(counter_, QuicInterval<int>(4, 7), 0); - ExpectCount(counter_, QuicInterval<int>(7, 10), 1); - - counter_.AddInterval(QuicInterval<int>(3, 8)); - EXPECT_EQ(counter_.MaxCount(), 2u); - ExpectCount(counter_, QuicInterval<int>(0, 3), 1); - EXPECT_EQ(counter_.Count(3), 2u); - ExpectCount(counter_, QuicInterval<int>(4, 7), 1); - EXPECT_EQ(counter_.Count(7), 2u); - ExpectCount(counter_, QuicInterval<int>(8, 10), 1); -} - -TEST_F(QuartcIntervalCounterTest, RemoveIntervals) { - counter_.AddInterval(QuicInterval<int>(0, 5)); - EXPECT_EQ(counter_.MaxCount(), 1u); - ExpectCount(counter_, QuicInterval<int>(0, 5), 1); - - counter_.AddInterval(QuicInterval<int>(4, 10)); - EXPECT_EQ(counter_.MaxCount(), 2u); - ExpectCount(counter_, QuicInterval<int>(0, 4), 1); - EXPECT_EQ(counter_.Count(4), 2u); - ExpectCount(counter_, QuicInterval<int>(5, 10), 1); - - counter_.RemoveInterval(QuicInterval<int>(0, 5)); - EXPECT_EQ(counter_.MaxCount(), 1u); - ExpectCount(counter_, QuicInterval<int>(0, 5), 0); - ExpectCount(counter_, QuicInterval<int>(5, 10), 1); - - counter_.RemoveInterval(QuicInterval<int>(5, 10)); - EXPECT_EQ(counter_.MaxCount(), 0u); - ExpectCount(counter_, QuicInterval<int>(0, 10), 0); -} - -} // namespace -} // namespace quic
diff --git a/quic/quartc/quartc_multiplexer.cc b/quic/quartc/quartc_multiplexer.cc deleted file mode 100644 index 376fac0..0000000 --- a/quic/quartc/quartc_multiplexer.cc +++ /dev/null
@@ -1,271 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/quartc_multiplexer.h" - -#include <cstdint> -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" -#include "net/third_party/quiche/src/quic/core/quic_data_writer.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -QuartcSendChannel::QuartcSendChannel(QuartcMultiplexer* multiplexer, - uint64_t id, - QuicBufferAllocator* allocator, - Delegate* delegate) - : multiplexer_(multiplexer), - id_(id), - encoded_length_(QuicDataWriter::GetVarInt62Len(id_)), - allocator_(allocator), - delegate_(delegate) {} - -QuartcStream* QuartcSendChannel::CreateOutgoingBidirectionalStream() { - if (!session_) { - QUIC_LOG(DFATAL) << "Session is not ready to write yet; channel_id=" << id_; - return nullptr; - } - QuicMemSlice id_slice = EncodeChannelId(); - - QuartcStream* stream = session_->CreateOutgoingBidirectionalStream(); - QuicConsumedData consumed = - stream->WriteMemSlices(QuicMemSliceSpan(&id_slice), /*fin=*/false); - DCHECK_EQ(consumed.bytes_consumed, encoded_length_); - return stream; -} - -bool QuartcSendChannel::SendOrQueueMessage(QuicMemSliceSpan message, - int64_t datagram_id) { - if (!session_) { - QUIC_LOG(DFATAL) << "Session is not ready to write yet; channel_id=" << id_ - << "datagram size=" << message.total_length(); - return false; - } - QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); // Empty storage. - storage.Append(EncodeChannelId()); - - message.ConsumeAll( - [&storage](QuicMemSlice slice) { storage.Append(std::move(slice)); }); - - // Allocate a unique datagram id so that notifications can be routed back to - // the right send channel. - int64_t unique_datagram_id = multiplexer_->AllocateDatagramId(this); - multiplexer_to_user_datagram_ids_[unique_datagram_id] = datagram_id; - - return session_->SendOrQueueMessage(storage.ToSpan(), unique_datagram_id); -} - -void QuartcSendChannel::OnMessageSent(int64_t datagram_id) { - // Map back to the caller-chosen |datagram_id|. - datagram_id = multiplexer_to_user_datagram_ids_[datagram_id]; - delegate_->OnMessageSent(datagram_id); -} - -void QuartcSendChannel::OnMessageAcked(int64_t datagram_id, - QuicTime receive_timestamp) { - // Map back to the caller-chosen |datagram_id|. - auto it = multiplexer_to_user_datagram_ids_.find(datagram_id); - if (it == multiplexer_to_user_datagram_ids_.end()) { - QUIC_LOG(DFATAL) << "Datagram acked/lost multiple times; datagram_id=" - << datagram_id; - return; - } - delegate_->OnMessageAcked(it->second, receive_timestamp); - multiplexer_to_user_datagram_ids_.erase(it); -} - -void QuartcSendChannel::OnMessageLost(int64_t datagram_id) { - // Map back to the caller-chosen |datagram_id|. - auto it = multiplexer_to_user_datagram_ids_.find(datagram_id); - if (it == multiplexer_to_user_datagram_ids_.end()) { - QUIC_LOG(DFATAL) << "Datagram acked/lost multiple times; datagram_id=" - << datagram_id; - return; - } - delegate_->OnMessageLost(it->second); - multiplexer_to_user_datagram_ids_.erase(it); -} - -void QuartcSendChannel::OnSessionCreated(QuartcSession* session) { - session_ = session; -} - -QuicMemSlice QuartcSendChannel::EncodeChannelId() { - QuicUniqueBufferPtr buffer = MakeUniqueBuffer(allocator_, encoded_length_); - QuicDataWriter writer(encoded_length_, buffer.get()); - writer.WriteVarInt62(id_); - return QuicMemSlice(std::move(buffer), encoded_length_); -} - -QuartcMultiplexer::QuartcMultiplexer( - QuicBufferAllocator* allocator, - QuartcSessionEventDelegate* session_delegate, - QuartcReceiveChannel* default_receive_channel) - : allocator_(allocator), - session_delegate_(session_delegate), - default_receive_channel_(default_receive_channel) { - CHECK_NE(session_delegate_, nullptr); - CHECK_NE(default_receive_channel_, nullptr); -} - -QuartcSendChannel* QuartcMultiplexer::CreateSendChannel( - uint64_t channel_id, - QuartcSendChannel::Delegate* delegate) { - send_channels_.push_back(std::make_unique<QuartcSendChannel>( - this, channel_id, allocator_, delegate)); - if (session_) { - send_channels_.back()->OnSessionCreated(session_); - } - return send_channels_.back().get(); -} - -void QuartcMultiplexer::RegisterReceiveChannel(uint64_t channel_id, - QuartcReceiveChannel* channel) { - if (channel == nullptr) { - receive_channels_.erase(channel_id); - return; - } - auto& registered_channel = receive_channels_[channel_id]; - if (registered_channel) { - QUIC_LOG(DFATAL) << "Attempted to overwrite existing channel_id=" - << channel_id; - return; - } - registered_channel = channel; -} - -int64_t QuartcMultiplexer::AllocateDatagramId(QuartcSendChannel* channel) { - send_channels_by_datagram_id_[next_datagram_id_] = channel; - return next_datagram_id_++; -} - -void QuartcMultiplexer::OnSessionCreated(QuartcSession* session) { - for (auto& channel : send_channels_) { - channel->OnSessionCreated(session); - } - session_ = session; - session_delegate_->OnSessionCreated(session); -} - -void QuartcMultiplexer::OnCryptoHandshakeComplete() { - session_delegate_->OnCryptoHandshakeComplete(); -} - -void QuartcMultiplexer::OnConnectionWritable() { - session_delegate_->OnConnectionWritable(); -} - -void QuartcMultiplexer::OnIncomingStream(QuartcStream* stream) { - stream->SetDelegate(this); -} - -void QuartcMultiplexer::OnCongestionControlChange( - QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) { - session_delegate_->OnCongestionControlChange(bandwidth_estimate, pacing_rate, - latest_rtt); -} - -void QuartcMultiplexer::OnConnectionClosed( - const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) { - session_delegate_->OnConnectionClosed(frame, source); -} - -void QuartcMultiplexer::OnMessageReceived(quiche::QuicheStringPiece message) { - QuicDataReader reader(message); - QuicVariableLengthIntegerLength channel_id_length = - reader.PeekVarInt62Length(); - - uint64_t channel_id; - if (!reader.ReadVarInt62(&channel_id)) { - QUIC_LOG(DFATAL) << "Received message without properly encoded channel id"; - return; - } - - QuartcReceiveChannel* channel = default_receive_channel_; - auto it = receive_channels_.find(channel_id); - if (it != receive_channels_.end()) { - channel = it->second; - } - - channel->OnMessageReceived(channel_id, message.substr(channel_id_length)); -} - -void QuartcMultiplexer::OnMessageSent(int64_t datagram_id) { - auto it = send_channels_by_datagram_id_.find(datagram_id); - if (it == send_channels_by_datagram_id_.end()) { - return; - } - it->second->OnMessageSent(datagram_id); -} - -void QuartcMultiplexer::OnMessageAcked(int64_t datagram_id, - QuicTime receive_timestamp) { - auto it = send_channels_by_datagram_id_.find(datagram_id); - if (it == send_channels_by_datagram_id_.end()) { - return; - } - it->second->OnMessageAcked(datagram_id, receive_timestamp); - send_channels_by_datagram_id_.erase(it); -} - -void QuartcMultiplexer::OnMessageLost(int64_t datagram_id) { - auto it = send_channels_by_datagram_id_.find(datagram_id); - if (it == send_channels_by_datagram_id_.end()) { - return; - } - it->second->OnMessageLost(datagram_id); - send_channels_by_datagram_id_.erase(it); -} - -size_t QuartcMultiplexer::OnReceived(QuartcStream* stream, - iovec* iov, - size_t iov_length, - bool /*fin*/) { - if (iov == nullptr || iov_length <= 0) { - return 0; - } - - QuicDataReader reader(static_cast<char*>(iov[0].iov_base), iov[0].iov_len); - QuicVariableLengthIntegerLength channel_id_length = - reader.PeekVarInt62Length(); - - uint64_t channel_id; - if (reader.BytesRemaining() >= channel_id_length) { - // Fast path, have enough data to read immediately. - if (!reader.ReadVarInt62(&channel_id)) { - return 0; - } - } else { - // Slow path, need to coalesce multiple iovecs. - std::string data; - for (size_t i = 0; i < iov_length; ++i) { - data += std::string(static_cast<char*>(iov[i].iov_base), iov[i].iov_len); - } - QuicDataReader combined_reader(data); - if (!combined_reader.ReadVarInt62(&channel_id)) { - return 0; - } - } - - QuartcReceiveChannel* channel = default_receive_channel_; - auto it = receive_channels_.find(channel_id); - if (it != receive_channels_.end()) { - channel = it->second; - } - channel->OnIncomingStream(channel_id, stream); - return channel_id_length; -} - -void QuartcMultiplexer::OnClose(QuartcStream* /*stream*/) {} - -void QuartcMultiplexer::OnBufferChanged(QuartcStream* /*stream*/) {} - -} // namespace quic
diff --git a/quic/quartc/quartc_multiplexer.h b/quic/quartc/quartc_multiplexer.h deleted file mode 100644 index 1e6c2e5..0000000 --- a/quic/quartc/quartc_multiplexer.h +++ /dev/null
@@ -1,190 +0,0 @@ -// Copyright (c) 2019 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 QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_ - -#include <cstdint> - -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -class QuartcMultiplexer; - -// A single, multiplexed send channel within a Quartc session. A send channel -// wraps send-side operations with an outgoing multiplex id. -class QuartcSendChannel { - public: - class Delegate { - public: - virtual ~Delegate() = default; - - // Called when a message with |datagram_id| is sent by this channel. - virtual void OnMessageSent(int64_t datagram_id) = 0; - - // Called when a message sent on this channel with |datagram_id| is acked. - // |receive_timestamp| indicates when the peer received this message, - // according to the peer's clock. - virtual void OnMessageAcked(int64_t datagram_id, - QuicTime receive_timestamp) = 0; - - // Called when a message sent on this channel with |datagram_id| is lost. - virtual void OnMessageLost(int64_t datagram_id) = 0; - }; - - QuartcSendChannel(QuartcMultiplexer* multiplexer, - uint64_t id, - QuicBufferAllocator* allocator, - Delegate* delegate); - virtual ~QuartcSendChannel() = default; - - // Creates a new, outgoing stream on this channel. - // - // Automatically writes the channel id to the start of the stream. The caller - // SHOULD create a |ScopedPacketFlusher| before calling this function to - // prevent the channel id from being sent by itself. - QuartcStream* CreateOutgoingBidirectionalStream(); - - // Writes |message| to the session. Prepends the channel's send id before any - // following message data. - bool SendOrQueueMessage(QuicMemSliceSpan message, int64_t datagram_id); - - // Gets the current largest message payload for this channel. Returns the - // largest payload size supported by the session minus overhead required to - // encode this channel's send id. - QuicPacketLength GetCurrentLargestMessagePayload() const; - - // The following are called by the multiplexer to deliver message - // notifications. The |datagram_id| passed to these is unique per-message, - // and must be translated back to the sender's chosen datagram_id. - void OnMessageSent(int64_t datagram_id); - void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp); - void OnMessageLost(int64_t datagram_id); - void OnSessionCreated(QuartcSession* session); - - private: - // Creates a mem slice containing a varint-62 encoded channel id. - QuicMemSlice EncodeChannelId(); - - QuartcMultiplexer* const multiplexer_; - const uint64_t id_; - const QuicVariableLengthIntegerLength encoded_length_; - QuicBufferAllocator* const allocator_; - Delegate* const delegate_; - - QuartcSession* session_; - - // Map of multiplexer-chosen to user/caller-specified datagram ids. The user - // may specify any number as a datagram's id. This number does not have to be - // unique across channels (nor even within a single channel). In order - // to demux sent, acked, and lost messages, the multiplexer assigns a globally - // unique id to each message. This map is used to restore the original caller - // datagram id before issuing callbacks. - QuicHashMap<int64_t, int64_t> multiplexer_to_user_datagram_ids_; -}; - -// A single, multiplexed receive channel within a Quartc session. A receive -// channel is a delegate which accepts incoming streams and datagrams on one (or -// more) channel ids. -class QuartcReceiveChannel { - public: - virtual ~QuartcReceiveChannel() = default; - - // Called when a new incoming stream arrives on this channel. - virtual void OnIncomingStream(uint64_t channel_id, QuartcStream* stream) = 0; - - // Called when a message is recieved by this channel. - virtual void OnMessageReceived(uint64_t channel_id, - quiche::QuicheStringPiece message) = 0; -}; - -// Delegate for session-wide events. -class QuartcSessionEventDelegate { - public: - virtual ~QuartcSessionEventDelegate() = default; - - virtual void OnSessionCreated(QuartcSession* session) = 0; - virtual void OnCryptoHandshakeComplete() = 0; - virtual void OnConnectionWritable() = 0; - virtual void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) = 0; - virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) = 0; -}; - -// A multiplexer capable of sending and receiving data on multiple channels. -class QuartcMultiplexer : public QuartcEndpoint::Delegate, - public QuartcStream::Delegate { - public: - // Creates a new multiplexer. |session_delegate| handles all session-wide - // events, while |default_receive_channel| handles incoming data on unknown - // or unregistered channel ids. Neither |session_delegate| nor - // |default_receive_channel| may be nullptr, and both must outlive the - // multiplexer. - QuartcMultiplexer(QuicBufferAllocator* allocator, - QuartcSessionEventDelegate* session_delegate, - QuartcReceiveChannel* default_receive_channel); - - // Creates a new send channel. The channel is owned by the multiplexer, and - // references to it must not outlive the multiplexer. - QuartcSendChannel* CreateSendChannel(uint64_t channel_id, - QuartcSendChannel::Delegate* delegate); - - // Registers a receiver for incoming data on |channel_id|. - void RegisterReceiveChannel(uint64_t channel_id, - QuartcReceiveChannel* channel); - - // Allocates a datagram id to |channel|. - int64_t AllocateDatagramId(QuartcSendChannel* channel); - - // QuartcEndpoint::Delegate overrides. - void OnSessionCreated(QuartcSession* session) override; - - // QuartcSession::Delegate overrides. - void OnCryptoHandshakeComplete() override; - void OnConnectionWritable() override; - void OnIncomingStream(QuartcStream* stream) override; - void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) override; - void OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) override; - void OnMessageReceived(quiche::QuicheStringPiece message) override; - void OnMessageSent(int64_t datagram_id) override; - void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp) override; - void OnMessageLost(int64_t datagram_id) override; - - // QuartcStream::Delegate overrides. - size_t OnReceived(QuartcStream* stream, - iovec* iov, - size_t iov_length, - bool fin) override; - void OnClose(QuartcStream* stream) override; - void OnBufferChanged(QuartcStream* stream) override; - - private: - QuicBufferAllocator* const allocator_; - QuartcSessionEventDelegate* const session_delegate_; - - QuartcSession* session_ = nullptr; - std::vector<std::unique_ptr<QuartcSendChannel>> send_channels_; - QuicHashMap<uint64_t, QuartcReceiveChannel*> receive_channels_; - QuartcReceiveChannel* default_receive_channel_ = nullptr; - - int64_t next_datagram_id_ = 1; - QuicHashMap<int64_t, QuartcSendChannel*> send_channels_by_datagram_id_; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_
diff --git a/quic/quartc/quartc_multiplexer_test.cc b/quic/quartc/quartc_multiplexer_test.cc deleted file mode 100644 index 024b67d..0000000 --- a/quic/quartc/quartc_multiplexer_test.cc +++ /dev/null
@@ -1,496 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/quartc_multiplexer.h" - -#include <memory> -#include <utility> - -#include "net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h" -#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" -#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h" -#include "net/third_party/quiche/src/quic/quartc/counting_packet_filter.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h" -#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace { - -using ::testing::ElementsAreArray; -using ::testing::Gt; -using ::testing::IsEmpty; -using ::testing::Pair; - -constexpr QuicTime::Delta kPropagationDelay = - QuicTime::Delta::FromMilliseconds(10); - -class FakeSessionEventDelegate : public QuartcSessionEventDelegate { - public: - void OnSessionCreated(QuartcSession* session) override { - session->StartCryptoHandshake(); - session_ = session; - } - - void OnConnectionWritable() override { ++writable_count_; } - - void OnCryptoHandshakeComplete() override { ++handshake_count_; } - - void OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) override { - error_ = frame.quic_error_code; - close_source_ = source; - } - - void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) override { - latest_bandwidth_estimate_ = bandwidth_estimate; - latest_pacing_rate_ = pacing_rate; - latest_rtt_ = latest_rtt; - } - - QuartcSession* session() { return session_; } - int writable_count() const { return writable_count_; } - int handshake_count() const { return handshake_count_; } - QuicErrorCode error() const { return error_; } - ConnectionCloseSource close_source() const { return close_source_; } - QuicBandwidth latest_bandwidth_estimate() const { - return latest_bandwidth_estimate_; - } - QuicBandwidth latest_pacing_rate() const { return latest_pacing_rate_; } - QuicTime::Delta latest_rtt() const { return latest_rtt_; } - - private: - QuartcSession* session_ = nullptr; - int writable_count_ = 0; - int handshake_count_ = 0; - QuicErrorCode error_ = QUIC_NO_ERROR; - ConnectionCloseSource close_source_; - QuicBandwidth latest_bandwidth_estimate_ = QuicBandwidth::Zero(); - QuicBandwidth latest_pacing_rate_ = QuicBandwidth::Zero(); - QuicTime::Delta latest_rtt_ = QuicTime::Delta::Zero(); -}; - -class FakeSendDelegate : public QuartcSendChannel::Delegate { - public: - void OnMessageSent(int64_t datagram_id) override { - datagrams_sent_.push_back(datagram_id); - } - - void OnMessageAcked(int64_t datagram_id, - QuicTime receive_timestamp) override { - datagrams_acked_.push_back({datagram_id, receive_timestamp}); - } - - void OnMessageLost(int64_t datagram_id) override { - datagrams_lost_.push_back(datagram_id); - } - - const std::vector<int64_t>& datagrams_sent() const { return datagrams_sent_; } - const std::vector<std::pair<int64_t, QuicTime>>& datagrams_acked() const { - return datagrams_acked_; - } - const std::vector<int64_t>& datagrams_lost() const { return datagrams_lost_; } - - private: - std::vector<int64_t> datagrams_sent_; - std::vector<std::pair<int64_t, QuicTime>> datagrams_acked_; - std::vector<int64_t> datagrams_lost_; -}; - -class FakeReceiveDelegate : public QuartcReceiveChannel, - public QuartcStream::Delegate { - public: - const std::vector<std::pair<uint64_t, std::string>> messages_received() - const { - return messages_received_; - } - - void OnIncomingStream(uint64_t channel_id, QuartcStream* stream) override { - stream->SetDelegate(this); - stream_to_channel_id_[stream] = channel_id; - } - - void OnMessageReceived(uint64_t channel_id, - quiche::QuicheStringPiece message) override { - messages_received_.emplace_back(channel_id, message); - } - - // Stream delegate overrides. - size_t OnReceived(QuartcStream* stream, - iovec* iov, - size_t iov_length, - bool fin) override { - if (!fin) { - return 0; - } - - size_t bytes = 0; - std::string message; - for (size_t i = 0; i < iov_length; ++i) { - message += - std::string(static_cast<char*>(iov[i].iov_base), iov[i].iov_len); - bytes += iov[i].iov_len; - } - QUIC_LOG(INFO) << "Received " << bytes << " byte message on channel " - << stream_to_channel_id_[stream]; - messages_received_.emplace_back(stream_to_channel_id_[stream], message); - return bytes; - } - - void OnClose(QuartcStream* stream) override { - stream_to_channel_id_.erase(stream); - } - - void OnBufferChanged(QuartcStream* /*stream*/) override {} - - private: - std::vector<std::pair<uint64_t, std::string>> messages_received_; - QuicUnorderedMap<QuartcStream*, uint64_t> stream_to_channel_id_; -}; - -class QuartcMultiplexerTest : public QuicTest { - public: - QuartcMultiplexerTest() - : simulator_(), - client_transport_(&simulator_, - "client_transport", - "server_transport", - 10 * kDefaultMaxPacketSize), - server_transport_(&simulator_, - "server_transport", - "client_transport", - 10 * kDefaultMaxPacketSize), - client_filter_(&simulator_, "client_filter", &client_transport_), - client_server_link_(&client_filter_, - &server_transport_, - QuicBandwidth::FromKBitsPerSecond(10 * 1000), - kPropagationDelay), - client_multiplexer_(simulator_.GetStreamSendBufferAllocator(), - &client_session_delegate_, - &client_default_receiver_), - server_multiplexer_(simulator_.GetStreamSendBufferAllocator(), - &server_session_delegate_, - &server_default_receiver_), - client_endpoint_(std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), - simulator_.GetClock(), - simulator_.GetRandomGenerator(), - &client_multiplexer_, - quic::QuartcSessionConfig(), - /*serialized_server_config=*/"")), - server_endpoint_(std::make_unique<QuartcServerEndpoint>( - simulator_.GetAlarmFactory(), - simulator_.GetClock(), - simulator_.GetRandomGenerator(), - &server_multiplexer_, - quic::QuartcSessionConfig())) { - // TODO(b/150224094): Re-enable TLS handshake. - // TODO(b/150236522): Parametrize by QUIC version. - quic::test::DisableQuicVersionsWithTls(); - } - - void Connect() { - client_endpoint_->Connect(&client_transport_); - server_endpoint_->Connect(&server_transport_); - ASSERT_TRUE(simulator_.RunUntil([this]() { - return client_session_delegate_.writable_count() > 0 && - server_session_delegate_.writable_count() > 0; - })); - } - - void Disconnect() { - client_session_delegate_.session()->CloseConnection("test"); - server_session_delegate_.session()->CloseConnection("test"); - } - - protected: - QuartcMultiplexer* client_multiplexer() { return &client_multiplexer_; } - - QuartcMultiplexer* server_multiplexer() { return &server_multiplexer_; } - - simulator::Simulator simulator_; - - simulator::SimulatedQuartcPacketTransport client_transport_; - simulator::SimulatedQuartcPacketTransport server_transport_; - simulator::CountingPacketFilter client_filter_; - simulator::SymmetricLink client_server_link_; - - FakeSessionEventDelegate client_session_delegate_; - FakeSessionEventDelegate server_session_delegate_; - - FakeReceiveDelegate client_default_receiver_; - FakeReceiveDelegate server_default_receiver_; - - QuartcMultiplexer client_multiplexer_; - QuartcMultiplexer server_multiplexer_; - - std::unique_ptr<QuartcClientEndpoint> client_endpoint_; - std::unique_ptr<QuartcServerEndpoint> server_endpoint_; -}; - -TEST_F(QuartcMultiplexerTest, MultiplexMessages) { - Connect(); - - FakeSendDelegate send_delegate_1; - QuartcSendChannel* send_channel_1 = - client_multiplexer()->CreateSendChannel(1, &send_delegate_1); - FakeSendDelegate send_delegate_2; - QuartcSendChannel* send_channel_2 = - client_multiplexer()->CreateSendChannel(2, &send_delegate_2); - - FakeReceiveDelegate receive_delegate_1; - server_multiplexer()->RegisterReceiveChannel(1, &receive_delegate_1); - - int num_messages = 10; - std::vector<std::pair<uint64_t, std::string>> messages_1; - messages_1.reserve(num_messages); - std::vector<std::pair<uint64_t, std::string>> messages_2; - messages_2.reserve(num_messages); - std::vector<int64_t> messages_sent_1; - std::vector<int64_t> messages_sent_2; - std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers_1; - std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers_2; - for (int i = 0; i < num_messages; ++i) { - messages_1.emplace_back(1, quiche::QuicheStrCat("message for 1: ", i)); - test::QuicTestMemSliceVector slice_1( - {std::make_pair(const_cast<char*>(messages_1.back().second.data()), - messages_1.back().second.size())}); - send_channel_1->SendOrQueueMessage(slice_1.span(), i); - messages_sent_1.push_back(i); - ack_matchers_1.push_back(Pair(i, Gt(QuicTime::Zero()))); - - messages_2.emplace_back(2, quiche::QuicheStrCat("message for 2: ", i)); - test::QuicTestMemSliceVector slice_2( - {std::make_pair(const_cast<char*>(messages_2.back().second.data()), - messages_2.back().second.size())}); - // Use i + 5 as the datagram id for channel 2, so that some of the ids - // overlap and some are disjoint. - send_channel_2->SendOrQueueMessage(slice_2.span(), i + 5); - messages_sent_2.push_back(i + 5); - ack_matchers_2.push_back(Pair(i + 5, Gt(QuicTime::Zero()))); - } - - EXPECT_TRUE(simulator_.RunUntil([&send_delegate_1, &send_delegate_2]() { - return send_delegate_1.datagrams_acked().size() == 10 && - send_delegate_2.datagrams_acked().size() == 10; - })); - - EXPECT_EQ(send_delegate_1.datagrams_sent(), messages_sent_1); - EXPECT_EQ(send_delegate_2.datagrams_sent(), messages_sent_2); - - EXPECT_EQ(receive_delegate_1.messages_received(), messages_1); - EXPECT_EQ(server_default_receiver_.messages_received(), messages_2); - - EXPECT_THAT(send_delegate_1.datagrams_acked(), - ElementsAreArray(ack_matchers_1)); - EXPECT_THAT(send_delegate_2.datagrams_acked(), - ElementsAreArray(ack_matchers_2)); -} - -TEST_F(QuartcMultiplexerTest, MultiplexStreams) { - FakeSendDelegate send_delegate_1; - QuartcSendChannel* send_channel_1 = - client_multiplexer()->CreateSendChannel(1, &send_delegate_1); - FakeSendDelegate send_delegate_2; - QuartcSendChannel* send_channel_2 = - client_multiplexer()->CreateSendChannel(2, &send_delegate_2); - - FakeQuartcStreamDelegate fake_send_stream_delegate; - - FakeReceiveDelegate receive_delegate_1; - server_multiplexer()->RegisterReceiveChannel(1, &receive_delegate_1); - - Connect(); - - int num_messages = 10; - std::vector<std::pair<uint64_t, std::string>> messages_1; - messages_1.reserve(num_messages); - std::vector<std::pair<uint64_t, std::string>> messages_2; - messages_2.reserve(num_messages); - for (int i = 0; i < num_messages; ++i) { - messages_1.emplace_back(1, quiche::QuicheStrCat("message for 1: ", i)); - test::QuicTestMemSliceVector slice_1( - {std::make_pair(const_cast<char*>(messages_1.back().second.data()), - messages_1.back().second.size())}); - QuartcStream* stream_1 = - send_channel_1->CreateOutgoingBidirectionalStream(); - stream_1->SetDelegate(&fake_send_stream_delegate); - stream_1->WriteMemSlices(slice_1.span(), /*fin=*/true); - - messages_2.emplace_back(2, quiche::QuicheStrCat("message for 2: ", i)); - test::QuicTestMemSliceVector slice_2( - {std::make_pair(const_cast<char*>(messages_2.back().second.data()), - messages_2.back().second.size())}); - QuartcStream* stream_2 = - send_channel_2->CreateOutgoingBidirectionalStream(); - stream_2->SetDelegate(&fake_send_stream_delegate); - stream_2->WriteMemSlices(slice_2.span(), /*fin=*/true); - } - - EXPECT_TRUE(simulator_.RunUntilOrTimeout( - [this, &receive_delegate_1]() { - return receive_delegate_1.messages_received().size() == 10 && - server_default_receiver_.messages_received().size() == 10; - }, - QuicTime::Delta::FromSeconds(5))); - - EXPECT_EQ(receive_delegate_1.messages_received(), messages_1); - EXPECT_EQ(server_default_receiver_.messages_received(), messages_2); -} - -// Tests that datagram-lost callbacks are invoked on the right send channel -// delegate, and that they work with overlapping datagram ids. -TEST_F(QuartcMultiplexerTest, MultiplexLostDatagrams) { - Connect(); - ASSERT_TRUE(simulator_.RunUntil([this]() { - return client_session_delegate_.handshake_count() > 0 && - server_session_delegate_.handshake_count() > 0; - })); - - // Just drop everything we try to send. - client_filter_.set_packets_to_drop(30); - - FakeSendDelegate send_delegate_1; - QuartcSendChannel* send_channel_1 = - client_multiplexer()->CreateSendChannel(1, &send_delegate_1); - FakeSendDelegate send_delegate_2; - QuartcSendChannel* send_channel_2 = - client_multiplexer()->CreateSendChannel(2, &send_delegate_2); - - FakeQuartcStreamDelegate fake_send_stream_delegate; - - FakeReceiveDelegate receive_delegate_1; - server_multiplexer()->RegisterReceiveChannel(1, &receive_delegate_1); - - int num_messages = 10; - std::vector<std::pair<uint64_t, std::string>> messages_1; - messages_1.reserve(num_messages); - std::vector<std::pair<uint64_t, std::string>> messages_2; - messages_2.reserve(num_messages); - std::vector<int64_t> messages_sent_1; - std::vector<int64_t> messages_sent_2; - for (int i = 0; i < num_messages; ++i) { - messages_1.emplace_back(1, quiche::QuicheStrCat("message for 1: ", i)); - test::QuicTestMemSliceVector slice_1( - {std::make_pair(const_cast<char*>(messages_1.back().second.data()), - messages_1.back().second.size())}); - send_channel_1->SendOrQueueMessage(slice_1.span(), i); - messages_sent_1.push_back(i); - - messages_2.emplace_back(2, quiche::QuicheStrCat("message for 2: ", i)); - test::QuicTestMemSliceVector slice_2( - {std::make_pair(const_cast<char*>(messages_2.back().second.data()), - messages_2.back().second.size())}); - // Use i + 5 as the datagram id for channel 2, so that some of the ids - // overlap and some are disjoint. - send_channel_2->SendOrQueueMessage(slice_2.span(), i + 5); - messages_sent_2.push_back(i + 5); - } - - // Now send something retransmittable to prompt loss detection. - // If we never send anything retransmittable, we will never get acks, and - // never detect losses. - messages_1.emplace_back( - 1, quiche::QuicheStrCat("message for 1: ", num_messages)); - test::QuicTestMemSliceVector slice( - {std::make_pair(const_cast<char*>(messages_1.back().second.data()), - messages_1.back().second.size())}); - QuartcStream* stream_1 = send_channel_1->CreateOutgoingBidirectionalStream(); - stream_1->SetDelegate(&fake_send_stream_delegate); - stream_1->WriteMemSlices(slice.span(), /*fin=*/true); - - EXPECT_TRUE(simulator_.RunUntilOrTimeout( - [&send_delegate_1, &send_delegate_2]() { - return send_delegate_1.datagrams_lost().size() == 10 && - send_delegate_2.datagrams_lost().size() == 10; - }, - QuicTime::Delta::FromSeconds(60))); - - EXPECT_EQ(send_delegate_1.datagrams_lost(), messages_sent_1); - EXPECT_EQ(send_delegate_2.datagrams_lost(), messages_sent_2); - - EXPECT_THAT(send_delegate_1.datagrams_acked(), IsEmpty()); - EXPECT_THAT(send_delegate_2.datagrams_acked(), IsEmpty()); - - EXPECT_THAT(receive_delegate_1.messages_received(), IsEmpty()); - EXPECT_THAT(server_default_receiver_.messages_received(), IsEmpty()); -} - -TEST_F(QuartcMultiplexerTest, UnregisterReceiveChannel) { - Connect(); - - FakeSendDelegate send_delegate; - QuartcSendChannel* send_channel = - client_multiplexer()->CreateSendChannel(1, &send_delegate); - FakeQuartcStreamDelegate fake_send_stream_delegate; - - FakeReceiveDelegate receive_delegate; - server_multiplexer()->RegisterReceiveChannel(1, &receive_delegate); - server_multiplexer()->RegisterReceiveChannel(1, nullptr); - - int num_messages = 10; - std::vector<std::pair<uint64_t, std::string>> messages; - messages.reserve(num_messages); - std::vector<int64_t> messages_sent; - std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers; - for (int i = 0; i < num_messages; ++i) { - messages.emplace_back(1, quiche::QuicheStrCat("message for 1: ", i)); - test::QuicTestMemSliceVector slice( - {std::make_pair(const_cast<char*>(messages.back().second.data()), - messages.back().second.size())}); - send_channel->SendOrQueueMessage(slice.span(), i); - messages_sent.push_back(i); - ack_matchers.push_back(Pair(i, Gt(QuicTime::Zero()))); - } - - EXPECT_TRUE(simulator_.RunUntil([&send_delegate]() { - return send_delegate.datagrams_acked().size() == 10; - })); - - EXPECT_EQ(send_delegate.datagrams_sent(), messages_sent); - EXPECT_EQ(server_default_receiver_.messages_received(), messages); - EXPECT_THAT(send_delegate.datagrams_acked(), ElementsAreArray(ack_matchers)); -} - -TEST_F(QuartcMultiplexerTest, CloseEvent) { - Connect(); - Disconnect(); - - EXPECT_THAT(client_session_delegate_.error(), - test::IsError(QUIC_CONNECTION_CANCELLED)); - EXPECT_THAT(server_session_delegate_.error(), - test::IsError(QUIC_CONNECTION_CANCELLED)); -} - -TEST_F(QuartcMultiplexerTest, CongestionEvent) { - Connect(); - ASSERT_TRUE(simulator_.RunUntil([this]() { - return client_session_delegate_.handshake_count() > 0 && - server_session_delegate_.handshake_count() > 0; - })); - - EXPECT_GT(client_session_delegate_.latest_bandwidth_estimate(), - QuicBandwidth::Zero()); - EXPECT_GT(client_session_delegate_.latest_pacing_rate(), - QuicBandwidth::Zero()); - EXPECT_GT(client_session_delegate_.latest_rtt(), QuicTime::Delta::Zero()); -} - -} // namespace -} // namespace quic
diff --git a/quic/quartc/quartc_packet_writer.cc b/quic/quartc/quartc_packet_writer.cc deleted file mode 100644 index 3923c22..0000000 --- a/quic/quartc/quartc_packet_writer.cc +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_packet_writer.h" - -#include <utility> - -namespace quic { - -std::unique_ptr<PerPacketOptions> QuartcPerPacketOptions::Clone() const { - return std::make_unique<QuartcPerPacketOptions>(*this); -} - -QuartcPacketWriter::QuartcPacketWriter(QuartcPacketTransport* packet_transport, - QuicByteCount max_packet_size) - : packet_transport_(packet_transport), max_packet_size_(max_packet_size) {} - -WriteResult QuartcPacketWriter::WritePacket( - const char* buffer, - size_t buf_len, - const QuicIpAddress& /*self_address*/, - const QuicSocketAddress& /*peer_address*/, - PerPacketOptions* options) { - DCHECK(packet_transport_); - - QuartcPacketTransport::PacketInfo info; - QuartcPerPacketOptions* quartc_options = - static_cast<QuartcPerPacketOptions*>(options); - if (quartc_options && quartc_options->connection) { - info.packet_number = - quartc_options->connection->packet_creator().packet_number(); - } - int bytes_written = packet_transport_->Write(buffer, buf_len, info); - if (bytes_written <= 0) { - writable_ = false; - return WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK); - } - return WriteResult(WRITE_STATUS_OK, bytes_written); -} - -bool QuartcPacketWriter::IsWriteBlocked() const { - return !writable_; -} - -QuicByteCount QuartcPacketWriter::GetMaxPacketSize( - const QuicSocketAddress& /*peer_address*/) const { - return max_packet_size_; -} - -void QuartcPacketWriter::SetWritable() { - writable_ = true; -} - -bool QuartcPacketWriter::SupportsReleaseTime() const { - return false; -} - -bool QuartcPacketWriter::IsBatchMode() const { - return false; -} - -QuicPacketBuffer QuartcPacketWriter::GetNextWriteLocation( - const QuicIpAddress& /*self_address*/, - const QuicSocketAddress& /*peer_address*/) { - return {nullptr, nullptr}; -} - -WriteResult QuartcPacketWriter::Flush() { - return WriteResult(WRITE_STATUS_OK, 0); -} - -void QuartcPacketWriter::SetPacketTransportDelegate( - QuartcPacketTransport::Delegate* delegate) { - packet_transport_->SetDelegate(delegate); -} - -} // namespace quic
diff --git a/quic/quartc/quartc_packet_writer.h b/quic/quartc/quartc_packet_writer.h deleted file mode 100644 index a59344c..0000000 --- a/quic/quartc/quartc_packet_writer.h +++ /dev/null
@@ -1,114 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_ - -#include "net/third_party/quiche/src/quic/core/quic_connection.h" -#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" - -namespace quic { - -// Send and receive packets, like a virtual UDP socket. For example, this -// could be implemented by WebRTC's IceTransport. -class QuartcPacketTransport { - public: - // Additional metadata provided for each packet written. - struct PacketInfo { - QuicPacketNumber packet_number; - }; - - // Delegate for packet transport callbacks. Note that the delegate is not - // thread-safe. Packet transport implementations must ensure that callbacks - // are synchronized with all other work done by QUIC. - class Delegate { - public: - virtual ~Delegate() = default; - - // Called whenever the transport can write. - virtual void OnTransportCanWrite() = 0; - - // Called when the transport receives a packet. - virtual void OnTransportReceived(const char* data, size_t data_len) = 0; - }; - - virtual ~QuartcPacketTransport() {} - - // Called by the QuartcPacketWriter when writing packets to the network. - // Return the number of written bytes. Return 0 if the write is blocked. - virtual int Write(const char* buffer, - size_t buf_len, - const PacketInfo& info) = 0; - - // Sets the delegate which must be called when the transport can write or - // a packet is received. QUIC sets |delegate| to a nonnull pointer when it - // is ready to process incoming packets and sets |delegate| to nullptr before - // QUIC is deleted. Implementations may assume |delegate| remains valid until - // it is set to nullptr. - virtual void SetDelegate(Delegate* delegate) = 0; -}; - -struct QuartcPerPacketOptions : public PerPacketOptions { - std::unique_ptr<PerPacketOptions> Clone() const override; - - // The connection which is sending this packet. - QuicConnection* connection = nullptr; -}; - -// Implements a QuicPacketWriter using a QuartcPacketTransport, which allows a -// QuicConnection to use (for example), a WebRTC IceTransport. -class QuartcPacketWriter : public QuicPacketWriter { - public: - QuartcPacketWriter(QuartcPacketTransport* packet_transport, - QuicByteCount max_packet_size); - ~QuartcPacketWriter() override {} - - // The QuicConnection calls WritePacket and the QuicPacketWriter writes them - // to the QuartcSession::PacketTransport. - WriteResult WritePacket(const char* buffer, - size_t buf_len, - const QuicIpAddress& self_address, - const QuicSocketAddress& peer_address, - PerPacketOptions* options) override; - - // Whether the underneath |transport_| is blocked. If this returns true, - // outgoing QUIC packets are queued by QuicConnection until SetWritable() is - // called. - bool IsWriteBlocked() const override; - - // Maximum size of the QUIC packet which can be written. Users such as WebRTC - // can set the value through the QuartcFactoryConfig without updating the QUIC - // code. - QuicByteCount GetMaxPacketSize( - const QuicSocketAddress& peer_address) const override; - - // Sets the packet writer to a writable (non-blocked) state. - void SetWritable() override; - - bool SupportsReleaseTime() const override; - - bool IsBatchMode() const override; - - QuicPacketBuffer GetNextWriteLocation( - const QuicIpAddress& self_address, - const QuicSocketAddress& peer_address) override; - - WriteResult Flush() override; - - void SetPacketTransportDelegate(QuartcPacketTransport::Delegate* delegate); - - private: - // QuartcPacketWriter will not own the transport. - QuartcPacketTransport* packet_transport_; - // The maximum size of the packet can be written by this writer. - QuicByteCount max_packet_size_; - - // Whether packets can be written. - bool writable_ = true; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_
diff --git a/quic/quartc/quartc_session.cc b/quic/quartc/quartc_session.cc deleted file mode 100644 index 3709267..0000000 --- a/quic/quartc/quartc_session.cc +++ /dev/null
@@ -1,469 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_session.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h" -#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace { - -// Arbitrary server port number for net::QuicCryptoClientConfig. -const int kQuicServerPort = 0; - -} // namespace - -QuartcSession::QuartcSession(std::unique_ptr<QuicConnection> connection, - Visitor* visitor, - const QuicConfig& config, - const ParsedQuicVersionVector& supported_versions, - const QuicClock* clock) - : QuicSession(connection.get(), - visitor, - config, - supported_versions, - /*num_expected_unidirectional_static_streams = */ 0), - connection_(std::move(connection)), - clock_(clock), - per_packet_options_(std::make_unique<QuartcPerPacketOptions>()) { - per_packet_options_->connection = connection_.get(); - connection_->set_per_packet_options(per_packet_options_.get()); -} - -QuartcSession::~QuartcSession() {} - -QuartcStream* QuartcSession::CreateOutgoingBidirectionalStream() { - // Use default priority for incoming QUIC streams. - // TODO(zhihuang): Determine if this value is correct. - return ActivateDataStream(CreateDataStream( - GetNextOutgoingBidirectionalStreamId(), QuicStream::kDefaultPriority)); -} - -bool QuartcSession::SendOrQueueMessage(QuicMemSliceSpan message, - int64_t datagram_id) { - if (!CanSendMessage()) { - QUIC_LOG(ERROR) << "Quic session does not support SendMessage"; - return false; - } - - if (message.total_length() > GetCurrentLargestMessagePayload()) { - QUIC_LOG(ERROR) << "Message is too big, message_size=" - << message.total_length() - << ", GetCurrentLargestMessagePayload=" - << GetCurrentLargestMessagePayload(); - return false; - } - - // There may be other messages in send queue, so we have to add message - // to the queue and call queue processing helper. - QueuedMessage queued_message; - queued_message.datagram_id = datagram_id; - message.ConsumeAll([&queued_message](QuicMemSlice slice) { - queued_message.message.Append(std::move(slice)); - }); - send_message_queue_.push_back(std::move(queued_message)); - - ProcessSendMessageQueue(); - - return true; -} - -void QuartcSession::ProcessSendMessageQueue() { - QuicConnection::ScopedPacketFlusher flusher(connection()); - while (!send_message_queue_.empty()) { - QueuedMessage& it = send_message_queue_.front(); - QuicMemSliceSpan span = it.message.ToSpan(); - const size_t message_size = span.total_length(); - MessageResult result = SendMessage(span); - - // Handle errors. - switch (result.status) { - case MESSAGE_STATUS_SUCCESS: { - QUIC_VLOG(1) << "Quartc message sent, message_id=" << result.message_id - << ", message_size=" << message_size; - - auto element = message_to_datagram_id_.find(result.message_id); - - DCHECK(element == message_to_datagram_id_.end()) - << "Mapped message_id already exists, message_id=" - << result.message_id << ", datagram_id=" << element->second; - - message_to_datagram_id_[result.message_id] = it.datagram_id; - - // Notify that datagram was sent. - session_delegate_->OnMessageSent(it.datagram_id); - } break; - - // If connection is congestion controlled or not writable yet, stop - // send loop and we'll retry again when we get OnCanWrite notification. - case MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED: - case MESSAGE_STATUS_BLOCKED: - QUIC_VLOG(1) << "Quartc message not sent because connection is blocked" - << ", message will be retried later, status=" - << result.status << ", message_size=" << message_size; - - return; - - // Other errors are unexpected. We do not propagate error to Quartc, - // because writes can be delayed. - case MESSAGE_STATUS_UNSUPPORTED: - case MESSAGE_STATUS_TOO_LARGE: - case MESSAGE_STATUS_INTERNAL_ERROR: - QUIC_DLOG(DFATAL) - << "Failed to send quartc message due to unexpected error" - << ", message will not be retried, status=" << result.status - << ", message_size=" << message_size; - break; - } - - send_message_queue_.pop_front(); - } -} - -void QuartcSession::OnCanWrite() { - // TODO(b/119640244): Since we currently use messages for audio and streams - // for video, it makes sense to process queued messages first, then call quic - // core OnCanWrite, which will resend queued streams. Long term we may need - // better solution especially if quic connection is used for both data and - // media. - - // Process quartc messages that were previously blocked. - ProcessSendMessageQueue(); - - QuicSession::OnCanWrite(); -} - -bool QuartcSession::SendProbingData() { - if (QuicSession::SendProbingData()) { - return true; - } - - // Set transmission type to PROBING_RETRANSMISSION such that the packets will - // be padded to full. - SetTransmissionType(PROBING_RETRANSMISSION); - // TODO(mellem): this sent PING will be retransmitted if it is lost which is - // not ideal. Consider to send stream data as probing data instead. - SendPing(); - return true; -} - -void QuartcSession::SetDefaultEncryptionLevel(EncryptionLevel level) { - QuicSession::SetDefaultEncryptionLevel(level); - switch (level) { - case ENCRYPTION_INITIAL: - break; - case ENCRYPTION_ZERO_RTT: - if (connection()->perspective() == Perspective::IS_CLIENT) { - DCHECK(IsEncryptionEstablished()); - DCHECK(session_delegate_); - session_delegate_->OnConnectionWritable(); - } - break; - case ENCRYPTION_HANDSHAKE: - break; - case ENCRYPTION_FORWARD_SECURE: - // On the server, handshake confirmed is the first time when you can start - // writing packets. - DCHECK(IsEncryptionEstablished()); - DCHECK(OneRttKeysAvailable()); - - DCHECK(session_delegate_); - session_delegate_->OnConnectionWritable(); - session_delegate_->OnCryptoHandshakeComplete(); - break; - default: - QUIC_BUG << "Unknown encryption level: " << level; - } -} - -void QuartcSession::OnOneRttKeysAvailable() { - QuicSession::OnOneRttKeysAvailable(); - // On the server, handshake confirmed is the first time when you can start - // writing packets. - DCHECK(IsEncryptionEstablished()); - DCHECK(OneRttKeysAvailable()); - - DCHECK(session_delegate_); - session_delegate_->OnConnectionWritable(); - session_delegate_->OnCryptoHandshakeComplete(); -} - -void QuartcSession::CancelStream(QuicStreamId stream_id) { - ResetQuartcStream(stream_id, QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED); -} - -void QuartcSession::ResetQuartcStream(QuicStreamId stream_id, - QuicRstStreamErrorCode error) { - if (!IsOpenStream(stream_id)) { - return; - } - QuicStream* stream = QuicSession::GetOrCreateStream(stream_id); - if (stream) { - stream->Reset(error); - } -} - -void QuartcSession::OnCongestionWindowChange(QuicTime /*now*/) { - DCHECK(session_delegate_); - const RttStats* rtt_stats = connection_->sent_packet_manager().GetRttStats(); - - QuicBandwidth bandwidth_estimate = - connection_->sent_packet_manager().BandwidthEstimate(); - - QuicByteCount in_flight = - connection_->sent_packet_manager().GetBytesInFlight(); - QuicBandwidth pacing_rate = - connection_->sent_packet_manager().GetSendAlgorithm()->PacingRate( - in_flight); - - session_delegate_->OnCongestionControlChange(bandwidth_estimate, pacing_rate, - rtt_stats->latest_rtt()); -} - -bool QuartcSession::ShouldKeepConnectionAlive() const { - // TODO(mellem): Quartc may want different keepalive logic than HTTP. - return GetNumActiveStreams() > 0; -} - -void QuartcSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) { - QuicSession::OnConnectionClosed(frame, source); - DCHECK(session_delegate_); - session_delegate_->OnConnectionClosed(frame, source); -} - -void QuartcSession::CloseConnection(const std::string& details) { - connection_->CloseConnection( - QuicErrorCode::QUIC_CONNECTION_CANCELLED, details, - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); -} - -void QuartcSession::SetDelegate(Delegate* session_delegate) { - if (session_delegate_) { - QUIC_LOG(WARNING) << "The delegate for the session has already been set."; - } - session_delegate_ = session_delegate; - DCHECK(session_delegate_); -} - -void QuartcSession::OnTransportCanWrite() { - connection()->writer()->SetWritable(); - if (HasDataToWrite()) { - connection()->OnCanWrite(); - } -} - -void QuartcSession::OnTransportReceived(const char* data, size_t data_len) { - QuicReceivedPacket packet(data, data_len, clock_->Now()); - ProcessUdpPacket(connection()->self_address(), connection()->peer_address(), - packet); -} - -void QuartcSession::OnMessageReceived(quiche::QuicheStringPiece message) { - session_delegate_->OnMessageReceived(message); -} - -void QuartcSession::OnMessageAcked(QuicMessageId message_id, - QuicTime receive_timestamp) { - auto element = message_to_datagram_id_.find(message_id); - - if (element == message_to_datagram_id_.end()) { - return; - } - - session_delegate_->OnMessageAcked(/*datagram_id=*/element->second, - receive_timestamp); - - // Free up space -- we should never see message_id again. - message_to_datagram_id_.erase(element); -} - -void QuartcSession::OnMessageLost(QuicMessageId message_id) { - auto it = message_to_datagram_id_.find(message_id); - if (it == message_to_datagram_id_.end()) { - return; - } - - session_delegate_->OnMessageLost(/*datagram_id=*/it->second); - - // Free up space. - message_to_datagram_id_.erase(it); -} - -QuicStream* QuartcSession::CreateIncomingStream(QuicStreamId id) { - return ActivateDataStream(CreateDataStream(id, QuicStream::kDefaultPriority)); -} - -QuicStream* QuartcSession::CreateIncomingStream(PendingStream* /*pending*/) { - QUIC_NOTREACHED(); - return nullptr; -} - -std::unique_ptr<QuartcStream> QuartcSession::CreateDataStream( - QuicStreamId id, - spdy::SpdyPriority priority) { - if (GetCryptoStream() == nullptr || - !GetCryptoStream()->encryption_established()) { - // Encryption not active so no stream created - return nullptr; - } - return InitializeDataStream(std::make_unique<QuartcStream>(id, this), - priority); -} - -std::unique_ptr<QuartcStream> QuartcSession::InitializeDataStream( - std::unique_ptr<QuartcStream> stream, - spdy::SpdyPriority priority) { - // Register the stream to the QuicWriteBlockedList. |priority| is clamped - // between 0 and 7, with 0 being the highest priority and 7 the lowest - // priority. - write_blocked_streams()->UpdateStreamPriority( - stream->id(), spdy::SpdyStreamPrecedence(priority)); - - if (IsIncomingStream(stream->id())) { - DCHECK(session_delegate_); - // Incoming streams need to be registered with the session_delegate_. - session_delegate_->OnIncomingStream(stream.get()); - } - return stream; -} - -QuartcStream* QuartcSession::ActivateDataStream( - std::unique_ptr<QuartcStream> stream) { - // Transfer ownership of the data stream to the session via ActivateStream(). - QuartcStream* raw = stream.release(); - if (raw) { - // Make QuicSession take ownership of the stream. - ActivateStream(std::unique_ptr<QuicStream>(raw)); - } - return raw; -} - -QuartcClientSession::QuartcClientSession( - std::unique_ptr<QuicConnection> connection, - const QuicConfig& config, - const ParsedQuicVersionVector& supported_versions, - const QuicClock* clock, - std::unique_ptr<QuartcPacketWriter> packet_writer, - std::unique_ptr<QuicCryptoClientConfig> client_crypto_config, - quiche::QuicheStringPiece server_crypto_config) - : QuartcSession(std::move(connection), - /*visitor=*/nullptr, - config, - supported_versions, - clock), - packet_writer_(std::move(packet_writer)), - client_crypto_config_(std::move(client_crypto_config)), - server_config_(server_crypto_config) { - DCHECK_EQ(QuartcSession::connection()->perspective(), Perspective::IS_CLIENT); -} - -QuartcClientSession::~QuartcClientSession() { - // The client session is the packet transport delegate, so it must be unset - // before the session is deleted. - packet_writer_->SetPacketTransportDelegate(nullptr); -} - -void QuartcClientSession::Initialize() { - DCHECK(crypto_stream_) << "Do not call QuartcSession::Initialize(), call " - "StartCryptoHandshake() instead."; - QuartcSession::Initialize(); - - // QUIC is ready to process incoming packets after Initialize(). - // Set the packet transport delegate to begin receiving packets. - packet_writer_->SetPacketTransportDelegate(this); -} - -const QuicCryptoStream* QuartcClientSession::GetCryptoStream() const { - return crypto_stream_.get(); -} - -QuicCryptoStream* QuartcClientSession::GetMutableCryptoStream() { - return crypto_stream_.get(); -} - -void QuartcClientSession::StartCryptoHandshake() { - QuicServerId server_id(/*host=*/"", kQuicServerPort, - /*privacy_mode_enabled=*/false); - - if (!server_config_.empty()) { - QuicCryptoServerConfig::ConfigOptions options; - - std::string error; - QuicWallTime now = clock()->WallNow(); - QuicCryptoClientConfig::CachedState::ServerConfigState result = - client_crypto_config_->LookupOrCreate(server_id)->SetServerConfig( - server_config_, now, - /*expiry_time=*/now.Add(QuicTime::Delta::Infinite()), &error); - - if (result == QuicCryptoClientConfig::CachedState::SERVER_CONFIG_VALID) { - DCHECK_EQ(error, ""); - client_crypto_config_->LookupOrCreate(server_id)->SetProof( - std::vector<std::string>{kDummyCertName}, /*cert_sct=*/"", - /*chlo_hash=*/"", /*signature=*/"anything"); - } else { - QUIC_LOG(DFATAL) << "Unable to set server config, error=" << error; - } - } - - crypto_stream_ = std::make_unique<QuicCryptoClientStream>( - server_id, this, - client_crypto_config_->proof_verifier()->CreateDefaultContext(), - client_crypto_config_.get(), this, /*has_application_state = */ true); - Initialize(); - crypto_stream_->CryptoConnect(); -} - -void QuartcClientSession::OnProofValid( - const QuicCryptoClientConfig::CachedState& /*cached*/) { - // TODO(zhihuang): Handle the proof verification. -} - -void QuartcClientSession::OnProofVerifyDetailsAvailable( - const ProofVerifyDetails& /*verify_details*/) { - // TODO(zhihuang): Handle the proof verification. -} - -QuartcServerSession::QuartcServerSession( - std::unique_ptr<QuicConnection> connection, - Visitor* visitor, - const QuicConfig& config, - const ParsedQuicVersionVector& supported_versions, - const QuicClock* clock, - const QuicCryptoServerConfig* server_crypto_config, - QuicCompressedCertsCache* const compressed_certs_cache, - QuicCryptoServerStreamBase::Helper* const stream_helper) - : QuartcSession(std::move(connection), - visitor, - config, - supported_versions, - clock), - server_crypto_config_(server_crypto_config), - compressed_certs_cache_(compressed_certs_cache), - stream_helper_(stream_helper) { - DCHECK_EQ(QuartcSession::connection()->perspective(), Perspective::IS_SERVER); -} - -const QuicCryptoStream* QuartcServerSession::GetCryptoStream() const { - return crypto_stream_.get(); -} - -QuicCryptoStream* QuartcServerSession::GetMutableCryptoStream() { - return crypto_stream_.get(); -} - -void QuartcServerSession::StartCryptoHandshake() { - crypto_stream_ = CreateCryptoServerStream( - server_crypto_config_, compressed_certs_cache_, this, stream_helper_); - Initialize(); -} - -} // namespace quic
diff --git a/quic/quartc/quartc_session.h b/quic/quartc/quartc_session.h deleted file mode 100644 index 66ddfc3..0000000 --- a/quic/quartc/quartc_session.h +++ /dev/null
@@ -1,339 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_SESSION_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_SESSION_H_ - -#include <memory> -#include <string> - -#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h" -#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h" -#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" -#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/core/quic_session.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -// QuartcSession owns and manages a QUIC connection. -class QuartcSession : public QuicSession, - public QuartcPacketTransport::Delegate { - public: - QuartcSession(std::unique_ptr<QuicConnection> connection, - Visitor* visitor, - const QuicConfig& config, - const ParsedQuicVersionVector& supported_versions, - const QuicClock* clock); - QuartcSession(const QuartcSession&) = delete; - QuartcSession& operator=(const QuartcSession&) = delete; - ~QuartcSession() override; - - // QuicSession overrides. - QuartcStream* CreateOutgoingBidirectionalStream(); - - // Sends short unreliable message using quic message frame (message must fit - // in one quic packet). If connection is blocked by congestion control, - // message will be queued and resent later after receiving an OnCanWrite - // notification. - // - // Message size must be <= GetLargestMessagePayload(). - // - // Supported in quic version 45 or later. - // - // Returns false and logs error if message is too long or session does not - // support SendMessage API. Other unexpected errors during send will not be - // returned, because messages can be sent later if connection is congestion - // controlled. - // - // |datagram_id| is used to notify when message was sent in - // Delegate::OnMessageSent. - // - // TODO(sukhanov): We can not use QUIC message ID for notifications, because - // QUIC does not take ownership of messages and if connection is congestion - // controlled, message is not sent and does not get message id until it is - // sent successfully. It also creates problem of flow control between - // messages and streams if they are used together. We discussed it with QUIC - // team and there are multiple solutions, but for now we have to use our - // own datagram identification. - bool SendOrQueueMessage(QuicMemSliceSpan message, int64_t datagram_id); - - // Returns largest message payload acceptable in SendQuartcMessage. - QuicPacketLength GetCurrentLargestMessagePayload() const { - return connection()->GetCurrentLargestMessagePayload(); - } - - // Return true if transport support message frame. - bool CanSendMessage() const { - return VersionSupportsMessageFrames(transport_version()); - } - - void SetDefaultEncryptionLevel(EncryptionLevel level) override; - void OnOneRttKeysAvailable() override; - - // QuicConnectionVisitorInterface overrides. - void OnCongestionWindowChange(QuicTime now) override; - bool ShouldKeepConnectionAlive() const override; - - void OnCanWrite() override; - bool SendProbingData() override; - - void OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) override; - - // QuartcSession methods. - virtual void StartCryptoHandshake() = 0; - - // Closes the connection with the given human-readable error details. - // The connection closes with the QUIC_CONNECTION_CANCELLED error code to - // indicate the application closed it. - // - // Informs the peer that the connection has been closed. This prevents the - // peer from waiting until the connection times out. - // - // Cleans up the underlying QuicConnection's state. Closing the connection - // makes it safe to delete the QuartcSession. - void CloseConnection(const std::string& details); - - // If the given stream is still open, sends a reset frame to cancel it. - // Note: This method cancels a stream by QuicStreamId rather than by pointer - // (or by a method on QuartcStream) because QuartcSession (and not - // the caller) owns the streams. Streams may finish and be deleted before the - // caller tries to cancel them, rendering the caller's pointers invalid. - void CancelStream(QuicStreamId stream_id); - - // Callbacks called by the QuartcSession to notify the user of the - // QuartcSession of certain events. - class Delegate { - public: - virtual ~Delegate() {} - - // Called when the crypto handshake is complete. Crypto handshake on the - // client is only completed _after_ SHLO is received, but we can actually - // start sending media data right after CHLO is sent. - virtual void OnCryptoHandshakeComplete() = 0; - - // Connection can be writable even before crypto handshake is complete. - // In particular, on the client, we can start sending data after sending - // full CHLO, without waiting for SHLO. This reduces a send delay by 1-rtt. - // - // This may be called multiple times. - virtual void OnConnectionWritable() = 0; - - // Called when a new stream is received from the remote endpoint. - virtual void OnIncomingStream(QuartcStream* stream) = 0; - - // Called when network parameters change in response to an ack frame. - virtual void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) = 0; - - // Called when the connection is closed. This means all of the streams will - // be closed and no new streams can be created. - virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) = 0; - - // Called when message (sent as SendMessage) is received. - virtual void OnMessageReceived(quiche::QuicheStringPiece message) = 0; - - // Called when message is sent to QUIC. - // - // Takes into account delay due to congestion control, but does not take - // into account any additional socket delays. - // - // Passed |datagram_id| is the same used in SendOrQueueMessage. - // - // TODO(sukhanov): We can take into account socket delay, but it's not clear - // if it's worth doing if we eventually plan to move congestion control to - // QUIC in QRTP model. If we need to do it, mellem@ thinks it's fairly - // strtaightforward: QUIC does not know about socket delay, but ICE does. We - // can tell ICE the QUIC packet number for each packet sent, and it will - // echo it back to us when the packet actually goes out. We just need to - // plumb that signal up to RTP's congestion control. - virtual void OnMessageSent(int64_t datagram_id) = 0; - - // Called when message with |datagram_id| gets acked. |receive_timestamp| - // indicates when the peer received this message, according to its own - // clock. - virtual void OnMessageAcked(int64_t datagram_id, - QuicTime receive_timestamp) = 0; - - // Called when message with |datagram_id| is lost. - virtual void OnMessageLost(int64_t datagram_id) = 0; - - // TODO(zhihuang): Add proof verification. - }; - - // The |delegate| is not owned by QuartcSession. - void SetDelegate(Delegate* session_delegate); - - // Called when CanWrite() changes from false to true. - void OnTransportCanWrite() override; - - // Called when a packet has been received and should be handled by the - // QuicConnection. - void OnTransportReceived(const char* data, size_t data_len) override; - - void OnMessageReceived(quiche::QuicheStringPiece message) override; - - // Called when message with |message_id| gets acked. - void OnMessageAcked(QuicMessageId message_id, - QuicTime receive_timestamp) override; - - void OnMessageLost(QuicMessageId message_id) override; - - // Returns number of queued (not sent) messages submitted by - // SendOrQueueMessage. Messages are queued if connection is congestion - // controlled. - size_t send_message_queue_size() const { return send_message_queue_.size(); } - - protected: - // QuicSession override. - QuicStream* CreateIncomingStream(QuicStreamId id) override; - QuicStream* CreateIncomingStream(PendingStream* pending) override; - - std::unique_ptr<QuartcStream> CreateDataStream(QuicStreamId id, - spdy::SpdyPriority priority); - // Activates a QuartcStream. The session takes ownership of the stream, but - // returns an unowned pointer to the stream for convenience. - QuartcStream* ActivateDataStream(std::unique_ptr<QuartcStream> stream); - - void ResetQuartcStream(QuicStreamId stream_id, QuicRstStreamErrorCode error); - - const QuicClock* clock() { return clock_; } - - private: - std::unique_ptr<QuartcStream> InitializeDataStream( - std::unique_ptr<QuartcStream> stream, - spdy::SpdyPriority priority); - - // Holds message until it's sent. - struct QueuedMessage { - QueuedMessage() : message(nullptr, 0, nullptr, 0), datagram_id(0) {} - - QuicMemSliceStorage message; - int64_t datagram_id; - }; - - void ProcessSendMessageQueue(); - - // Take ownership of the QuicConnection. Note: if |connection_| changes, - // the new value of |connection_| must be given to |packet_writer_| before any - // packets are written. Otherwise, |packet_writer_| will crash. - std::unique_ptr<QuicConnection> connection_; - - // For recording packet receipt time - const QuicClock* clock_; - - // Not owned by QuartcSession. - Delegate* session_delegate_ = nullptr; - - // Options passed to the packet writer for each packet. - std::unique_ptr<QuartcPerPacketOptions> per_packet_options_; - - // Queue of pending messages sent by SendQuartcMessage that were not sent - // yet or blocked by congestion control. Messages are queued in the order - // of sent by SendOrQueueMessage(). - QuicCircularDeque<QueuedMessage> send_message_queue_; - - // Maps message ids to datagram ids, so we could translate message ACKs - // received from QUIC to datagram ACKs that are propagated up the stack. - QuicHashMap<QuicMessageId, int64_t> message_to_datagram_id_; -}; - -class QuartcClientSession : public QuartcSession, - public QuicCryptoClientStream::ProofHandler { - public: - QuartcClientSession( - std::unique_ptr<QuicConnection> connection, - const QuicConfig& config, - const ParsedQuicVersionVector& supported_versions, - const QuicClock* clock, - std::unique_ptr<QuartcPacketWriter> packet_writer, - std::unique_ptr<QuicCryptoClientConfig> client_crypto_config, - quiche::QuicheStringPiece server_crypto_config); - QuartcClientSession(const QuartcClientSession&) = delete; - QuartcClientSession& operator=(const QuartcClientSession&) = delete; - - ~QuartcClientSession() override; - - // Initialize should not be called on a QuartcSession. Instead, call - // StartCryptoHandshake(). - // TODO(mellem): Move creation of the crypto stream into Initialize() and - // remove StartCryptoHandshake() to bring QuartcSession in line with other - // implementations of QuicSession, which can be started by calling - // Initialize(). - void Initialize() override; - - // Accessors for the client crypto stream. - QuicCryptoStream* GetMutableCryptoStream() override; - const QuicCryptoStream* GetCryptoStream() const override; - - // Initializes the session and sends a handshake. - void StartCryptoHandshake() override; - - // ProofHandler overrides. - void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override; - - // Called by the client crypto handshake when proof verification details - // become available, either because proof verification is complete, or when - // cached details are used. - void OnProofVerifyDetailsAvailable( - const ProofVerifyDetails& verify_details) override; - - private: - // Packet writer used by |connection_|. - std::unique_ptr<QuartcPacketWriter> packet_writer_; - - // Config for QUIC crypto stream. - std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_; - - // Client perspective crypto stream. - std::unique_ptr<QuicCryptoClientStream> crypto_stream_; - - const std::string server_config_; -}; - -class QuartcServerSession : public QuartcSession { - public: - QuartcServerSession(std::unique_ptr<QuicConnection> connection, - Visitor* visitor, - const QuicConfig& config, - const ParsedQuicVersionVector& supported_versions, - const QuicClock* clock, - const QuicCryptoServerConfig* server_crypto_config, - QuicCompressedCertsCache* const compressed_certs_cache, - QuicCryptoServerStreamBase::Helper* const stream_helper); - QuartcServerSession(const QuartcServerSession&) = delete; - QuartcServerSession& operator=(const QuartcServerSession&) = delete; - - // Accessors for the server crypto stream. - QuicCryptoStream* GetMutableCryptoStream() override; - const QuicCryptoStream* GetCryptoStream() const override; - - // Initializes the session and prepares to receive a handshake. - void StartCryptoHandshake() override; - - private: - // Config for QUIC crypto stream. - const QuicCryptoServerConfig* server_crypto_config_; - - // Used by QUIC crypto server stream to track most recently compressed certs. - QuicCompressedCertsCache* const compressed_certs_cache_; - - // This helper is needed to create QuicCryptoServerStream. - QuicCryptoServerStreamBase::Helper* const stream_helper_; - - // Server perspective crypto stream. - std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_SESSION_H_
diff --git a/quic/quartc/quartc_session_test.cc b/quic/quartc/quartc_session_test.cc deleted file mode 100644 index 96f6a0c..0000000 --- a/quic/quartc/quartc_session_test.cc +++ /dev/null
@@ -1,684 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_session.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_clock.h" -#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h" -#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h" -#include "net/third_party/quiche/src/quic/quartc/counting_packet_filter.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" -#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -namespace { - -using ::testing::ElementsAre; -using ::testing::ElementsAreArray; -using ::testing::Gt; -using ::testing::Pair; - -constexpr QuicTime::Delta kPropagationDelay = - QuicTime::Delta::FromMilliseconds(10); -// Propagation delay and a bit, but no more than full RTT. -constexpr QuicTime::Delta kPropagationDelayAndABit = - QuicTime::Delta::FromMilliseconds(12); - -static QuicByteCount kDefaultMaxPacketSize = 1200; - -test::QuicTestMemSliceVector CreateMemSliceVector( - quiche::QuicheStringPiece data) { - return test::QuicTestMemSliceVector( - {std::pair<char*, size_t>(const_cast<char*>(data.data()), data.size())}); -} - -class QuartcSessionTest : public QuicTest { - public: - QuartcSessionTest() { - SetQuicReloadableFlag(quic_bw_sampler_app_limited_starting_value, true); - } - ~QuartcSessionTest() override {} - - void Init(bool create_client_endpoint = true) { - // TODO(b/150224094): Re-enable TLS handshake. - // TODO(b/150236522): Parametrize by QUIC version. - quic::test::DisableQuicVersionsWithTls(); - - client_transport_ = - std::make_unique<simulator::SimulatedQuartcPacketTransport>( - &simulator_, "client_transport", "server_transport", - 10 * kDefaultMaxPacketSize); - server_transport_ = - std::make_unique<simulator::SimulatedQuartcPacketTransport>( - &simulator_, "server_transport", "client_transport", - 10 * kDefaultMaxPacketSize); - - client_filter_ = std::make_unique<simulator::CountingPacketFilter>( - &simulator_, "client_filter", client_transport_.get()); - - client_server_link_ = std::make_unique<simulator::SymmetricLink>( - client_filter_.get(), server_transport_.get(), - QuicBandwidth::FromKBitsPerSecond(10 * 1000), kPropagationDelay); - - client_stream_delegate_ = std::make_unique<FakeQuartcStreamDelegate>(); - client_session_delegate_ = std::make_unique<FakeQuartcEndpointDelegate>( - client_stream_delegate_.get(), simulator_.GetClock()); - - server_stream_delegate_ = std::make_unique<FakeQuartcStreamDelegate>(); - server_session_delegate_ = std::make_unique<FakeQuartcEndpointDelegate>( - server_stream_delegate_.get(), simulator_.GetClock()); - - // No 0-rtt setup, because server config is empty. - // CannotCreateDataStreamBeforeHandshake depends on 1-rtt setup. - if (create_client_endpoint) { - client_endpoint_ = std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), client_session_delegate_.get(), - quic::QuartcSessionConfig(), - /*serialized_server_config=*/""); - } - server_endpoint_ = std::make_unique<QuartcServerEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), server_session_delegate_.get(), - quic::QuartcSessionConfig()); - } - - // Note that input session config will apply to both server and client. - // Perspective and packet_transport will be overwritten. - void CreateClientAndServerSessions( - const QuartcSessionConfig& /*session_config*/, - bool init = true) { - if (init) { - Init(); - } - - server_endpoint_->Connect(server_transport_.get()); - client_endpoint_->Connect(client_transport_.get()); - - CHECK(simulator_.RunUntil([this] { - return client_session_delegate_->session() != nullptr && - server_session_delegate_->session() != nullptr; - })); - - client_peer_ = client_session_delegate_->session(); - server_peer_ = server_session_delegate_->session(); - } - - // Runs all tasks scheduled in the next 200 ms. - void RunTasks() { simulator_.RunFor(QuicTime::Delta::FromMilliseconds(200)); } - - void AwaitHandshake() { - simulator_.RunUntil([this] { - return client_peer_->OneRttKeysAvailable() && - server_peer_->OneRttKeysAvailable(); - }); - } - - // Test handshake establishment and sending/receiving of data for two - // directions. - void TestSendReceiveStreams() { - ASSERT_TRUE(server_peer_->OneRttKeysAvailable()); - ASSERT_TRUE(client_peer_->OneRttKeysAvailable()); - ASSERT_TRUE(server_peer_->IsEncryptionEstablished()); - ASSERT_TRUE(client_peer_->IsEncryptionEstablished()); - - // Now we can establish encrypted outgoing stream. - QuartcStream* outgoing_stream = - server_peer_->CreateOutgoingBidirectionalStream(); - QuicStreamId stream_id = outgoing_stream->id(); - ASSERT_NE(nullptr, outgoing_stream); - EXPECT_TRUE(server_peer_->ShouldKeepConnectionAlive()); - - outgoing_stream->SetDelegate(server_stream_delegate_.get()); - - // Send a test message from peer 1 to peer 2. - test::QuicTestMemSliceVector data = CreateMemSliceVector("Hello"); - outgoing_stream->WriteMemSlices(data.span(), /*fin=*/false); - RunTasks(); - - // Wait for peer 2 to receive messages. - ASSERT_TRUE(client_stream_delegate_->has_data()); - - QuartcStream* incoming = client_session_delegate_->last_incoming_stream(); - ASSERT_TRUE(incoming); - EXPECT_EQ(incoming->id(), stream_id); - EXPECT_TRUE(client_peer_->ShouldKeepConnectionAlive()); - - EXPECT_EQ(client_stream_delegate_->data()[stream_id], "Hello"); - // Send a test message from peer 2 to peer 1. - test::QuicTestMemSliceVector response = CreateMemSliceVector("Response"); - incoming->WriteMemSlices(response.span(), /*fin=*/false); - RunTasks(); - // Wait for peer 1 to receive messages. - ASSERT_TRUE(server_stream_delegate_->has_data()); - - EXPECT_EQ(server_stream_delegate_->data()[stream_id], "Response"); - } - - // Test sending/receiving of messages for two directions. - void TestSendReceiveMessage() { - ASSERT_TRUE(server_peer_->CanSendMessage()); - ASSERT_TRUE(client_peer_->CanSendMessage()); - - // Disable probing retransmissions such that the first message from either - // side can be sent without being queued. - client_peer_->connection()->set_fill_up_link_during_probing(false); - server_peer_->connection()->set_fill_up_link_during_probing(false); - - int64_t server_datagram_id = 111; - int64_t client_datagram_id = 222; - - // Send message from peer 1 to peer 2. - test::QuicTestMemSliceVector message = - CreateMemSliceVector("Message from server"); - ASSERT_TRUE( - server_peer_->SendOrQueueMessage(message.span(), server_datagram_id)); - - // First message in each direction should not be queued. - EXPECT_EQ(server_peer_->send_message_queue_size(), 0u); - - // Wait for peer 2 to receive message. - RunTasks(); - - EXPECT_THAT(client_session_delegate_->incoming_messages(), - testing::ElementsAre("Message from server")); - - EXPECT_THAT(server_session_delegate_->sent_datagram_ids(), - testing::ElementsAre(server_datagram_id)); - - EXPECT_THAT( - server_session_delegate_->acked_datagram_id_to_receive_timestamp(), - ElementsAre(Pair(server_datagram_id, Gt(QuicTime::Zero())))); - - // Send message from peer 2 to peer 1. - message = CreateMemSliceVector("Message from client"); - ASSERT_TRUE( - client_peer_->SendOrQueueMessage(message.span(), client_datagram_id)); - - // First message in each direction should not be queued. - EXPECT_EQ(client_peer_->send_message_queue_size(), 0u); - - // Wait for peer 1 to receive message. - RunTasks(); - - EXPECT_THAT(server_session_delegate_->incoming_messages(), - testing::ElementsAre("Message from client")); - - EXPECT_THAT(client_session_delegate_->sent_datagram_ids(), - testing::ElementsAre(client_datagram_id)); - - EXPECT_THAT( - client_session_delegate_->acked_datagram_id_to_receive_timestamp(), - ElementsAre(Pair(client_datagram_id, Gt(QuicTime::Zero())))); - } - - // Test for sending multiple messages that also result in queueing. - // This is one-way test, which is run in given direction. - void TestSendReceiveQueuedMessages(bool direction_from_server) { - // Send until queue_size number of messages are queued. - constexpr size_t queue_size = 10; - - ASSERT_TRUE(server_peer_->CanSendMessage()); - ASSERT_TRUE(client_peer_->CanSendMessage()); - - QuartcSession* const peer_sending = - direction_from_server ? server_peer_ : client_peer_; - - FakeQuartcEndpointDelegate* const delegate_receiving = - direction_from_server ? client_session_delegate_.get() - : server_session_delegate_.get(); - - FakeQuartcEndpointDelegate* const delegate_sending = - direction_from_server ? server_session_delegate_.get() - : client_session_delegate_.get(); - - // There should be no messages in the queue before we start sending. - EXPECT_EQ(peer_sending->send_message_queue_size(), 0u); - - // Send messages from peer 1 to peer 2 until required number of messages - // are queued in unsent message queue. - std::vector<std::string> sent_messages; - std::vector<int64_t> sent_datagram_ids; - int64_t current_datagram_id = 0; - while (peer_sending->send_message_queue_size() < queue_size) { - sent_messages.push_back(quiche::QuicheStrCat("Sending message, index=", - sent_messages.size())); - ASSERT_TRUE(peer_sending->SendOrQueueMessage( - CreateMemSliceVector(sent_messages.back()).span(), - current_datagram_id)); - - sent_datagram_ids.push_back(current_datagram_id); - ++current_datagram_id; - } - - // Wait for peer 2 to receive all messages. - RunTasks(); - - std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers; - for (int64_t id : sent_datagram_ids) { - ack_matchers.push_back(Pair(id, Gt(QuicTime::Zero()))); - } - EXPECT_EQ(delegate_receiving->incoming_messages(), sent_messages); - EXPECT_EQ(delegate_sending->sent_datagram_ids(), sent_datagram_ids); - EXPECT_THAT(delegate_sending->acked_datagram_id_to_receive_timestamp(), - ElementsAreArray(ack_matchers)); - } - - // Test sending long messages: - // - message of maximum allowed length should succeed - // - message of > maximum allowed length should fail. - void TestSendLongMessage() { - ASSERT_TRUE(server_peer_->CanSendMessage()); - ASSERT_TRUE(client_peer_->CanSendMessage()); - - // Send message of maximum allowed length. - std::string message_max_long = - std::string(server_peer_->GetCurrentLargestMessagePayload(), 'A'); - test::QuicTestMemSliceVector message = - CreateMemSliceVector(message_max_long); - ASSERT_TRUE( - server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/0)); - - // Send long message which should fail. - std::string message_too_long = - std::string(server_peer_->GetCurrentLargestMessagePayload() + 1, 'B'); - message = CreateMemSliceVector(message_too_long); - ASSERT_FALSE( - server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/0)); - - // Wait for peer 2 to receive message. - RunTasks(); - - // Client should only receive one message of allowed length. - EXPECT_THAT(client_session_delegate_->incoming_messages(), - testing::ElementsAre(message_max_long)); - } - - // Test that client and server are not connected after handshake failure. - void TestDisconnectAfterFailedHandshake() { - EXPECT_TRUE(!client_session_delegate_->connected()); - EXPECT_TRUE(!server_session_delegate_->connected()); - - EXPECT_FALSE(client_peer_->IsEncryptionEstablished()); - EXPECT_FALSE(client_peer_->OneRttKeysAvailable()); - - EXPECT_FALSE(server_peer_->IsEncryptionEstablished()); - EXPECT_FALSE(server_peer_->OneRttKeysAvailable()); - } - - protected: - simulator::Simulator simulator_; - - std::unique_ptr<simulator::SimulatedQuartcPacketTransport> client_transport_; - std::unique_ptr<simulator::SimulatedQuartcPacketTransport> server_transport_; - std::unique_ptr<simulator::CountingPacketFilter> client_filter_; - std::unique_ptr<simulator::SymmetricLink> client_server_link_; - - std::unique_ptr<FakeQuartcStreamDelegate> client_stream_delegate_; - std::unique_ptr<FakeQuartcEndpointDelegate> client_session_delegate_; - std::unique_ptr<FakeQuartcStreamDelegate> server_stream_delegate_; - std::unique_ptr<FakeQuartcEndpointDelegate> server_session_delegate_; - - std::unique_ptr<QuartcClientEndpoint> client_endpoint_; - std::unique_ptr<QuartcServerEndpoint> server_endpoint_; - - QuartcSession* client_peer_ = nullptr; - QuartcSession* server_peer_ = nullptr; -}; - -TEST_F(QuartcSessionTest, SendReceiveStreams) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - TestSendReceiveStreams(); -} - -TEST_F(QuartcSessionTest, SendReceiveMessages) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - TestSendReceiveMessage(); -} - -TEST_F(QuartcSessionTest, SendReceiveQueuedMessages) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - TestSendReceiveQueuedMessages(/*direction_from_server=*/true); - TestSendReceiveQueuedMessages(/*direction_from_server=*/false); -} - -TEST_F(QuartcSessionTest, SendMultiMemSliceMessage) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - ASSERT_TRUE(server_peer_->CanSendMessage()); - - std::vector<std::pair<char*, size_t>> buffers; - char first_piece[] = "Hello, "; - char second_piece[] = "world!"; - buffers.emplace_back(first_piece, 7); - buffers.emplace_back(second_piece, 6); - test::QuicTestMemSliceVector message(buffers); - ASSERT_TRUE( - server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/1)); - - // Wait for the client to receive the message. - RunTasks(); - - // The message is not fragmented along MemSlice boundaries. - EXPECT_THAT(client_session_delegate_->incoming_messages(), - testing::ElementsAre("Hello, world!")); -} - -TEST_F(QuartcSessionTest, SendMessageFails) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - TestSendLongMessage(); -} - -TEST_F(QuartcSessionTest, TestCryptoHandshakeCanWriteTriggers) { - CreateClientAndServerSessions(QuartcSessionConfig()); - - AwaitHandshake(); - - RunTasks(); - - ASSERT_TRUE(client_session_delegate_->writable_time().IsInitialized()); - ASSERT_TRUE( - client_session_delegate_->crypto_handshake_time().IsInitialized()); - // On client, we are writable 1-rtt before crypto handshake is complete. - ASSERT_LT(client_session_delegate_->writable_time(), - client_session_delegate_->crypto_handshake_time()); - - ASSERT_TRUE(server_session_delegate_->writable_time().IsInitialized()); - ASSERT_TRUE( - server_session_delegate_->crypto_handshake_time().IsInitialized()); - // On server, the writable time and crypto handshake are the same. (when SHLO - // is sent). - ASSERT_EQ(server_session_delegate_->writable_time(), - server_session_delegate_->crypto_handshake_time()); -} - -TEST_F(QuartcSessionTest, PreSharedKeyHandshake) { - QuartcSessionConfig config; - config.pre_shared_key = "foo"; - CreateClientAndServerSessions(config); - AwaitHandshake(); - TestSendReceiveStreams(); - TestSendReceiveMessage(); -} - -// Test that data streams are not created before handshake. -TEST_F(QuartcSessionTest, CannotCreateDataStreamBeforeHandshake) { - CreateClientAndServerSessions(QuartcSessionConfig()); - EXPECT_EQ(nullptr, server_peer_->CreateOutgoingBidirectionalStream()); - EXPECT_EQ(nullptr, client_peer_->CreateOutgoingBidirectionalStream()); -} - -TEST_F(QuartcSessionTest, CancelQuartcStream) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - ASSERT_TRUE(client_peer_->OneRttKeysAvailable()); - ASSERT_TRUE(server_peer_->OneRttKeysAvailable()); - - QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream(); - ASSERT_NE(nullptr, stream); - - uint32_t id = stream->id(); - EXPECT_FALSE(client_peer_->IsClosedStream(id)); - stream->SetDelegate(client_stream_delegate_.get()); - client_peer_->CancelStream(id); - EXPECT_EQ(stream->stream_error(), - QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED); - EXPECT_TRUE(client_peer_->IsClosedStream(id)); -} - -// TODO(b/112561077): This is the wrong layer for this test. We should write a -// test specifically for QuartcPacketWriter with a stubbed-out -// QuartcPacketTransport and remove -// SimulatedQuartcPacketTransport::last_packet_number(). -TEST_F(QuartcSessionTest, WriterGivesPacketNumberToTransport) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - ASSERT_TRUE(client_peer_->OneRttKeysAvailable()); - ASSERT_TRUE(server_peer_->OneRttKeysAvailable()); - - QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream(); - stream->SetDelegate(client_stream_delegate_.get()); - - test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello"); - stream->WriteMemSlices(stream_data.span(), /*fin=*/false); - RunTasks(); - - // The transport should see the latest packet number sent by QUIC. - EXPECT_EQ( - client_transport_->last_packet_number(), - client_peer_->connection()->sent_packet_manager().GetLargestSentPacket()); -} - -TEST_F(QuartcSessionTest, CloseConnection) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - ASSERT_TRUE(client_peer_->OneRttKeysAvailable()); - ASSERT_TRUE(server_peer_->OneRttKeysAvailable()); - - client_peer_->CloseConnection("Connection closed by client"); - EXPECT_FALSE(client_session_delegate_->connected()); - RunTasks(); - EXPECT_FALSE(server_session_delegate_->connected()); -} - -TEST_F(QuartcSessionTest, StreamRetransmissionEnabled) { - CreateClientAndServerSessions(QuartcSessionConfig()); - AwaitHandshake(); - ASSERT_TRUE(client_peer_->OneRttKeysAvailable()); - ASSERT_TRUE(server_peer_->OneRttKeysAvailable()); - - QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream(); - QuicStreamId stream_id = stream->id(); - stream->SetDelegate(client_stream_delegate_.get()); - stream->set_cancel_on_loss(false); - - client_filter_->set_packets_to_drop(1); - - test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello"); - stream->WriteMemSlices(stream_data.span(), /*fin=*/false); - RunTasks(); - - // Stream data should make it despite packet loss. - ASSERT_TRUE(server_stream_delegate_->has_data()); - EXPECT_EQ(server_stream_delegate_->data()[stream_id], "Hello"); -} - -TEST_F(QuartcSessionTest, StreamRetransmissionDisabled) { - // Disable tail loss probe, otherwise test maybe flaky because dropped - // message will be retransmitted to detect tail loss. - QuartcSessionConfig session_config; - session_config.enable_tail_loss_probe = false; - CreateClientAndServerSessions(session_config); - - // Disable probing retransmissions, otherwise test maybe flaky because dropped - // message will be retransmitted to to probe for more bandwidth. - client_peer_->connection()->set_fill_up_link_during_probing(false); - - AwaitHandshake(); - ASSERT_TRUE(client_peer_->OneRttKeysAvailable()); - ASSERT_TRUE(server_peer_->OneRttKeysAvailable()); - - // The client sends an ACK for the crypto handshake next. This must be - // flushed before we set the filter to drop the next packet, in order to - // ensure that the filter drops a data-bearing packet instead of just an ack. - RunTasks(); - - QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream(); - QuicStreamId stream_id = stream->id(); - stream->SetDelegate(client_stream_delegate_.get()); - stream->set_cancel_on_loss(true); - - client_filter_->set_packets_to_drop(1); - - test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello"); - stream->WriteMemSlices(stream_data.span(), /*fin=*/false); - simulator_.RunFor(QuicTime::Delta::FromMilliseconds(1)); - - // Send another packet to trigger loss detection. - QuartcStream* stream_1 = client_peer_->CreateOutgoingBidirectionalStream(); - stream_1->SetDelegate(client_stream_delegate_.get()); - - test::QuicTestMemSliceVector stream_data_1 = - CreateMemSliceVector("Second message"); - stream_1->WriteMemSlices(stream_data_1.span(), /*fin=*/false); - RunTasks(); - - // QUIC should try to retransmit the first stream by loss detection. Instead, - // it will cancel itself. - EXPECT_THAT(server_stream_delegate_->data()[stream_id], testing::IsEmpty()); - - EXPECT_TRUE(client_peer_->IsClosedStream(stream_id)); - EXPECT_TRUE(server_peer_->IsClosedStream(stream_id)); - EXPECT_THAT(client_stream_delegate_->stream_error(stream_id), - test::IsStreamError(QUIC_STREAM_CANCELLED)); - EXPECT_THAT(server_stream_delegate_->stream_error(stream_id), - test::IsStreamError(QUIC_STREAM_CANCELLED)); -} - -TEST_F(QuartcSessionTest, LostDatagramNotifications) { - // Disable tail loss probe, otherwise test maybe flaky because dropped - // message will be retransmitted to detect tail loss. - QuartcSessionConfig session_config; - session_config.enable_tail_loss_probe = false; - CreateClientAndServerSessions(session_config); - - // Disable probing retransmissions, otherwise test maybe flaky because dropped - // message will be retransmitted to to probe for more bandwidth. - client_peer_->connection()->set_fill_up_link_during_probing(false); - server_peer_->connection()->set_fill_up_link_during_probing(false); - - AwaitHandshake(); - ASSERT_TRUE(client_peer_->OneRttKeysAvailable()); - ASSERT_TRUE(server_peer_->OneRttKeysAvailable()); - - // The client sends an ACK for the crypto handshake next. This must be - // flushed before we set the filter to drop the next packet, in order to - // ensure that the filter drops a data-bearing packet instead of just an ack. - RunTasks(); - - // Drop the next packet. - client_filter_->set_packets_to_drop(1); - - test::QuicTestMemSliceVector message = - CreateMemSliceVector("This message will be lost"); - ASSERT_TRUE(client_peer_->SendOrQueueMessage(message.span(), 1)); - - RunTasks(); - - // Send another packet to elicit an ack and trigger loss detection. - message = CreateMemSliceVector("This message will arrive"); - ASSERT_TRUE(client_peer_->SendOrQueueMessage(message.span(), 2)); - - RunTasks(); - - EXPECT_THAT(server_session_delegate_->incoming_messages(), - ElementsAre("This message will arrive")); - EXPECT_THAT(client_session_delegate_->sent_datagram_ids(), ElementsAre(1, 2)); - EXPECT_THAT( - client_session_delegate_->acked_datagram_id_to_receive_timestamp(), - ElementsAre(Pair(2, Gt(QuicTime::Zero())))); - EXPECT_THAT(client_session_delegate_->lost_datagram_ids(), ElementsAre(1)); -} - -TEST_F(QuartcSessionTest, ServerRegistersAsWriteBlocked) { - // Initialize client and server session, but with the server write-blocked. - Init(); - server_transport_->SetWritable(false); - CreateClientAndServerSessions(QuartcSessionConfig(), /*init=*/false); - - // Let the client send a few copies of the CHLO. The server can't respond, as - // it's still write-blocked. - RunTasks(); - - // Making the server's transport writable should trigger a callback that - // reaches the server session, allowing it to write packets. - server_transport_->SetWritable(true); - - // Now the server should respond with the SHLO, encryption should be - // established, and data should flow normally. - // Note that if the server is *not* correctly registered as write-blocked, - // it will crash here (see b/124527328 for details). - AwaitHandshake(); - TestSendReceiveStreams(); -} - -TEST_F(QuartcSessionTest, PreSharedKeyHandshakeIs0RTT) { - QuartcSessionConfig session_config; - session_config.pre_shared_key = "foo"; - - // Client endpoint is created below. Destructing client endpoint - // causes issues with the simulator. - Init(/*create_client_endpoint=*/false); - - server_endpoint_->Connect(server_transport_.get()); - - client_endpoint_ = std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), client_session_delegate_.get(), - QuartcSessionConfig(), - // This is the key line here. It passes through the server config - // from the server to the client. - server_endpoint_->server_crypto_config()); - - client_endpoint_->Connect(client_transport_.get()); - - // Running for 1ms. This is shorter than the RTT, so the - // client session should be created, but server won't be created yet. - simulator_.RunFor(QuicTime::Delta::FromMilliseconds(1)); - - client_peer_ = client_session_delegate_->session(); - server_peer_ = server_session_delegate_->session(); - - ASSERT_NE(client_peer_, nullptr); - ASSERT_EQ(server_peer_, nullptr); - - // Write data to the client before running tasks. This should be sent by the - // client and received by the server if the handshake is 0RTT. - // If this test fails, add 'RunTasks()' above, and see what error is sent - // by the server in the rejection message. - QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream(); - ASSERT_NE(stream, nullptr); - QuicStreamId stream_id = stream->id(); - stream->SetDelegate(client_stream_delegate_.get()); - - char message[] = "Hello in 0RTTs!"; - test::QuicTestMemSliceVector data({std::make_pair(message, strlen(message))}); - stream->WriteMemSlices(data.span(), /*fin=*/false); - - // This will now run the rest of the connection. But the - // Server peer will receive the CHLO and message after 1 delay. - simulator_.RunFor(kPropagationDelayAndABit); - - // If we can decrypt the data, it means that 0 rtt was successful. - // This is because we waited only a propagation delay. So if the decryption - // failed, we would send sREJ instead of SHLO, but it wouldn't be delivered to - // the client yet. - ASSERT_TRUE(server_stream_delegate_->has_data()); - EXPECT_EQ(server_stream_delegate_->data()[stream_id], message); -} - -} // namespace - -} // namespace quic
diff --git a/quic/quartc/quartc_stream.cc b/quic/quartc/quartc_stream.cc deleted file mode 100644 index 01494c5..0000000 --- a/quic/quartc/quartc_stream.cc +++ /dev/null
@@ -1,170 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_stream.h" - -#include <memory> -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h" -#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h" -#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h" -#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { - -QuartcStream::QuartcStream(QuicStreamId id, QuicSession* session) - : QuicStream(id, session, /*is_static=*/false, BIDIRECTIONAL) { - sequencer()->set_level_triggered(true); -} - -QuartcStream::~QuartcStream() {} - -void QuartcStream::OnDataAvailable() { - size_t bytes_consumed = 0; - do { - bool fin = sequencer()->ReadableBytes() + sequencer()->NumBytesConsumed() == - sequencer()->close_offset(); - - // Upper bound on number of readable regions. Each complete block's worth - // of data crosses at most one region boundary. The remainder may cross one - // more boundary. Number of regions is one more than the number of region - // boundaries crossed. - size_t iov_length = sequencer()->ReadableBytes() / - QuicStreamSequencerBuffer::kBlockSizeBytes + - 2; - std::unique_ptr<iovec[]> iovecs = std::make_unique<iovec[]>(iov_length); - iov_length = sequencer()->GetReadableRegions(iovecs.get(), iov_length); - - bytes_consumed = delegate_->OnReceived(this, iovecs.get(), iov_length, fin); - sequencer()->MarkConsumed(bytes_consumed); - if (sequencer()->IsClosed()) { - OnFinRead(); - break; - } - } while (bytes_consumed > 0); -} - -void QuartcStream::OnClose() { - QuicStream::OnClose(); - DCHECK(delegate_); - delegate_->OnClose(this); -} - -void QuartcStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) { - QuicStream::OnStreamDataConsumed(bytes_consumed); - - if (delegate_) { - delegate_->OnBufferChanged(this); - } -} - -void QuartcStream::OnDataBuffered( - QuicStreamOffset /*offset*/, - QuicByteCount /*data_length*/, - const QuicReferenceCountedPointer< - QuicAckListenerInterface>& /*ack_listener*/) { - if (delegate_) { - delegate_->OnBufferChanged(this); - } -} - -bool QuartcStream::OnStreamFrameAcked(QuicStreamOffset offset, - QuicByteCount data_length, - bool fin_acked, - QuicTime::Delta ack_delay_time, - QuicTime receive_timestamp, - QuicByteCount* newly_acked_length) { - // Previous losses of acked data are no longer relevant to the retransmission - // count. Once data is acked, it will never be retransmitted. - lost_frame_counter_.RemoveInterval( - QuicInterval<QuicStreamOffset>(offset, offset + data_length)); - - return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked, - ack_delay_time, receive_timestamp, - newly_acked_length); -} - -void QuartcStream::OnStreamFrameRetransmitted(QuicStreamOffset offset, - QuicByteCount data_length, - bool fin_retransmitted) { - QuicStream::OnStreamFrameRetransmitted(offset, data_length, - fin_retransmitted); - - DCHECK(delegate_); - delegate_->OnBufferChanged(this); -} - -void QuartcStream::OnStreamFrameLost(QuicStreamOffset offset, - QuicByteCount data_length, - bool fin_lost) { - QuicStream::OnStreamFrameLost(offset, data_length, fin_lost); - - lost_frame_counter_.AddInterval( - QuicInterval<QuicStreamOffset>(offset, offset + data_length)); - - DCHECK(delegate_); - delegate_->OnBufferChanged(this); -} - -void QuartcStream::OnCanWrite() { - if (lost_frame_counter_.MaxCount() > - static_cast<size_t>(max_retransmission_count_) && - HasPendingRetransmission()) { - Reset(QUIC_STREAM_CANCELLED); - return; - } - QuicStream::OnCanWrite(); -} - -bool QuartcStream::cancel_on_loss() { - return max_retransmission_count_ == 0; -} - -void QuartcStream::set_cancel_on_loss(bool cancel_on_loss) { - if (cancel_on_loss) { - max_retransmission_count_ = 0; - } else { - max_retransmission_count_ = std::numeric_limits<int>::max(); - } -} - -int QuartcStream::max_retransmission_count() const { - return max_retransmission_count_; -} - -void QuartcStream::set_max_retransmission_count(int max_retransmission_count) { - max_retransmission_count_ = max_retransmission_count; -} - -QuicByteCount QuartcStream::BytesPendingRetransmission() { - if (lost_frame_counter_.MaxCount() > - static_cast<size_t>(max_retransmission_count_)) { - return 0; // Lost bytes will never be retransmitted. - } - QuicByteCount bytes = 0; - for (const auto& interval : send_buffer().pending_retransmissions()) { - bytes += interval.Length(); - } - return bytes; -} - -QuicStreamOffset QuartcStream::ReadOffset() { - return sequencer()->NumBytesConsumed(); -} - -void QuartcStream::FinishWriting() { - WriteOrBufferData(quiche::QuicheStringPiece(nullptr, 0), true, nullptr); -} - -void QuartcStream::SetDelegate(Delegate* delegate) { - delegate_ = delegate; - DCHECK(delegate_); -} - -} // namespace quic
diff --git a/quic/quartc/quartc_stream.h b/quic/quartc/quartc_stream.h deleted file mode 100644 index 7f3c28d..0000000 --- a/quic/quartc/quartc_stream.h +++ /dev/null
@@ -1,142 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_QUARTC_STREAM_H_ -#define QUICHE_QUIC_QUARTC_QUARTC_STREAM_H_ - -#include <stddef.h> -#include <limits> - -#include "net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h" -#include "net/third_party/quiche/src/quic/core/quic_session.h" -#include "net/third_party/quiche/src/quic/core/quic_stream.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" -#include "net/quic/platform/impl/quic_export_impl.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_interval_counter.h" - -namespace quic { - -// Sends and receives data with a particular QUIC stream ID, reliably and -// in-order. To send/receive data out of order, use separate streams. To -// send/receive unreliably, close a stream after reliability is no longer -// needed. -class QuartcStream : public QuicStream { - public: - QuartcStream(QuicStreamId id, QuicSession* session); - - ~QuartcStream() override; - - // QuicStream overrides. - void OnDataAvailable() override; - - void OnClose() override; - - void OnStreamDataConsumed(QuicByteCount bytes_consumed) override; - - void OnDataBuffered( - QuicStreamOffset offset, - QuicByteCount data_length, - const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener) - override; - - bool OnStreamFrameAcked(QuicStreamOffset offset, - QuicByteCount data_length, - bool fin_acked, - QuicTime::Delta ack_delay_time, - QuicTime receive_timestamp, - QuicByteCount* newly_acked_length) override; - - void OnStreamFrameRetransmitted(QuicStreamOffset offset, - QuicByteCount data_length, - bool fin_retransmitted) override; - - void OnStreamFrameLost(QuicStreamOffset offset, - QuicByteCount data_length, - bool fin_lost) override; - - void OnCanWrite() override; - - // QuartcStream interface methods. - - // Whether the stream should be cancelled instead of retransmitted on loss. - // If set to true, the stream will reset itself instead of retransmitting lost - // stream frames. Defaults to false. Setting it to true is equivalent to - // setting |max_retransmission_count| to zero. - bool cancel_on_loss(); - void set_cancel_on_loss(bool cancel_on_loss); - - // Maximum number of times this stream's data may be retransmitted. Each byte - // of stream data may be retransmitted this many times. If any byte (or range - // of bytes) is lost and would be retransmitted more than this number of - // times, the stream resets itself instead of retransmitting the data again. - // Setting this value to zero disables retransmissions. - // - // Note that this limit applies only to stream data, not to the FIN bit. If - // only the FIN bit needs to be retransmitted, there is no benefit to - // cancelling the stream and sending a reset frame instead. - int max_retransmission_count() const; - void set_max_retransmission_count(int max_retransmission_count); - - QuicByteCount BytesPendingRetransmission(); - - // Returns the current read offset for this stream. During a call to - // Delegate::OnReceived, this value is the offset of the first byte read. - QuicStreamOffset ReadOffset(); - - // Marks this stream as finished writing. Asynchronously sends a FIN and - // closes the write-side. It is not necessary to call FinishWriting() if the - // last call to Write() sends a FIN. - void FinishWriting(); - - // Implemented by the user of the QuartcStream to receive incoming - // data and be notified of state changes. - class Delegate { - public: - virtual ~Delegate() {} - - // Called when the stream receives data. |iov| is a pointer to the first of - // |iov_length| readable regions. |iov| points to readable data within - // |stream|'s sequencer buffer. QUIC may modify or delete this data after - // the application consumes it. |fin| indicates the end of stream data. - // Returns the number of bytes consumed. May return 0 if the delegate is - // unable to consume any bytes at this time. - virtual size_t OnReceived(QuartcStream* stream, - iovec* iov, - size_t iov_length, - bool fin) = 0; - - // Called when the stream is closed, either locally or by the remote - // endpoint. Streams close when (a) fin bits are both sent and received, - // (b) Close() is called, or (c) the stream is reset. - // TODO(zhihuang) Creates a map from the integer error_code to WebRTC native - // error code. - virtual void OnClose(QuartcStream* stream) = 0; - - // Called when the contents of the stream's buffer changes. - virtual void OnBufferChanged(QuartcStream* stream) = 0; - }; - - // The |delegate| is not owned by QuartcStream. - void SetDelegate(Delegate* delegate); - - private: - Delegate* delegate_ = nullptr; - - // Maximum number of times this stream's data may be retransmitted. - int max_retransmission_count_ = std::numeric_limits<int>::max(); - - // Counter which tracks the number of times each frame has been lost - // (accounting for the possibility of overlapping frames). - // - // If the maximum count of any lost frame exceeds |max_retransmission_count_|, - // the stream will cancel itself on the next attempt to retransmit data (the - // next call to |OnCanWrite|). - QuartcIntervalCounter<QuicStreamOffset> lost_frame_counter_; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_QUARTC_STREAM_H_
diff --git a/quic/quartc/quartc_stream_test.cc b/quic/quartc/quartc_stream_test.cc deleted file mode 100644 index f21d1dc..0000000 --- a/quic/quartc/quartc_stream_test.cc +++ /dev/null
@@ -1,652 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/quartc_stream.h" - -#include <memory> -#include <string> -#include <type_traits> -#include <utility> - -#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" -#include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h" -#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" -#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" -#include "net/third_party/quiche/src/quic/core/quic_clock.h" -#include "net/third_party/quiche/src/quic/core/quic_config.h" -#include "net/third_party/quiche/src/quic/core/quic_connection.h" -#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" -#include "net/third_party/quiche/src/quic/core/quic_data_writer.h" -#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h" -#include "net/third_party/quiche/src/quic/core/quic_session.h" -#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/core/quic_versions.h" -#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_factory.h" -#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" - -using ::quic::test::IsQuicStreamNoError; -using ::quic::test::IsStreamError; - -namespace quic { - -namespace { - -static const QuicStreamId kStreamId = 5; - -// MockQuicSession that does not create streams and writes data from -// QuicStream to a string. -class MockQuicSession : public QuicSession { - public: - MockQuicSession(QuicConnection* connection, - const QuicConfig& config, - std::string* write_buffer) - : QuicSession(connection, - nullptr /*visitor*/, - config, - CurrentSupportedVersions(), - /*num_expected_unidirectional_static_streams = */ 0), - write_buffer_(write_buffer) {} - - ~MockQuicSession() override {} - - // Writes outgoing data from QuicStream to a string. - QuicConsumedData WritevData( - QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - StreamSendingState state, - TransmissionType /*type*/, - quiche::QuicheOptional<EncryptionLevel> /*level*/) override { - if (!writable_) { - return QuicConsumedData(0, false); - } - - // WritevData does not pass down a iovec, data is saved in stream before - // data is consumed. Retrieve data from stream. - char* buf = new char[write_length]; - QuicDataWriter writer(write_length, buf, quiche::NETWORK_BYTE_ORDER); - QuicStream* stream = GetOrCreateStream(id); - DCHECK(stream); - if (write_length > 0) { - stream->WriteStreamData(offset, write_length, &writer); - } - write_buffer_->append(buf, write_length); - delete[] buf; - return QuicConsumedData(write_length, state != StreamSendingState::NO_FIN); - } - - QuartcStream* CreateIncomingStream(QuicStreamId /*id*/) override { - return nullptr; - } - - QuartcStream* CreateIncomingStream(PendingStream* /*pending*/) override { - return nullptr; - } - - const QuicCryptoStream* GetCryptoStream() const override { return nullptr; } - QuicCryptoStream* GetMutableCryptoStream() override { return nullptr; } - bool ShouldKeepConnectionAlive() const override { - return GetNumActiveStreams() > 0; - } - - // Called by QuicStream when they want to close stream. - void SendRstStream(QuicStreamId /*id*/, - QuicRstStreamErrorCode /*error*/, - QuicStreamOffset /*bytes_written*/) override {} - - // Sets whether data is written to buffer, or else if this is write blocked. - void set_writable(bool writable) { writable_ = writable; } - - // Tracks whether the stream is write blocked and its priority. - void RegisterReliableStream(QuicStreamId stream_id, - spdy::SpdyPriority priority) { - write_blocked_streams()->RegisterStream( - stream_id, - /*is_static_stream=*/false, spdy::SpdyStreamPrecedence(priority)); - } - - // The session take ownership of the stream. - void ActivateReliableStream(std::unique_ptr<QuicStream> stream) { - ActivateStream(std::move(stream)); - } - - private: - // Stores written data from ReliableQuicStreamAdapter. - std::string* write_buffer_; - // Whether data is written to write_buffer_. - bool writable_ = true; -}; - -// Packet writer that does nothing. This is required for QuicConnection but -// isn't used for writing data. -class DummyPacketWriter : public QuicPacketWriter { - public: - DummyPacketWriter() {} - - // QuicPacketWriter overrides. - WriteResult WritePacket(const char* /*buffer*/, - size_t /*buf_len*/, - const QuicIpAddress& /*self_address*/, - const QuicSocketAddress& /*peer_address*/, - PerPacketOptions* /*options*/) override { - return WriteResult(WRITE_STATUS_ERROR, 0); - } - - bool IsWriteBlocked() const override { return false; } - - void SetWritable() override {} - - QuicByteCount GetMaxPacketSize( - const QuicSocketAddress& /*peer_address*/) const override { - return 0; - } - - bool SupportsReleaseTime() const override { return false; } - - bool IsBatchMode() const override { return false; } - - QuicPacketBuffer GetNextWriteLocation( - const QuicIpAddress& /*self_address*/, - const QuicSocketAddress& /*peer_address*/) override { - return {nullptr, nullptr}; - } - - WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); } -}; - -class MockQuartcStreamDelegate : public QuartcStream::Delegate { - public: - MockQuartcStreamDelegate(QuicStreamId id, std::string* read_buffer) - : id_(id), read_buffer_(read_buffer) {} - - void OnBufferChanged(QuartcStream* stream) override { - last_bytes_buffered_ = stream->BufferedDataBytes(); - last_bytes_pending_retransmission_ = stream->BytesPendingRetransmission(); - } - - size_t OnReceived(QuartcStream* stream, - iovec* iov, - size_t iov_length, - bool /*fin*/) override { - EXPECT_EQ(id_, stream->id()); - EXPECT_EQ(stream->ReadOffset(), read_buffer_->size()); - size_t bytes_consumed = 0; - for (size_t i = 0; i < iov_length; ++i) { - read_buffer_->append(static_cast<const char*>(iov[i].iov_base), - iov[i].iov_len); - bytes_consumed += iov[i].iov_len; - } - return bytes_consumed; - } - - void OnClose(QuartcStream* /*stream*/) override { closed_ = true; } - - bool closed() { return closed_; } - - QuicByteCount last_bytes_buffered() { return last_bytes_buffered_; } - QuicByteCount last_bytes_pending_retransmission() { - return last_bytes_pending_retransmission_; - } - - protected: - QuicStreamId id_; - // Data read by the QuicStream. - std::string* read_buffer_; - // Whether the QuicStream is closed. - bool closed_ = false; - - // Last amount of data observed as buffered. - QuicByteCount last_bytes_buffered_ = 0; - QuicByteCount last_bytes_pending_retransmission_ = 0; -}; - -class QuartcStreamTest : public QuicTestWithParam<ParsedQuicVersion>, - public QuicConnectionHelperInterface { - public: - QuartcStreamTest() : version_(GetParam()) {} - - ~QuartcStreamTest() override = default; - - void CreateReliableQuicStream() { - // Arbitrary values for QuicConnection. - Perspective perspective = Perspective::IS_SERVER; - QuicIpAddress ip; - ip.FromString("0.0.0.0"); - bool owns_writer = true; - - alarm_factory_ = std::make_unique<test::MockAlarmFactory>(); - - connection_ = std::make_unique<QuicConnection>( - QuicUtils::CreateZeroConnectionId(version_.transport_version), - QuicSocketAddress(ip, 0), this /*QuicConnectionHelperInterface*/, - alarm_factory_.get(), new DummyPacketWriter(), owns_writer, perspective, - ParsedQuicVersionVector{version_}); - clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); - session_ = std::make_unique<MockQuicSession>(connection_.get(), - QuicConfig(), &write_buffer_); - mock_stream_delegate_ = - std::make_unique<MockQuartcStreamDelegate>(kStreamId, &read_buffer_); - stream_ = new QuartcStream(kStreamId, session_.get()); - stream_->SetDelegate(mock_stream_delegate_.get()); - session_->ActivateReliableStream(std::unique_ptr<QuartcStream>(stream_)); - } - - const QuicClock* GetClock() const override { return &clock_; } - - QuicRandom* GetRandomGenerator() override { - return QuicRandom::GetInstance(); - } - - QuicBufferAllocator* GetStreamSendBufferAllocator() override { - return &buffer_allocator_; - } - - protected: - const ParsedQuicVersion version_; - // The QuicSession will take the ownership. - QuartcStream* stream_; - std::unique_ptr<MockQuartcStreamDelegate> mock_stream_delegate_; - std::unique_ptr<MockQuicSession> session_; - // Data written by the ReliableQuicStreamAdapterTest. - std::string write_buffer_; - // Data read by the ReliableQuicStreamAdapterTest. - std::string read_buffer_; - std::unique_ptr<QuicAlarmFactory> alarm_factory_; - std::unique_ptr<QuicConnection> connection_; - // Used to implement the QuicConnectionHelperInterface. - SimpleBufferAllocator buffer_allocator_; - MockClock clock_; -}; - -// TODO(b/150224094): Enable versions with TLS handshake. -INSTANTIATE_TEST_SUITE_P( - Tests, - QuartcStreamTest, - ::testing::ValuesIn(CurrentSupportedVersionsWithQuicCrypto()), - ::testing::PrintToStringParamName()); - -// Write an entire string. -TEST_P(QuartcStreamTest, WriteDataWhole) { - CreateReliableQuicStream(); - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - EXPECT_EQ("Foo bar", write_buffer_); -} - -// Write part of a string. -TEST_P(QuartcStreamTest, WriteDataPartial) { - CreateReliableQuicStream(); - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 5)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - EXPECT_EQ("Foo b", write_buffer_); -} - -// Test that a QuartcStream buffers writes correctly. -TEST_P(QuartcStreamTest, StreamBuffersData) { - CreateReliableQuicStream(); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - - // The stream is not yet writable, so data will be buffered. - session_->set_writable(false); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - // Check that data is buffered. - EXPECT_TRUE(stream_->HasBufferedData()); - EXPECT_EQ(7u, stream_->BufferedDataBytes()); - - // Check that the stream told its delegate about the buffer change. - EXPECT_EQ(7u, mock_stream_delegate_->last_bytes_buffered()); - - // Check that none of the data was written yet. - // Note that |write_buffer_| actually holds data written by the QuicSession - // (not data buffered by the stream). - EXPECT_EQ(0ul, write_buffer_.size()); - - char message1[] = "xyzzy"; - test::QuicTestMemSliceVector data1({std::make_pair(message1, 5)}); - - // More writes go into the buffer. - stream_->WriteMemSlices(data1.span(), /*fin=*/false); - - EXPECT_TRUE(stream_->HasBufferedData()); - EXPECT_EQ(12u, stream_->BufferedDataBytes()); - EXPECT_EQ(12u, mock_stream_delegate_->last_bytes_buffered()); - EXPECT_EQ(0ul, write_buffer_.size()); - - // The stream becomes writable, so it sends the buffered data. - session_->set_writable(true); - stream_->OnCanWrite(); - - EXPECT_FALSE(stream_->HasBufferedData()); - EXPECT_EQ(0u, stream_->BufferedDataBytes()); - EXPECT_EQ(0u, mock_stream_delegate_->last_bytes_buffered()); - EXPECT_EQ("Foo barxyzzy", write_buffer_); -} - -// Finish writing to a stream. -// It delivers the fin bit and closes the write-side as soon as possible. -TEST_P(QuartcStreamTest, FinishWriting) { - CreateReliableQuicStream(); - - session_->set_writable(false); - stream_->FinishWriting(); - EXPECT_FALSE(stream_->fin_sent()); - - // Fin is sent as soon as the stream becomes writable. - session_->set_writable(true); - stream_->OnCanWrite(); - EXPECT_TRUE(stream_->fin_sent()); - EXPECT_TRUE(stream_->write_side_closed()); -} - -// Read an entire string. -TEST_P(QuartcStreamTest, ReadDataWhole) { - CreateReliableQuicStream(); - QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!"); - stream_->OnStreamFrame(frame); - - EXPECT_EQ("Hello, World!", read_buffer_); -} - -// Read part of a string. -TEST_P(QuartcStreamTest, ReadDataPartial) { - CreateReliableQuicStream(); - QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!"); - frame.data_length = 5; - stream_->OnStreamFrame(frame); - - EXPECT_EQ("Hello", read_buffer_); -} - -// Streams do not call OnReceived() after StopReading(). -// Note: this is tested here because Quartc relies on this behavior. -TEST_P(QuartcStreamTest, StopReading) { - CreateReliableQuicStream(); - stream_->StopReading(); - - QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!"); - stream_->OnStreamFrame(frame); - - EXPECT_EQ(0ul, read_buffer_.size()); - - QuicStreamFrame frame2(kStreamId, true, 0, "Hello, World!"); - stream_->OnStreamFrame(frame2); - - EXPECT_EQ(0ul, read_buffer_.size()); - EXPECT_TRUE(stream_->fin_received()); -} - -// Test that closing the stream results in a callback. -TEST_P(QuartcStreamTest, CloseStream) { - CreateReliableQuicStream(); - EXPECT_FALSE(mock_stream_delegate_->closed()); - stream_->CloseWriteSide(); - stream_->CloseReadSide(); - EXPECT_TRUE(mock_stream_delegate_->closed()); -} - -// Both sending and receiving fin automatically closes a stream. -TEST_P(QuartcStreamTest, CloseOnFins) { - CreateReliableQuicStream(); - QuicStreamFrame frame(kStreamId, true, 0, 0); - stream_->OnStreamFrame(frame); - - test::QuicTestMemSliceVector data({}); - stream_->WriteMemSlices(data.span(), /*fin=*/true); - - // Check that the OnClose() callback occurred. - EXPECT_TRUE(mock_stream_delegate_->closed()); -} - -TEST_P(QuartcStreamTest, TestCancelOnLossDisabled) { - CreateReliableQuicStream(); - - // This should be the default state. - EXPECT_FALSE(stream_->cancel_on_loss()); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError()); -} - -TEST_P(QuartcStreamTest, TestCancelOnLossEnabled) { - CreateReliableQuicStream(); - stream_->set_cancel_on_loss(true); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo bar", write_buffer_); - EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED)); -} - -TEST_P(QuartcStreamTest, MaxRetransmissionsAbsent) { - CreateReliableQuicStream(); - - // This should be the default state. - EXPECT_EQ(stream_->max_retransmission_count(), - std::numeric_limits<int>::max()); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError()); -} - -TEST_P(QuartcStreamTest, MaxRetransmissionsSet) { - CreateReliableQuicStream(); - stream_->set_max_retransmission_count(2); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_); - - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_); - EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED)); -} - -TEST_P(QuartcStreamTest, MaxRetransmissionsDisjointFrames) { - CreateReliableQuicStream(); - stream_->set_max_retransmission_count(2); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - // Retransmit bytes [0, 3]. - stream_->OnStreamFrameLost(0, 4, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo ", write_buffer_); - - // Retransmit bytes [4, 6]. Everything has been retransmitted once. - stream_->OnStreamFrameLost(4, 3, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - - // Retransmit bytes [0, 6]. Everything can be retransmitted a second time. - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_); -} - -TEST_P(QuartcStreamTest, MaxRetransmissionsOverlappingFrames) { - CreateReliableQuicStream(); - stream_->set_max_retransmission_count(2); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - // Retransmit bytes 0 to 3. - stream_->OnStreamFrameLost(0, 4, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo ", write_buffer_); - - // Retransmit bytes 3 to 6. Byte 3 has been retransmitted twice. - stream_->OnStreamFrameLost(3, 4, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - - // Retransmit byte 3 a third time. This should cause cancellation. - stream_->OnStreamFrameLost(3, 1, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED)); -} - -TEST_P(QuartcStreamTest, MaxRetransmissionsWithAckedFrame) { - CreateReliableQuicStream(); - stream_->set_max_retransmission_count(1); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - // Retransmit bytes [0, 7). - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - - // Ack bytes [0, 7). These bytes should be pruned from the data tracked by - // the stream. - QuicByteCount newly_acked_length = 0; - stream_->OnStreamFrameAcked(0, 7, false, QuicTime::Delta::FromMilliseconds(1), - QuicTime::Zero(), &newly_acked_length); - EXPECT_EQ(7u, newly_acked_length); - stream_->OnCanWrite(); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - - // Retransmit bytes [0, 7) again. - // QUIC will never mark frames as lost after they've been acked, but this lets - // us test that QuartcStream stopped tracking these bytes after the acked. - stream_->OnStreamFrameLost(0, 7, false); - stream_->OnCanWrite(); - - // QuartcStream should be cancelled, but it stopped tracking the lost bytes - // after they were acked, so it's not. - EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError()); -} - -TEST_P(QuartcStreamTest, TestBytesPendingRetransmission) { - CreateReliableQuicStream(); - stream_->set_cancel_on_loss(false); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - stream_->OnStreamFrameLost(0, 4, false); - EXPECT_EQ(stream_->BytesPendingRetransmission(), 4u); - EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 4u); - - stream_->OnStreamFrameLost(4, 3, false); - EXPECT_EQ(stream_->BytesPendingRetransmission(), 7u); - EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 7u); - - stream_->OnCanWrite(); - EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u); - EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u); - - EXPECT_EQ("Foo barFoo bar", write_buffer_); - EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError()); -} - -TEST_P(QuartcStreamTest, TestBytesPendingRetransmissionWithCancelOnLoss) { - CreateReliableQuicStream(); - stream_->set_cancel_on_loss(true); - - char message[] = "Foo bar"; - test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->WriteMemSlices(data.span(), /*fin=*/false); - - EXPECT_EQ("Foo bar", write_buffer_); - - stream_->OnStreamFrameLost(0, 4, false); - EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u); - EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u); - - stream_->OnStreamFrameLost(4, 3, false); - EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u); - EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u); - - stream_->OnCanWrite(); - EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u); - EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u); - - EXPECT_EQ("Foo bar", write_buffer_); - EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED)); -} - -} // namespace - -} // namespace quic
diff --git a/quic/quartc/simulated_packet_transport.cc b/quic/quartc/simulated_packet_transport.cc deleted file mode 100644 index 263c213..0000000 --- a/quic/quartc/simulated_packet_transport.cc +++ /dev/null
@@ -1,98 +0,0 @@ -// Copyright (c) 2018 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/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" - -#include <utility> - -#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" - -namespace quic { -namespace simulator { - -SimulatedQuartcPacketTransport::SimulatedQuartcPacketTransport( - Simulator* simulator, - const std::string& name, - const std::string& peer_name, - QuicByteCount queue_capacity) - : Endpoint(simulator, name), - peer_name_(peer_name), - egress_queue_(simulator, - quiche::QuicheStringPrintf("%s (TX Queue)", name.c_str()), - queue_capacity) { - egress_queue_.set_listener_interface(this); -} - -int SimulatedQuartcPacketTransport::Write(const char* buffer, - size_t buf_len, - const PacketInfo& info) { - if (!writable_) { - return 0; - } - if (egress_queue_.bytes_queued() + buf_len > egress_queue_.capacity()) { - return 0; - } - - last_packet_number_ = info.packet_number; - - auto packet = std::make_unique<Packet>(); - packet->contents = std::string(buffer, buf_len); - packet->size = buf_len; - packet->tx_timestamp = clock_->Now(); - packet->source = name(); - packet->destination = peer_name_; - - egress_queue_.AcceptPacket(std::move(packet)); - return buf_len; -} - -void SimulatedQuartcPacketTransport::SetDelegate(Delegate* delegate) { - delegate_ = delegate; - Schedule(clock_->Now()); -} - -UnconstrainedPortInterface* SimulatedQuartcPacketTransport::GetRxPort() { - return this; -} - -void SimulatedQuartcPacketTransport::SetTxPort(ConstrainedPortInterface* port) { - egress_queue_.set_tx_port(port); - Schedule(clock_->Now()); -} - -void SimulatedQuartcPacketTransport::AcceptPacket( - std::unique_ptr<Packet> packet) { - // Simulated switches broadcast packets to all ports if the cannot determine - // the recipient, so we need to drop packets that aren't intended for us. - if (packet->destination != name()) { - return; - } - - if (delegate_) { - delegate_->OnTransportReceived(packet->contents.data(), packet->size); - } -} - -void SimulatedQuartcPacketTransport::OnPacketDequeued() { - if (delegate_ && writable_) { - delegate_->OnTransportCanWrite(); - } -} - -void SimulatedQuartcPacketTransport::Act() { - if (delegate_ && writable_) { - delegate_->OnTransportCanWrite(); - } -} - -void SimulatedQuartcPacketTransport::SetWritable(bool writable) { - writable_ = writable; - if (writable_) { - // May need to call |Delegate::OnTransportCanWrite|. - Schedule(clock_->Now()); - } -} - -} // namespace simulator -} // namespace quic
diff --git a/quic/quartc/simulated_packet_transport.h b/quic/quartc/simulated_packet_transport.h deleted file mode 100644 index 185668b..0000000 --- a/quic/quartc/simulated_packet_transport.h +++ /dev/null
@@ -1,84 +0,0 @@ -// Copyright (c) 2018 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 QUICHE_QUIC_QUARTC_SIMULATED_PACKET_TRANSPORT_H_ -#define QUICHE_QUIC_QUARTC_SIMULATED_PACKET_TRANSPORT_H_ - -#include <string> - -#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/port.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/queue.h" - -namespace quic { -namespace simulator { - -// Simulated implementation of QuartcPacketTransport. This packet transport -// implementation connects Quartc to a QUIC simulator's network fabric. -// Assumes that its caller and delegate run on the same thread as the network -// simulation and therefore require no additional synchronization. -class SimulatedQuartcPacketTransport : public Endpoint, - public QuartcPacketTransport, - public UnconstrainedPortInterface, - public Queue::ListenerInterface { - public: - SimulatedQuartcPacketTransport(Simulator* simulator, - const std::string& name, - const std::string& peer_name, - QuicByteCount queue_capacity); - - // QuartcPacketTransport methods. - int Write(const char* buffer, - size_t buf_len, - const PacketInfo& info) override; - void SetDelegate(Delegate* delegate) override; - - // Simulation methods below. These are implementation details. - - // Endpoint methods. Called by the simulation to connect the transport. - UnconstrainedPortInterface* GetRxPort() override; - void SetTxPort(ConstrainedPortInterface* port) override; - - // UnconstrainedPortInterface method. Called by the simulation to deliver a - // packet to this transport. - void AcceptPacket(std::unique_ptr<Packet> packet) override; - - // Queue::ListenerInterface method. Called when the internal egress queue has - // dispatched a packet and may have room for more. - void OnPacketDequeued() override; - - // Actor method. The transport schedules this to run when the delegate is set - // in order to trigger an initial call to |Delegate::OnTransportCanWrite()|. - // (The Quartc packet writer starts in a blocked state and needs an initial - // callback to unblock it.) - void Act() override; - - // Changes whether the transport is writable. If |writable| is false, the - // transport will reject calls to |Write| and will not call - // |Delegate::OnTransportCanWrite|. If |writable| is true, the transport will - // allow calls to |Write| and will call |Delegate::OnTransportCanWrite| - // whenever it is able to write another packet. - void SetWritable(bool writable); - - // Last packet number sent over this simulated transport. - // TODO(b/112561077): Reorganize tests so that this method can be deleted. - // This exists purely for use by quartc_session_test.cc, to test that the - // packet writer passes packet numbers to the transport. - QuicPacketNumber last_packet_number() { return last_packet_number_; } - - private: - std::string peer_name_; - Delegate* delegate_ = nullptr; - Queue egress_queue_; - QuicPacketNumber last_packet_number_; - - // Controls whether the transport is considered to be writable. Used to - // simulate behavior that arises when the transport is blocked. - bool writable_ = true; -}; - -} // namespace simulator -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_SIMULATED_PACKET_TRANSPORT_H_
diff --git a/quic/quartc/simulated_packet_transport_test.cc b/quic/quartc/simulated_packet_transport_test.cc deleted file mode 100644 index 24a4f4f..0000000 --- a/quic/quartc/simulated_packet_transport_test.cc +++ /dev/null
@@ -1,163 +0,0 @@ -// Copyright (c) 2018 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/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" - -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h" - -namespace quic { -namespace simulator { -namespace { - -using ::testing::ElementsAre; - -const QuicBandwidth kDefaultBandwidth = - QuicBandwidth::FromKBitsPerSecond(10 * 1000); -const QuicTime::Delta kDefaultPropagationDelay = - QuicTime::Delta::FromMilliseconds(20); -const QuicByteCount kDefaultBdp = kDefaultBandwidth * kDefaultPropagationDelay; -const QuicByteCount kDefaultPacketSize = 1200; -const QuicPacketCount kDefaultQueueLength = 10; - -class FakeDelegate : public QuartcPacketTransport::Delegate { - public: - explicit FakeDelegate(QuartcPacketTransport* transport) - : transport_(transport) { - transport_->SetDelegate(this); - } - - ~FakeDelegate() { transport_->SetDelegate(nullptr); } - - void OnTransportCanWrite() override { - while (!packets_to_send_.empty()) { - const std::string& packet = packets_to_send_.front(); - if (transport_->Write(packet.data(), packet.size(), - QuartcPacketTransport::PacketInfo()) < - static_cast<int>(packet.size())) { - ++write_blocked_count_; - return; - } - packets_to_send_.pop(); - } - } - - void OnTransportReceived(const char* data, size_t data_len) override { - packets_received_.emplace_back(data, data_len); - } - - void AddPacketToSend(const std::string& packet) { - packets_to_send_.push(packet); - } - - size_t packets_to_send() { return packets_to_send_.size(); } - const std::vector<std::string>& packets_received() { - return packets_received_; - } - int write_blocked_count() { return write_blocked_count_; } - - private: - QuartcPacketTransport* const transport_ = nullptr; - std::queue<std::string> packets_to_send_; - std::vector<std::string> packets_received_; - int write_blocked_count_ = 0; -}; - -class SimulatedPacketTransportTest : public QuicTest { - protected: - SimulatedPacketTransportTest() - : switch_(&simulator_, "Switch", /*port_count=*/8, 2 * kDefaultBdp), - client_(&simulator_, - "sender", - "receiver", - kDefaultQueueLength * kDefaultPacketSize), - server_(&simulator_, - "receiver", - "sender", - kDefaultQueueLength * kDefaultPacketSize), - client_link_(&client_, - switch_.port(1), - kDefaultBandwidth, - kDefaultPropagationDelay), - server_link_(&server_, - switch_.port(2), - kDefaultBandwidth, - kDefaultPropagationDelay), - client_delegate_(&client_), - server_delegate_(&server_) {} - - Simulator simulator_; - Switch switch_; - - SimulatedQuartcPacketTransport client_; - SimulatedQuartcPacketTransport server_; - - SymmetricLink client_link_; - SymmetricLink server_link_; - - FakeDelegate client_delegate_; - FakeDelegate server_delegate_; -}; - -TEST_F(SimulatedPacketTransportTest, OneWayTransmission) { - std::string packet_1(kDefaultPacketSize, 'a'); - std::string packet_2(kDefaultPacketSize, 'b'); - client_delegate_.AddPacketToSend(packet_1); - client_delegate_.AddPacketToSend(packet_2); - - simulator_.RunUntil( - [this] { return client_delegate_.packets_to_send() == 0; }); - simulator_.RunFor(3 * kDefaultPropagationDelay); - - EXPECT_THAT(server_delegate_.packets_received(), - ElementsAre(packet_1, packet_2)); - EXPECT_THAT(client_delegate_.packets_received(), ElementsAre()); -} - -TEST_F(SimulatedPacketTransportTest, TwoWayTransmission) { - std::string packet_1(kDefaultPacketSize, 'a'); - std::string packet_2(kDefaultPacketSize, 'b'); - std::string packet_3(kDefaultPacketSize, 'c'); - std::string packet_4(kDefaultPacketSize, 'd'); - - client_delegate_.AddPacketToSend(packet_1); - client_delegate_.AddPacketToSend(packet_2); - server_delegate_.AddPacketToSend(packet_3); - server_delegate_.AddPacketToSend(packet_4); - - simulator_.RunUntil( - [this] { return client_delegate_.packets_to_send() == 0; }); - simulator_.RunUntil( - [this] { return server_delegate_.packets_to_send() == 0; }); - simulator_.RunFor(3 * kDefaultPropagationDelay); - - EXPECT_THAT(server_delegate_.packets_received(), - ElementsAre(packet_1, packet_2)); - EXPECT_THAT(client_delegate_.packets_received(), - ElementsAre(packet_3, packet_4)); -} - -TEST_F(SimulatedPacketTransportTest, TestWriteBlocked) { - // Add 10 packets beyond what fits in the egress queue. - std::vector<std::string> packets; - for (unsigned int i = 0; i < kDefaultQueueLength + 10; ++i) { - packets.push_back(std::string(kDefaultPacketSize, 'a' + i)); - client_delegate_.AddPacketToSend(packets.back()); - } - - simulator_.RunUntil( - [this] { return client_delegate_.packets_to_send() == 0; }); - simulator_.RunFor(3 * kDefaultPropagationDelay); - - // Each of the 10 packets in excess of the sender's egress queue length will - // block the first time |client_delegate_| tries to write them. - EXPECT_EQ(client_delegate_.write_blocked_count(), 10); - EXPECT_EQ(server_delegate_.packets_received(), packets); -} - -} // namespace -} // namespace simulator -} // namespace quic
diff --git a/quic/quartc/test/bidi_test_runner.cc b/quic/quartc/test/bidi_test_runner.cc deleted file mode 100644 index 4608c3c..0000000 --- a/quic/quartc/test/bidi_test_runner.cc +++ /dev/null
@@ -1,192 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/test/bidi_test_runner.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/quartc/test/quartc_peer.h" - -namespace quic { -namespace test { - -namespace { - -void LogResults(const std::vector<ReceivedMessage>& messages, - IdToSequenceNumberMap sent_sequence_numbers) { - QuicTime::Delta max_delay = QuicTime::Delta::Zero(); - QuicTime::Delta total_delay = QuicTime::Delta::Zero(); - QuicByteCount total_throughput = 0; - int64_t messages_received = 0; - for (const auto& message : messages) { - QuicTime::Delta one_way_delay = - message.receive_time - message.frame.send_time; - QUIC_VLOG(1) << "Frame details: source_id=" << message.frame.source_id - << ", sequence_number=" << message.frame.sequence_number - << ", one_way_delay (ms)=" << one_way_delay.ToMilliseconds(); - max_delay = std::max(max_delay, one_way_delay); - total_delay = total_delay + one_way_delay; - total_throughput += message.frame.size; - ++messages_received; - } - - int64_t messages_expected = 0; - for (const auto& it : sent_sequence_numbers) { - // Sequence numbers start at zero, so add one to the last sequence number - // to get the expected number of messages. - messages_expected += it.second + 1; - } - - QuicBandwidth total_bandwidth = QuicBandwidth::FromBytesAndTimeDelta( - total_throughput, - messages.back().receive_time - messages.front().receive_time); - double fraction_lost = - 1.0 - static_cast<double>(messages_received) / messages_expected; - QUIC_LOG(INFO) << "Summary:\n max_delay (ms)=" << max_delay.ToMilliseconds() - << "\n average_delay (ms)=" - << total_delay.ToMilliseconds() / messages.size() - << "\n total_throughput (bytes)=" << total_throughput - << "\n total_bandwidth (bps)=" - << total_bandwidth.ToBitsPerSecond() - << "\n fraction_lost=" << fraction_lost; -} - -} // namespace - -BidiTestRunner::BidiTestRunner(simulator::Simulator* simulator, - QuartcPacketTransport* client_transport, - QuartcPacketTransport* server_transport) - : simulator_(simulator), - client_transport_(client_transport), - server_transport_(server_transport) { - // Set up default data source configs. - // Emulates an audio source with a 20 ms ptime. - QuartcDataSource::Config audio; - audio.id = 1; - audio.frame_interval = QuicTime::Delta::FromMilliseconds(20); - audio.min_bandwidth = QuicBandwidth::FromKBitsPerSecond(8); - audio.max_bandwidth = QuicBandwidth::FromKBitsPerSecond(64); - - // Emulates a video source at 30 fps. - QuartcDataSource::Config video; - video.id = 2; - video.frame_interval = QuicTime::Delta::FromMicroseconds(33333); - video.min_bandwidth = QuicBandwidth::FromKBitsPerSecond(25); - video.max_bandwidth = QuicBandwidth::FromKBitsPerSecond(5000); - - // Note: by placing audio first, it takes priority in bandwidth allocations. - client_configs_.push_back(audio); - client_configs_.push_back(video); - server_configs_.push_back(audio); - server_configs_.push_back(video); -} - -BidiTestRunner::~BidiTestRunner() { - // Note that peers must be deleted before endpoints. Peers close the - // connection when deleted. - client_peer_.reset(); - server_peer_.reset(); -} - -bool BidiTestRunner::RunTest(QuicTime::Delta test_duration) { - client_peer_ = std::make_unique<QuartcPeer>( - simulator_->GetClock(), simulator_->GetAlarmFactory(), - simulator_->GetRandomGenerator(), - simulator_->GetStreamSendBufferAllocator(), client_configs_); - server_peer_ = std::make_unique<QuartcPeer>( - simulator_->GetClock(), simulator_->GetAlarmFactory(), - simulator_->GetRandomGenerator(), - simulator_->GetStreamSendBufferAllocator(), server_configs_); - - QuartcEndpoint::Delegate* server_delegate = server_peer_.get(); - if (server_interceptor_) { - server_interceptor_->SetDelegate(server_delegate); - server_delegate = server_interceptor_; - } - server_endpoint_ = std::make_unique<QuartcServerEndpoint>( - simulator_->GetAlarmFactory(), simulator_->GetClock(), - simulator_->GetRandomGenerator(), server_delegate, QuartcSessionConfig()); - - QuartcEndpoint::Delegate* client_delegate = client_peer_.get(); - if (client_interceptor_) { - client_interceptor_->SetDelegate(client_delegate); - client_delegate = client_interceptor_; - } - client_endpoint_ = std::make_unique<QuartcClientEndpoint>( - simulator_->GetAlarmFactory(), simulator_->GetClock(), - simulator_->GetRandomGenerator(), client_delegate, QuartcSessionConfig(), - server_endpoint_->server_crypto_config()); - - QuicTime start_time = simulator_->GetClock()->Now(); - server_endpoint_->Connect(server_transport_); - client_endpoint_->Connect(client_transport_); - - // Measure connect latency. - if (!simulator_->RunUntil([this] { return client_peer_->Enabled(); })) { - return false; - } - QuicTime client_connected = simulator_->GetClock()->Now(); - QuicTime::Delta client_connect_latency = client_connected - start_time; - - if (!simulator_->RunUntil([this] { return server_peer_->Enabled(); })) { - return false; - } - QuicTime server_connected = simulator_->GetClock()->Now(); - QuicTime::Delta server_connect_latency = server_connected - start_time; - - QUIC_LOG(INFO) << "Connect latencies (ms): client=" << client_connect_latency - << ", server=" << server_connect_latency; - - // Run the test. - simulator_->RunFor(test_duration); - - // Disable sending and drain. - // Note that draining by waiting for the last sequence number sent may be - // flaky if packet loss is enabled. However, simulator-based tests don't - // currently have any loss. - server_peer_->SetEnabled(false); - client_peer_->SetEnabled(false); - - if (!simulator_->RunUntil([this] { return PacketsDrained(); })) { - return false; - } - - // Compute results. - QUIC_LOG(INFO) << "Printing client->server results:"; - LogResults(server_peer_->received_messages(), - client_peer_->GetLastSequenceNumbers()); - - QUIC_LOG(INFO) << "Printing server->client results:"; - LogResults(client_peer_->received_messages(), - server_peer_->GetLastSequenceNumbers()); - return true; -} - -bool BidiTestRunner::PacketsDrained() { - const ReceivedMessage& last_server_message = - server_peer_->received_messages().back(); - const ReceivedMessage& last_client_message = - client_peer_->received_messages().back(); - - // Last observed propagation delay on the client -> server path. - QuicTime::Delta last_client_server_delay = - last_server_message.receive_time - last_server_message.frame.send_time; - - // Last observed propagation delay on the server -> client path. - QuicTime::Delta last_server_client_delay = - last_client_message.receive_time - last_client_message.frame.send_time; - - // Last observed RTT based on the propagation delays above. - QuicTime::Delta last_rtt = - last_client_server_delay + last_server_client_delay; - - // If nothing interesting has happened for at least one RTT, then it's - // unlikely anything is still in flight. - QuicTime now = simulator_->GetClock()->Now(); - return now - last_server_message.receive_time > last_rtt && - now - last_client_message.receive_time > last_rtt; -} - -} // namespace test -} // namespace quic
diff --git a/quic/quartc/test/bidi_test_runner.h b/quic/quartc/test/bidi_test_runner.h deleted file mode 100644 index 4369e22..0000000 --- a/quic/quartc/test/bidi_test_runner.h +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright (c) 2019 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 QUICHE_QUIC_QUARTC_TEST_BIDI_TEST_RUNNER_H_ -#define QUICHE_QUIC_QUARTC_TEST_BIDI_TEST_RUNNER_H_ - -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quiche/src/quic/quartc/test/quartc_data_source.h" -#include "net/third_party/quiche/src/quic/quartc/test/quartc_peer.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" - -namespace quic { -namespace test { - -// Interface for a component that intercepts endpoint callbacks before -// forwarding them to another delegate. -class QuartcEndpointInterceptor : public QuartcEndpoint::Delegate { - public: - ~QuartcEndpointInterceptor() override = default; - - // Passes the test's endpoint delegate to this interceptor. The interceptor - // must forward all callbacks to this delegate as soon as it finishes handling - // them. - virtual void SetDelegate(QuartcEndpoint::Delegate* delegate) = 0; -}; - -// Runner for bidirectional media flow tests. -// -// BidiTestRunner allows an external fixture to set up transports, then executes -// a test. During the test, it sets up two QuartcPeers, connects them through -// the transports, and sends data in both directions for a specified duration. -// It then stops sending, waits for any pending messages to finish transmission, -// and then computes and logs a few basic metrics. -// -// For now, the runner computes the maximum and average one-way delay, the total -// throughput (in bytes) and the average bandwidth (in bits per second). It -// logs these to the test's text logs. -// -// By default, the BidiTestRunner emulates one video stream and one audio stream -// in each direction. The audio stream runs with a 20 ms ptime, between 8 and -// 64 kbps. The video stream runs at 30 fps, between 25 kbps and 5 mbps. -// Individual tests can overwrite the configs. -// -// BidiTestRunner provides a way for the test to register an "interceptor" on -// each endpoint. This allows a test to reconfigure that endpoint's session -// prior to beginning the test. For example, interceptors may be used to attach -// debug visitors or change the congestion controller. -class BidiTestRunner { - public: - // TODO(b/130540842): Make this compatible with non-simulator execution. - BidiTestRunner(simulator::Simulator* simulator, - QuartcPacketTransport* client_transport, - QuartcPacketTransport* server_transport); - - virtual ~BidiTestRunner(); - - void set_client_configs(std::vector<QuartcDataSource::Config> configs) { - client_configs_ = std::move(configs); - } - - void set_server_configs(std::vector<QuartcDataSource::Config> configs) { - server_configs_ = std::move(configs); - } - - void set_client_interceptor(QuartcEndpointInterceptor* interceptor) { - client_interceptor_ = interceptor; - } - - void set_server_interceptor(QuartcEndpointInterceptor* interceptor) { - server_interceptor_ = interceptor; - } - - virtual bool RunTest(QuicTime::Delta test_duration); - - private: - // Returns true when no pending packets are believed to be in-flight. - bool PacketsDrained(); - - simulator::Simulator* simulator_; - QuartcPacketTransport* client_transport_; - QuartcPacketTransport* server_transport_; - - std::vector<QuartcDataSource::Config> client_configs_; - std::vector<QuartcDataSource::Config> server_configs_; - - QuartcEndpointInterceptor* client_interceptor_ = nullptr; - QuartcEndpointInterceptor* server_interceptor_ = nullptr; - - std::unique_ptr<QuartcServerEndpoint> server_endpoint_; - std::unique_ptr<QuartcClientEndpoint> client_endpoint_; - - std::unique_ptr<QuartcPeer> client_peer_; - std::unique_ptr<QuartcPeer> server_peer_; -}; - -} // namespace test -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_TEST_BIDI_TEST_RUNNER_H_
diff --git a/quic/quartc/test/quartc_bidi_test.cc b/quic/quartc/test/quartc_bidi_test.cc deleted file mode 100644 index dcf5509..0000000 --- a/quic/quartc/test/quartc_bidi_test.cc +++ /dev/null
@@ -1,200 +0,0 @@ -// Copyright (c) 2019 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 <utility> - -#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" -#include "net/third_party/quiche/src/quic/quartc/test/bidi_test_runner.h" -#include "net/third_party/quiche/src/quic/quartc/test/quartc_competing_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/test/quic_trace_interceptor.h" -#include "net/third_party/quiche/src/quic/quartc/test/random_packet_filter.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h" - -namespace quic { -namespace test { -namespace { - -class QuartcBidiTest : public QuicTest { - protected: - QuartcBidiTest() { - // TODO(b/150224094): Re-enable TLS handshake. - // TODO(b/150236522): Parametrize by QUIC version. - quic::test::DisableQuicVersionsWithTls(); - - uint64_t seed = QuicRandom::GetInstance()->RandUint64(); - QUIC_LOG(INFO) << "Setting random seed to " << seed; - random_.set_seed(seed); - simulator_.set_random_generator(&random_); - - client_trace_interceptor_ = - std::make_unique<QuicTraceInterceptor>("client"); - server_trace_interceptor_ = - std::make_unique<QuicTraceInterceptor>("server"); - } - - void CreateTransports(QuicBandwidth bandwidth, - QuicTime::Delta propagation_delay, - QuicByteCount queue_length, - int loss_percent) { - // Endpoints which serve as the transports for client and server. - client_transport_ = - std::make_unique<simulator::SimulatedQuartcPacketTransport>( - &simulator_, "client_transport", "server_transport", queue_length); - server_transport_ = - std::make_unique<simulator::SimulatedQuartcPacketTransport>( - &simulator_, "server_transport", "client_transport", queue_length); - - // Filters on each of the endpoints facilitate random packet loss. - client_filter_ = std::make_unique<simulator::RandomPacketFilter>( - &simulator_, "client_filter", client_transport_.get()); - server_filter_ = std::make_unique<simulator::RandomPacketFilter>( - &simulator_, "server_filter", server_transport_.get()); - client_filter_->set_loss_percent(loss_percent); - server_filter_->set_loss_percent(loss_percent); - - // Each endpoint connects directly to a switch. - client_switch_ = std::make_unique<simulator::Switch>( - &simulator_, "client_switch", /*port_count=*/8, 2 * queue_length); - server_switch_ = std::make_unique<simulator::Switch>( - &simulator_, "server_switch", /*port_count=*/8, 2 * queue_length); - - // Links to the switch have significantly higher bandwidth than the - // bottleneck and insignificant propagation delay. - client_link_ = std::make_unique<simulator::SymmetricLink>( - client_filter_.get(), client_switch_->port(1), 10 * bandwidth, - QuicTime::Delta::FromMicroseconds(1)); - server_link_ = std::make_unique<simulator::SymmetricLink>( - server_filter_.get(), server_switch_->port(1), 10 * bandwidth, - QuicTime::Delta::FromMicroseconds(1)); - - // The bottleneck link connects the two switches with the bandwidth and - // propagation delay specified by the test case. - bottleneck_link_ = std::make_unique<simulator::SymmetricLink>( - client_switch_->port(2), server_switch_->port(2), bandwidth, - propagation_delay); - } - - void SetupCompetingEndpoints(QuicBandwidth bandwidth, - QuicTime::Delta send_interval, - QuicByteCount bytes_per_interval) { - competing_client_ = std::make_unique<QuartcCompetingEndpoint>( - &simulator_, send_interval, bytes_per_interval, "competing_client", - "competing_server", quic::Perspective::IS_CLIENT, - quic::test::TestConnectionId(3)); - competing_server_ = std::make_unique<QuartcCompetingEndpoint>( - &simulator_, send_interval, bytes_per_interval, "competing_server", - "competing_client", quic::Perspective::IS_SERVER, - quic::test::TestConnectionId(3)); - - competing_client_link_ = std::make_unique<quic::simulator::SymmetricLink>( - competing_client_->endpoint(), client_switch_->port(3), 10 * bandwidth, - QuicTime::Delta::FromMicroseconds(1)); - competing_server_link_ = std::make_unique<quic::simulator::SymmetricLink>( - competing_server_->endpoint(), server_switch_->port(3), 10 * bandwidth, - QuicTime::Delta::FromMicroseconds(1)); - } - - simulator::Simulator simulator_; - SimpleRandom random_; - - std::unique_ptr<simulator::SimulatedQuartcPacketTransport> client_transport_; - std::unique_ptr<simulator::SimulatedQuartcPacketTransport> server_transport_; - std::unique_ptr<simulator::RandomPacketFilter> client_filter_; - std::unique_ptr<simulator::RandomPacketFilter> server_filter_; - std::unique_ptr<simulator::Switch> client_switch_; - std::unique_ptr<simulator::Switch> server_switch_; - std::unique_ptr<simulator::SymmetricLink> client_link_; - std::unique_ptr<simulator::SymmetricLink> server_link_; - std::unique_ptr<simulator::SymmetricLink> bottleneck_link_; - - std::unique_ptr<QuartcCompetingEndpoint> competing_client_; - std::unique_ptr<QuartcCompetingEndpoint> competing_server_; - std::unique_ptr<simulator::SymmetricLink> competing_client_link_; - std::unique_ptr<simulator::SymmetricLink> competing_server_link_; - - std::unique_ptr<QuicTraceInterceptor> client_trace_interceptor_; - std::unique_ptr<QuicTraceInterceptor> server_trace_interceptor_; -}; - -TEST_F(QuartcBidiTest, Basic300kbps200ms) { - CreateTransports(QuicBandwidth::FromKBitsPerSecond(300), - QuicTime::Delta::FromMilliseconds(200), - 10 * kDefaultMaxPacketSize, /*loss_percent=*/0); - BidiTestRunner runner(&simulator_, client_transport_.get(), - server_transport_.get()); - runner.set_client_interceptor(client_trace_interceptor_.get()); - runner.set_server_interceptor(server_trace_interceptor_.get()); - EXPECT_TRUE(runner.RunTest(QuicTime::Delta::FromSeconds(30))); -} - -TEST_F(QuartcBidiTest, 300kbps200ms2PercentLoss) { - CreateTransports(QuicBandwidth::FromKBitsPerSecond(300), - QuicTime::Delta::FromMilliseconds(200), - 10 * kDefaultMaxPacketSize, /*loss_percent=*/2); - BidiTestRunner runner(&simulator_, client_transport_.get(), - server_transport_.get()); - runner.set_client_interceptor(client_trace_interceptor_.get()); - runner.set_server_interceptor(server_trace_interceptor_.get()); - EXPECT_TRUE(runner.RunTest(QuicTime::Delta::FromSeconds(30))); -} - -TEST_F(QuartcBidiTest, 300kbps200ms2PercentLossCompetingBurst) { - QuicBandwidth bandwidth = QuicBandwidth::FromKBitsPerSecond(300); - CreateTransports(bandwidth, QuicTime::Delta::FromMilliseconds(200), - 10 * quic::kDefaultMaxPacketSize, /*loss_percent=*/2); - SetupCompetingEndpoints(bandwidth, QuicTime::Delta::FromSeconds(15), - /*bytes_per_interval=*/50 * 1024); - - quic::test::BidiTestRunner runner(&simulator_, client_transport_.get(), - server_transport_.get()); - runner.set_client_interceptor(client_trace_interceptor_.get()); - runner.set_server_interceptor(server_trace_interceptor_.get()); - EXPECT_TRUE(runner.RunTest(QuicTime::Delta::FromSeconds(30))); -} - -TEST_F(QuartcBidiTest, 300kbps200ms2PercentLossSmallCompetingSpikes) { - QuicBandwidth bandwidth = QuicBandwidth::FromKBitsPerSecond(300); - CreateTransports(bandwidth, QuicTime::Delta::FromMilliseconds(200), - 10 * quic::kDefaultMaxPacketSize, /*loss_percent=*/2); - - // Competition sends a small amount of data (10 kb) every 2 seconds. - SetupCompetingEndpoints(bandwidth, QuicTime::Delta::FromSeconds(2), - /*bytes_per_interval=*/10 * 1024); - - quic::test::BidiTestRunner runner(&simulator_, client_transport_.get(), - server_transport_.get()); - runner.set_client_interceptor(client_trace_interceptor_.get()); - runner.set_server_interceptor(server_trace_interceptor_.get()); - EXPECT_TRUE(runner.RunTest(QuicTime::Delta::FromSeconds(30))); -} - -TEST_F(QuartcBidiTest, 300kbps200ms2PercentLossAggregation) { - QuicBandwidth bandwidth = QuicBandwidth::FromKBitsPerSecond(300); - CreateTransports(bandwidth, QuicTime::Delta::FromMilliseconds(200), - 10 * quic::kDefaultMaxPacketSize, /*loss_percent=*/2); - - // Set aggregation on the queues at either end of the bottleneck. - client_switch_->port_queue(2)->EnableAggregation( - 10 * 1024, QuicTime::Delta::FromMilliseconds(100)); - server_switch_->port_queue(2)->EnableAggregation( - 10 * 1024, QuicTime::Delta::FromMilliseconds(100)); - - quic::test::BidiTestRunner runner(&simulator_, client_transport_.get(), - server_transport_.get()); - runner.set_client_interceptor(client_trace_interceptor_.get()); - runner.set_server_interceptor(server_trace_interceptor_.get()); - EXPECT_TRUE(runner.RunTest(QuicTime::Delta::FromSeconds(30))); -} - -} // namespace -} // namespace test -} // namespace quic
diff --git a/quic/quartc/test/quartc_competing_endpoint.cc b/quic/quartc/test/quartc_competing_endpoint.cc deleted file mode 100644 index bb073ec..0000000 --- a/quic/quartc/test/quartc_competing_endpoint.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/test/quartc_competing_endpoint.h" - -#include <utility> - -#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" - -namespace quic { -namespace test { - -QuartcCompetingEndpoint::QuartcCompetingEndpoint( - simulator::Simulator* simulator, - QuicTime::Delta send_interval, - QuicByteCount bytes_per_interval, - const std::string& name, - const std::string& peer_name, - Perspective perspective, - QuicConnectionId connection_id) - : Actor(simulator, quiche::QuicheStrCat(name, " actor")), - send_interval_(send_interval), - bytes_per_interval_(bytes_per_interval), - endpoint_(std::make_unique<simulator::QuicEndpoint>(simulator, - name, - peer_name, - perspective, - connection_id)) { - // Schedule the first send for one send interval into the test. - Schedule(simulator_->GetClock()->Now() + send_interval_); - last_send_time_ = simulator_->GetClock()->Now(); -} - -void QuartcCompetingEndpoint::Act() { - endpoint_->AddBytesToTransfer(bytes_per_interval_); - if (send_interval_ > QuicTime::Delta::Zero()) { - Schedule(last_send_time_ + send_interval_); - } - last_send_time_ = simulator_->GetClock()->Now(); -} - -} // namespace test -} // namespace quic
diff --git a/quic/quartc/test/quartc_competing_endpoint.h b/quic/quartc/test/quartc_competing_endpoint.h deleted file mode 100644 index 3b66131..0000000 --- a/quic/quartc/test/quartc_competing_endpoint.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright (c) 2019 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 QUICHE_QUIC_QUARTC_TEST_QUARTC_COMPETING_ENDPOINT_H_ -#define QUICHE_QUIC_QUARTC_TEST_QUARTC_COMPETING_ENDPOINT_H_ - -#include <string> - -#include "net/third_party/quiche/src/quic/core/quic_alarm.h" -#include "net/third_party/quiche/src/quic/core/quic_connection_id.h" -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/actor.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" - -namespace quic { -namespace test { - -// Wrapper for a QUIC endpoint that competes with a Quartc flow in simulator -// tests. A competing endpoint sends a fixed number of bytes at a fixed -// frequency. -class QuartcCompetingEndpoint : public simulator::Actor { - public: - // Creates a competing endpoint that sends |bytes_per_interval| every - // |send_interval|, starting one |send_interval| after it is created - // (according to |simulator|'s clock). - QuartcCompetingEndpoint(simulator::Simulator* simulator, - QuicTime::Delta send_interval, - QuicByteCount bytes_per_interval, - const std::string& name, - const std::string& peer_name, - Perspective perspective, - QuicConnectionId connection_id); - - simulator::QuicEndpoint* endpoint() { return endpoint_.get(); } - - void Act() override; - - private: - const QuicTime::Delta send_interval_; - const QuicByteCount bytes_per_interval_; - std::unique_ptr<simulator::QuicEndpoint> endpoint_; - std::unique_ptr<QuicAlarm> send_alarm_; - - QuicTime last_send_time_ = QuicTime::Zero(); -}; - -} // namespace test -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_TEST_QUARTC_COMPETING_ENDPOINT_H_
diff --git a/quic/quartc/test/quartc_data_source.cc b/quic/quartc/test/quartc_data_source.cc deleted file mode 100644 index 5856bef..0000000 --- a/quic/quartc/test/quartc_data_source.cc +++ /dev/null
@@ -1,144 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/test/quartc_data_source.h" - -#include "net/third_party/quiche/src/quic/core/quic_data_reader.h" -#include "net/third_party/quiche/src/quic/core/quic_data_writer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace test { - -namespace { - -class SendAlarmDelegate : public QuicAlarm::Delegate { - public: - explicit SendAlarmDelegate(QuartcDataSource* source) : source_(source) {} - - void OnAlarm() override { source_->OnSendAlarm(); } - - private: - QuartcDataSource* source_; -}; - -} // namespace - -bool ParsedQuartcDataFrame::Parse(quiche::QuicheStringPiece data, - ParsedQuartcDataFrame* out) { - QuicDataReader reader(data.data(), data.size()); - - uint32_t source_id; - if (!reader.ReadUInt32(&source_id)) { - return false; - } - - uint64_t sequence_number; - if (!reader.ReadUInt64(&sequence_number)) { - return false; - } - - uint64_t time_bits; - if (!reader.ReadUInt64(&time_bits)) { - return false; - } - quiche::QuicheStringPiece payload = reader.ReadRemainingPayload(); - - out->source_id = source_id; - out->sequence_number = sequence_number; - out->send_time = - QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(time_bits); - out->size = data.size(); - out->payload = std::string(payload.data(), payload.size()); - - return true; -} - -QuartcDataSource::QuartcDataSource(const QuicClock* clock, - QuicAlarmFactory* alarm_factory, - QuicRandom* random, - const Config& config, - Delegate* delegate) - : clock_(clock), - alarm_factory_(alarm_factory), - random_(random), - config_(config), - delegate_(delegate), - send_alarm_(alarm_factory_->CreateAlarm(new SendAlarmDelegate(this))), - sequence_number_(0), - allocated_bandwidth_(config_.min_bandwidth), - last_send_time_(QuicTime::Zero()) {} - -void QuartcDataSource::OnSendAlarm() { - QuicTime now = clock_->Now(); - QuicTime::Delta time_since_last_send(QuicTime::Delta::Zero()); - if (last_send_time_.IsInitialized()) { - // If previous frames have been sent, use the actual time since the last - // send to compute the frame size. - time_since_last_send = now - last_send_time_; - } else { - // For the first frame, use the configured frame interval. - time_since_last_send = config_.frame_interval; - } - - QuicByteCount bytes = - allocated_bandwidth_.ToBytesPerPeriod(time_since_last_send); - while (config_.max_frame_size > 0 && bytes > config_.max_frame_size) { - GenerateFrame(config_.max_frame_size, now); - bytes -= config_.max_frame_size; - } - GenerateFrame(bytes, now); - - // Reset alarm. - last_send_time_ = now; - send_alarm_->Set(now + config_.frame_interval); -} - -QuicBandwidth QuartcDataSource::AllocateBandwidth(QuicBandwidth bandwidth) { - allocated_bandwidth_ = std::max(config_.min_bandwidth, - std::min(bandwidth, config_.max_bandwidth)); - return std::max(bandwidth - allocated_bandwidth_, QuicBandwidth::Zero()); -} - -bool QuartcDataSource::Enabled() const { - return send_alarm_->IsSet(); -} - -void QuartcDataSource::SetEnabled(bool value) { - if (Enabled() == value) { - return; - } - - if (!value) { - send_alarm_->Cancel(); - - // Reset the last send time. When re-enabled, the data source should - // produce a frame of approximately the right size for its current - // bandwidth allocation and frame interval, not a huge frame accounting for - // all the time since it was disabled. - last_send_time_ = QuicTime::Zero(); - return; - } - - send_alarm_->Set(clock_->Now()); -} - -void QuartcDataSource::GenerateFrame(QuicByteCount frame_size, QuicTime now) { - frame_size = std::max(frame_size, kDataFrameHeaderSize); - if (buffer_.size() < frame_size) { - buffer_.resize(frame_size); - } - - // Generate data. - QuicDataWriter writer(frame_size, buffer_.data()); - writer.WriteUInt32(config_.id); - writer.WriteUInt64(sequence_number_++); - writer.WriteUInt64((now - QuicTime::Zero()).ToMicroseconds()); - writer.WriteRandomBytes(random_, writer.remaining()); - - delegate_->OnDataProduced(writer.data(), writer.length()); -} - -} // namespace test -} // namespace quic
diff --git a/quic/quartc/test/quartc_data_source.h b/quic/quartc/test/quartc_data_source.h deleted file mode 100644 index af796e6..0000000 --- a/quic/quartc/test/quartc_data_source.h +++ /dev/null
@@ -1,121 +0,0 @@ -// Copyright (c) 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 QUICHE_QUIC_QUARTC_TEST_QUARTC_DATA_SOURCE_H_ -#define QUICHE_QUIC_QUARTC_TEST_QUARTC_DATA_SOURCE_H_ - -#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" -#include "net/third_party/quiche/src/quic/core/quic_alarm.h" -#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" -#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" -#include "net/third_party/quiche/src/quic/core/quic_clock.h" -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace test { - -// Frames sent by a QuartcDataSource have a 20-byte header (4 bytes for the -// source id, 8 bytes for the sequence number, 8 bytes for the timestamp). -constexpr QuicByteCount kDataFrameHeaderSize = 20; - -// Struct representing one frame of data sent by a QuartcDataSource. -struct ParsedQuartcDataFrame { - // Parses the given data as a frame generated by QuartcDataSource. Returns - // true if parsing succeeds or false if parsing fails. - static bool Parse(quiche::QuicheStringPiece data, ParsedQuartcDataFrame* out); - - // Note that a properly formatted, parseable frame always contains these three - // header fields. - int32_t source_id = -1; - int64_t sequence_number = -1; - QuicTime send_time = QuicTime::Zero(); - - // Total size, including header and payload. - QuicByteCount size = 0; - std::string payload; -}; - -// Alarm-based source of random data to send. QuartcDataSource is configured to -// generate new data at fixed intervals. -class QuartcDataSource { - public: - struct Config { - // 32-bit ID for this data source. - int32_t id = 0; - - // Minimum bandwidth allocated to this data source. - QuicBandwidth min_bandwidth = QuicBandwidth::Zero(); - - // Maximum bandwidth allocated to this data source. - QuicBandwidth max_bandwidth = QuicBandwidth::Infinite(); - - // Interval between frames for this data source. - QuicTime::Delta frame_interval = QuicTime::Delta::FromMilliseconds(10); - - // Maximum size of frames produced by this source. If this value is greater - // than 0, the source may produce multiple frames with the same timestamp - // rather than a single frame that is larger than this size. - // If less than kDataFrameHeaderSize, the source produces frames of - // kDataFrameHeaderSize. - QuicByteCount max_frame_size = 0; - }; - - class Delegate { - public: - virtual ~Delegate() = default; - - virtual void OnDataProduced(const char* data, size_t length) = 0; - }; - - QuartcDataSource(const QuicClock* clock, - QuicAlarmFactory* alarm_factory, - QuicRandom* random, - const Config& config, - Delegate* delegate); - - void OnSendAlarm(); - - // Allocates bandwidth to this source. The source clamps the given value - // between its configured min and max bandwidth, and returns any amount in - // excess of its maximum allocation. - QuicBandwidth AllocateBandwidth(QuicBandwidth bandwidth); - - // Whether the data source is enabled. The data source only produces data - // when enabled. When first enabled, the data source starts sending - // immediately. When disabled, the data source stops sending immediately. - bool Enabled() const; - void SetEnabled(bool value); - - // Returns the sequence number of the last frame generated (or -1 if no frames - // have been generated). - int64_t sequence_number() const { return sequence_number_ - 1; } - - private: - void GenerateFrame(QuicByteCount frame_size, QuicTime now); - - const QuicClock* clock_; - QuicAlarmFactory* alarm_factory_; - QuicRandom* random_; - const Config config_; - Delegate* delegate_; - - std::unique_ptr<QuicAlarm> send_alarm_; - - int64_t sequence_number_; - QuicBandwidth allocated_bandwidth_; - QuicTime last_send_time_; - - // Buffer for frames of data generated by the source. The source writes each - // frame into this buffer, then hands the delegate a pointer to it. It's a - // std::vector simply to make it quick and easy to resize if necessary (eg. if - // |allocated_bandwidth_| increases and the frame size goes up. Otherwise, it - // would be a char[]. - std::vector<char> buffer_; -}; - -} // namespace test -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_TEST_QUARTC_DATA_SOURCE_H_
diff --git a/quic/quartc/test/quartc_data_source_test.cc b/quic/quartc/test/quartc_data_source_test.cc deleted file mode 100644 index 3bf7e66..0000000 --- a/quic/quartc/test/quartc_data_source_test.cc +++ /dev/null
@@ -1,381 +0,0 @@ -// Copyright (c) 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/third_party/quiche/src/quic/quartc/test/quartc_data_source.h" - -#include <utility> -#include <vector> - -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace test { -namespace { - -class FakeDelegate : public QuartcDataSource::Delegate { - public: - void OnDataProduced(const char* data, size_t length) override; - - const std::vector<ParsedQuartcDataFrame>& frames() { return frames_; } - - private: - std::vector<ParsedQuartcDataFrame> frames_; -}; - -void FakeDelegate::OnDataProduced(const char* data, size_t length) { - ParsedQuartcDataFrame frame; - quiche::QuicheStringPiece message(data, length); - if (ParsedQuartcDataFrame::Parse(message, &frame)) { - frames_.push_back(frame); - } else { - QUIC_LOG(FATAL) << "Data source produced a frame it can't parse: " - << message; - } -} - -class QuartcDataSourceTest : public QuicTest { - protected: - QuartcDataSourceTest() : simulator_() {} - - simulator::Simulator simulator_; - FakeDelegate delegate_; - - std::unique_ptr<QuartcDataSource> source_; -}; - -TEST_F(QuartcDataSourceTest, ProducesFrameEveryInterval) { - QuartcDataSource::Config config; - config.frame_interval = QuicTime::Delta::FromMilliseconds(20); - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval)); - source_->SetEnabled(true); - - simulator_.RunFor(config.frame_interval); - EXPECT_EQ(delegate_.frames().size(), 1u); - - simulator_.RunFor(config.frame_interval); - EXPECT_EQ(delegate_.frames().size(), 2u); - - simulator_.RunFor(config.frame_interval * 20); - EXPECT_EQ(delegate_.frames().size(), 22u); -} - -TEST_F(QuartcDataSourceTest, DoesNotProduceFramesUntilEnabled) { - QuartcDataSource::Config config; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval)); - - simulator_.RunFor(config.frame_interval * 20); - EXPECT_EQ(delegate_.frames().size(), 0u); - - // The first frame is produced immediately (but asynchronously) upon enabling - // the source. - source_->SetEnabled(true); - simulator_.RunFor(QuicTime::Delta::FromMicroseconds(1)); - EXPECT_EQ(delegate_.frames().size(), 1u); -} - -TEST_F(QuartcDataSourceTest, DisableAndEnable) { - QuartcDataSource::Config config; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval)); - - source_->SetEnabled(true); - simulator_.RunFor(config.frame_interval * 20); - EXPECT_EQ(delegate_.frames().size(), 20u); - - // No new frames while the source is disabled. - source_->SetEnabled(false); - simulator_.RunFor(config.frame_interval * 20); - EXPECT_EQ(delegate_.frames().size(), 20u); - - // The first frame is produced immediately (but asynchronously) upon enabling - // the source. - source_->SetEnabled(true); - simulator_.RunFor(QuicTime::Delta::FromMicroseconds(1)); - ASSERT_EQ(delegate_.frames().size(), 21u); - - // The first frame after a pause should be no larger than previous frames. - EXPECT_EQ(delegate_.frames()[0].payload.size(), - delegate_.frames()[20].payload.size()); - - // The first frame after the pause should have a much later timestamp. - // Note that the previous frame (19) happens at the *start* of the 20th - // interval. Frame 20 would normally happen one interval later, but we've - // delayed it by an extra 20 intervals (for a total of 21 intervals later). - EXPECT_EQ(delegate_.frames()[20].send_time - delegate_.frames()[19].send_time, - 21 * config.frame_interval); -} - -TEST_F(QuartcDataSourceTest, EnablingTwiceDoesNotChangeSchedule) { - QuartcDataSource::Config config; - config.frame_interval = QuicTime::Delta::FromMilliseconds(20); - - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval)); - - // The first frame is produced immediately (but asynchronously) upon enabling - // the source. - source_->SetEnabled(true); - simulator_.RunFor(QuicTime::Delta::FromMicroseconds(1)); - EXPECT_EQ(delegate_.frames().size(), 1u); - - // Enabling the source again does not re-schedule the alarm. - source_->SetEnabled(true); - simulator_.RunFor(QuicTime::Delta::FromMicroseconds(1)); - EXPECT_EQ(delegate_.frames().size(), 1u); - - // The second frame is sent at the expected interval after the first. - ASSERT_TRUE( - simulator_.RunUntil([this] { return delegate_.frames().size() == 2; })); - - EXPECT_EQ(delegate_.frames()[1].send_time - delegate_.frames()[0].send_time, - config.frame_interval); -} - -TEST_F(QuartcDataSourceTest, ProducesFramesWithConfiguredSourceId) { - QuartcDataSource::Config config; - config.id = 7; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval)); - source_->SetEnabled(true); - simulator_.RunFor(config.frame_interval); - - ASSERT_EQ(delegate_.frames().size(), 1u); - EXPECT_EQ(delegate_.frames()[0].source_id, config.id); -} - -TEST_F(QuartcDataSourceTest, ProducesFramesAtAllocatedBandwidth) { - QuartcDataSource::Config config; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - - constexpr QuicByteCount bytes_per_frame = 1000; - source_->AllocateBandwidth(QuicBandwidth::FromBytesAndTimeDelta( - bytes_per_frame, config.frame_interval)); - source_->SetEnabled(true); - simulator_.RunFor(config.frame_interval); - - ASSERT_EQ(delegate_.frames().size(), 1u); - EXPECT_EQ(delegate_.frames()[0].payload.size(), - bytes_per_frame - kDataFrameHeaderSize); - EXPECT_EQ(delegate_.frames()[0].size, bytes_per_frame); -} - -TEST_F(QuartcDataSourceTest, ProducesParseableHeaderWhenNotEnoughBandwidth) { - QuartcDataSource::Config config; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - - // Allocate less bandwidth than the source requires for its header. - source_->AllocateBandwidth(QuicBandwidth::FromBytesAndTimeDelta( - kDataFrameHeaderSize - 10, config.frame_interval)); - source_->SetEnabled(true); - - QuicTime start_time = simulator_.GetClock()->Now(); - simulator_.RunFor(config.frame_interval); - - ASSERT_EQ(delegate_.frames().size(), 1u); - EXPECT_EQ(delegate_.frames()[0].payload.size(), 0u); - EXPECT_EQ(delegate_.frames()[0].size, kDataFrameHeaderSize); - - // Header fields are still present and parseable. - EXPECT_EQ(delegate_.frames()[0].source_id, 0); - EXPECT_EQ(delegate_.frames()[0].sequence_number, 0); - EXPECT_EQ(delegate_.frames()[0].send_time, start_time); -} - -TEST_F(QuartcDataSourceTest, ProducesSequenceNumbers) { - QuartcDataSource::Config config; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval)); - source_->SetEnabled(true); - - simulator_.RunFor(config.frame_interval * 20); - - ASSERT_EQ(delegate_.frames().size(), 20u); - for (int i = 0; i < 20; ++i) { - EXPECT_EQ(delegate_.frames()[i].sequence_number, i); - } -} - -TEST_F(QuartcDataSourceTest, ProducesSendTimes) { - QuartcDataSource::Config config; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval)); - source_->SetEnabled(true); - - simulator_.RunFor(config.frame_interval * 20); - - ASSERT_EQ(delegate_.frames().size(), 20u); - QuicTime first_send_time = delegate_.frames()[0].send_time; - for (int i = 1; i < 20; ++i) { - EXPECT_EQ(delegate_.frames()[i].send_time, - first_send_time + i * config.frame_interval); - } -} - -TEST_F(QuartcDataSourceTest, AllocateClampsToMin) { - QuartcDataSource::Config config; - config.min_bandwidth = QuicBandwidth::FromBitsPerSecond(8000); - config.frame_interval = QuicTime::Delta::FromMilliseconds(100); - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - - // When allocating less than the minimum, there is nothing left over. - EXPECT_EQ(source_->AllocateBandwidth(QuicBandwidth::FromBitsPerSecond(6000)), - QuicBandwidth::Zero()); - - source_->SetEnabled(true); - simulator_.RunFor(config.frame_interval); - - // The frames produced use min_bandwidth instead of the lower allocation. - QuicByteCount bytes_per_frame = - config.min_bandwidth.ToBytesPerPeriod(config.frame_interval); - ASSERT_EQ(delegate_.frames().size(), 1u); - EXPECT_EQ(delegate_.frames()[0].payload.size(), - bytes_per_frame - kDataFrameHeaderSize); - EXPECT_EQ(delegate_.frames()[0].size, bytes_per_frame); -} - -TEST_F(QuartcDataSourceTest, AllocateClampsToMax) { - QuartcDataSource::Config config; - config.max_bandwidth = QuicBandwidth::FromBitsPerSecond(8000); - config.frame_interval = QuicTime::Delta::FromMilliseconds(100); - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - - // When allocating more than the maximum, the excess is returned. - EXPECT_EQ(source_->AllocateBandwidth(QuicBandwidth::FromBitsPerSecond(10000)), - QuicBandwidth::FromBitsPerSecond(2000)); - - source_->SetEnabled(true); - simulator_.RunFor(config.frame_interval); - - // The frames produced use max_bandwidth instead of the higher allocation. - QuicByteCount bytes_per_frame = - config.max_bandwidth.ToBytesPerPeriod(config.frame_interval); - ASSERT_EQ(delegate_.frames().size(), 1u); - EXPECT_EQ(delegate_.frames()[0].payload.size(), - bytes_per_frame - kDataFrameHeaderSize); - EXPECT_EQ(delegate_.frames()[0].size, bytes_per_frame); -} - -TEST_F(QuartcDataSourceTest, MaxFrameSize) { - constexpr QuicByteCount bytes_per_frame = 1000; - QuartcDataSource::Config config; - config.max_frame_size = bytes_per_frame; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - - // Allocate enough bandwidth for more than one frame per interval. - source_->AllocateBandwidth(QuicBandwidth::FromBytesAndTimeDelta( - 3 * bytes_per_frame, config.frame_interval)); - source_->SetEnabled(true); - - QuicTime start_time = simulator_.GetClock()->Now(); - simulator_.RunFor(config.frame_interval); - - // Since there's enough bandwidth for three frames per interval, that's what - // the source should generate. - EXPECT_EQ(delegate_.frames().size(), 3u); - int i = 0; - for (const auto& frame : delegate_.frames()) { - // Each of the frames should start with a header that can be parsed. - // Each gets the same timestamp, but a different sequence number. - EXPECT_EQ(frame.source_id, config.id); - EXPECT_EQ(frame.sequence_number, i++); - EXPECT_EQ(frame.send_time, start_time); - - // Each of the frames should have the configured maximum size. - EXPECT_EQ(frame.payload.size(), bytes_per_frame - kDataFrameHeaderSize); - EXPECT_EQ(frame.size, bytes_per_frame); - } -} - -TEST_F(QuartcDataSourceTest, ProducesParseableHeaderWhenMaxFrameSizeTooSmall) { - QuartcDataSource::Config config; - config.max_frame_size = kDataFrameHeaderSize - 1; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(200, config.frame_interval)); - source_->SetEnabled(true); - - QuicTime start_time = simulator_.GetClock()->Now(); - simulator_.RunFor(config.frame_interval); - - ASSERT_GE(delegate_.frames().size(), 1u); - EXPECT_EQ(delegate_.frames()[0].payload.size(), 0u); - EXPECT_EQ(delegate_.frames()[0].size, kDataFrameHeaderSize); - - // Header fields are still present and parseable. - EXPECT_EQ(delegate_.frames()[0].source_id, 0); - EXPECT_EQ(delegate_.frames()[0].sequence_number, 0); - EXPECT_EQ(delegate_.frames()[0].send_time, start_time); -} - -TEST_F(QuartcDataSourceTest, ProducesParseableHeaderWhenLeftoverSizeTooSmall) { - QuartcDataSource::Config config; - config.max_frame_size = 200; - source_ = std::make_unique<QuartcDataSource>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), config, &delegate_); - - // Allocate enough bandwidth to send a 200-byte frame and a 1-byte frame. - source_->AllocateBandwidth( - QuicBandwidth::FromBytesAndTimeDelta(201, config.frame_interval)); - source_->SetEnabled(true); - - QuicTime start_time = simulator_.GetClock()->Now(); - simulator_.RunFor(config.frame_interval); - - ASSERT_EQ(delegate_.frames().size(), 2u); - EXPECT_EQ(delegate_.frames()[0].payload.size(), 200u - kDataFrameHeaderSize); - EXPECT_EQ(delegate_.frames()[0].size, 200u); - - // The second frame, using the 1 leftover byte from the first, rounds up to - // the minimum frame size (just the header and no payload). - EXPECT_EQ(delegate_.frames()[1].payload.size(), 0u); - EXPECT_EQ(delegate_.frames()[1].size, kDataFrameHeaderSize); - - // Header fields are still present and parseable. - EXPECT_EQ(delegate_.frames()[1].source_id, 0); - EXPECT_EQ(delegate_.frames()[1].sequence_number, 1); - EXPECT_EQ(delegate_.frames()[1].send_time, start_time); -} - -} // namespace -} // namespace test -} // namespace quic
diff --git a/quic/quartc/test/quartc_peer.cc b/quic/quartc/test/quartc_peer.cc deleted file mode 100644 index ea1257d..0000000 --- a/quic/quartc/test/quartc_peer.cc +++ /dev/null
@@ -1,124 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/test/quartc_peer.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace test { - -QuartcPeer::QuartcPeer(const QuicClock* clock, - QuicAlarmFactory* alarm_factory, - QuicRandom* random, - QuicBufferAllocator* buffer_allocator, - const std::vector<QuartcDataSource::Config>& configs) - : clock_(clock), - alarm_factory_(alarm_factory), - random_(random), - buffer_allocator_(buffer_allocator), - enabled_(false), - session_(nullptr), - configs_(configs), - last_available_(QuicBandwidth::Zero()) {} - -QuartcPeer::~QuartcPeer() { - session_->CloseConnection("~QuartcPeer()"); -} - -void QuartcPeer::SetEnabled(bool value) { - enabled_ = value; - for (auto& source : data_sources_) { - source->SetEnabled(enabled_); - } -} - -IdToSequenceNumberMap QuartcPeer::GetLastSequenceNumbers() const { - DCHECK_GE(configs_.size(), data_sources_.size()); - IdToSequenceNumberMap out; - for (size_t i = 0; i < data_sources_.size(); ++i) { - out[configs_[i].id] = data_sources_[i]->sequence_number(); - } - return out; -} - -void QuartcPeer::OnSessionCreated(QuartcSession* session) { - session_ = session; - - session_->StartCryptoHandshake(); - - QuicByteCount largest_message_payload = - session_->GetGuaranteedLargestMessagePayload(); - for (auto& config : configs_) { - // Clamp maximum frame sizes to the largest supported by the session before - // creating data sources. - config.max_frame_size = - config.max_frame_size > 0 - ? std::min(config.max_frame_size, largest_message_payload) - : largest_message_payload; - QUIC_LOG(INFO) << "Set max frame size for source " << config.id << " to " - << config.max_frame_size; - data_sources_.push_back(std::make_unique<QuartcDataSource>( - clock_, alarm_factory_, random_, config, this)); - } -} - -void QuartcPeer::OnCryptoHandshakeComplete() { - SetEnabled(true); -} - -void QuartcPeer::OnConnectionWritable() { - SetEnabled(true); -} - -void QuartcPeer::OnIncomingStream(QuartcStream* stream) { - QUIC_LOG(DFATAL) << "Unexpected incoming stream, id=" << stream->id(); -} - -void QuartcPeer::OnCongestionControlChange(QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta /*latest_rtt*/) { - // Note: this is fairly crude rate adaptation and makes no effort to account - // for overhead. The congestion controller is assumed to account for this. - // It may do so by detecting overuse and pushing back on its bandwidth - // estimate, or it may explicitly subtract overhead before surfacing its - // estimate. - QuicBandwidth available = std::min(bandwidth_estimate, pacing_rate); - last_available_ = available; - for (auto& source : data_sources_) { - available = source->AllocateBandwidth(available); - } -} - -void QuartcPeer::OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource /*source*/) { - QUIC_LOG(INFO) << "Connection closed, frame=" << frame; - SetEnabled(false); -} - -void QuartcPeer::OnMessageReceived(quiche::QuicheStringPiece message) { - ReceivedMessage received; - received.receive_time = clock_->Now(); - - if (!ParsedQuartcDataFrame::Parse(message, &received.frame)) { - QUIC_LOG(DFATAL) << "Failed to parse incoming message as test data frame: [" - << message << "]"; - } - received_messages_.push_back(received); -} - -void QuartcPeer::OnDataProduced(const char* data, size_t length) { - // Further packetization is not required, as sources are configured to produce - // frames that fit within message payloads. - DCHECK_LE(length, session_->GetCurrentLargestMessagePayload()); - struct iovec iov = {const_cast<char*>(data), length}; - QuicMemSliceStorage storage(&iov, 1, buffer_allocator_, length); - session_->SendOrQueueMessage(storage.ToSpan(), /*datagram_id=*/0); -} - -} // namespace test -} // namespace quic
diff --git a/quic/quartc/test/quartc_peer.h b/quic/quartc/test/quartc_peer.h deleted file mode 100644 index 7e413f8..0000000 --- a/quic/quartc/test/quartc_peer.h +++ /dev/null
@@ -1,131 +0,0 @@ -// Copyright (c) 2019 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 QUICHE_QUIC_QUARTC_TEST_QUARTC_PEER_H_ -#define QUICHE_QUIC_QUARTC_TEST_QUARTC_PEER_H_ - -#include <string> - -#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" -#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" -#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" -#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h" -#include "net/third_party/quiche/src/quic/quartc/test/quartc_data_source.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace test { - -// Map of source id to sequence number. -using IdToSequenceNumberMap = std::map<int32_t, int64_t>; - -// ParsedQuartcDataFrame with a receive_time. -struct ReceivedMessage { - ParsedQuartcDataFrame frame; - QuicTime receive_time = QuicTime::Zero(); -}; - -// Test utility that adapts QuartcDataSources to a QuartcSession. -// The utility creates and manages a set of QuartcDataSources. It sends the -// data produced by those sources as QUIC datagram frames. It reconfigures the -// maximum frame size of each source in order to fit test frames into QUIC -// datagram frames. It also adjusts the bitrate of each source to fit within -// the bandwidth available to the session. -class QuartcPeer : public QuartcEndpoint::Delegate, - public QuartcDataSource::Delegate { - public: - // Creates a QuartcPeer that sends data from a set of sources described by - // |configs|. Note that the max frame size of each config may be adjusted in - // order to fit within the constraints of the QUIC session. - QuartcPeer(const QuicClock* clock, - QuicAlarmFactory* alarm_factory, - QuicRandom* random, - QuicBufferAllocator* buffer_allocator, - const std::vector<QuartcDataSource::Config>& configs); - QuartcPeer(QuartcPeer&) = delete; - QuartcPeer& operator=(QuartcPeer&) = delete; - - ~QuartcPeer(); - - // Enable or disable this peer. Disabling a peer causes it to stop sending - // messages (which may be useful for flushing data during tests). - // A peer begins disabled. It automatically enables itself as soon as its - // session becomes writable, and disables itself when its session closes. - bool Enabled() const { return enabled_; } - void SetEnabled(bool value); - - // Messages received from the peer, in the order they were received. - const std::vector<ReceivedMessage>& received_messages() const { - return received_messages_; - } - - // Returns a map of source id to the sequence number of the last frame - // produced by that source. - IdToSequenceNumberMap GetLastSequenceNumbers() const; - - QuicBandwidth last_available_bandwidth() { return last_available_; } - - QuartcSession* session() const { return session_; } - - // QuartcEndpoint::Delegate overrides. - void OnSessionCreated(QuartcSession* session) override; - - // QuartcSession::Delegate overrides. - void OnCryptoHandshakeComplete() override; - void OnConnectionWritable() override; - void OnIncomingStream(QuartcStream* stream) override; - void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) override; - void OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) override; - void OnMessageReceived(quiche::QuicheStringPiece message) override; - void OnMessageSent(int64_t /*datagram_id*/) override {} - void OnMessageAcked(int64_t /*datagram_id*/, - QuicTime /*receive_timestamp*/) override {} - void OnMessageLost(int64_t /*datagram_id*/) override {} - - // QuartcDataSource::Delegate overrides. - void OnDataProduced(const char* data, size_t length) override; - - private: - const QuicClock* clock_; - QuicAlarmFactory* alarm_factory_; - QuicRandom* random_; - QuicBufferAllocator* buffer_allocator_; - - // Whether the peer is currently sending. - bool enabled_; - - // Session used for sending and receiving data. Not owned. Created by an - // external QuartcEndpoint and set in the |OnSessionCreated| callback. - QuartcSession* session_; - - // Saved copy of the configs for data sources. These configs may be modified - // before |data_sources_| are initialized (for example, to set appropriate - // max frame sizes). - std::vector<QuartcDataSource::Config> configs_; - - // Data sources are initialized once the session is created and enabled once - // the session is able to send. - std::vector<std::unique_ptr<QuartcDataSource>> data_sources_; - - // Messages received by this peer from the remote peer. Stored in the order - // they are received. - std::vector<ReceivedMessage> received_messages_; - - // Last available bandwidth. - QuicBandwidth last_available_; -}; - -} // namespace test -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_FAKE_QUARTC_PEER_H_
diff --git a/quic/quartc/test/quartc_peer_test.cc b/quic/quartc/test/quartc_peer_test.cc deleted file mode 100644 index f3e5b68..0000000 --- a/quic/quartc/test/quartc_peer_test.cc +++ /dev/null
@@ -1,450 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/test/quartc_peer.h" - -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" -#include "net/third_party/quiche/src/quic/core/quic_constants.h" -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" - -namespace quic { -namespace test { -namespace { - -using ::testing::_; -using ::testing::NiceMock; -using ::testing::Return; - -constexpr QuicBandwidth kLinkBandwidth = QuicBandwidth::FromKBitsPerSecond(512); - -class QuartcPeerTest : public QuicTest { - protected: - QuartcPeerTest() - : client_transport_(&simulator_, - "client_transport", - "server_transport", - 10 * kDefaultMaxPacketSize), - server_transport_(&simulator_, - "server_transport", - "client_transport", - 10 * kDefaultMaxPacketSize), - client_server_link_(&client_transport_, - &server_transport_, - kLinkBandwidth, - QuicTime::Delta::FromMilliseconds(100)) { - // TODO(b/150224094): Re-enable TLS handshake. - // TODO(b/150236522): Parametrize by QUIC version. - quic::test::DisableQuicVersionsWithTls(); - - simulator_.set_random_generator(&rng_); - } - - void CreatePeers(const std::vector<QuartcDataSource::Config>& configs) { - client_peer_ = std::make_unique<QuartcPeer>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), - simulator_.GetStreamSendBufferAllocator(), configs); - server_peer_ = std::make_unique<QuartcPeer>( - simulator_.GetClock(), simulator_.GetAlarmFactory(), - simulator_.GetRandomGenerator(), - simulator_.GetStreamSendBufferAllocator(), configs); - } - - void Connect() { - DCHECK(client_peer_); - DCHECK(server_peer_); - - server_endpoint_ = std::make_unique<QuartcServerEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), server_peer_.get(), - QuartcSessionConfig()); - client_endpoint_ = std::make_unique<QuartcClientEndpoint>( - simulator_.GetAlarmFactory(), simulator_.GetClock(), - simulator_.GetRandomGenerator(), client_peer_.get(), - QuartcSessionConfig(), server_endpoint_->server_crypto_config()); - - server_endpoint_->Connect(&server_transport_); - client_endpoint_->Connect(&client_transport_); - } - - void SetMockBandwidth(MockSendAlgorithm* send_algorithm, - QuicBandwidth bandwidth) { - ON_CALL(*send_algorithm, BandwidthEstimate()) - .WillByDefault(Return(bandwidth)); - ON_CALL(*send_algorithm, PacingRate(_)).WillByDefault(Return(bandwidth)); - ON_CALL(*send_algorithm, CanSend(_)).WillByDefault(Return(true)); - } - - void RampUpBandwidth(QuicBandwidth bandwidth) { - ASSERT_TRUE(simulator_.RunUntilOrTimeout( - [this] { - return client_peer_->session() != nullptr && - server_peer_->session() != nullptr; - }, - QuicTime::Delta::FromSeconds(60))); - - MockSendAlgorithm* client_send_algorithm = - new NiceMock<MockSendAlgorithm>(); - SetMockBandwidth(client_send_algorithm, bandwidth); - QuicConnectionPeer::SetSendAlgorithm(client_peer_->session()->connection(), - client_send_algorithm); - - MockSendAlgorithm* server_send_algorithm = - new NiceMock<MockSendAlgorithm>(); - SetMockBandwidth(server_send_algorithm, bandwidth); - QuicConnectionPeer::SetSendAlgorithm(server_peer_->session()->connection(), - server_send_algorithm); - } - - void WaitForMessages() { - simulator_.RunFor(QuicTime::Delta::FromSeconds(10)); - ASSERT_TRUE(simulator_.RunUntil([this] { - return !client_peer_->received_messages().empty() && - !server_peer_->received_messages().empty(); - })); - } - - SimpleRandom rng_; - simulator::Simulator simulator_; - simulator::SimulatedQuartcPacketTransport client_transport_; - simulator::SimulatedQuartcPacketTransport server_transport_; - simulator::SymmetricLink client_server_link_; - - std::unique_ptr<QuartcClientEndpoint> client_endpoint_; - std::unique_ptr<QuartcPeer> client_peer_; - - std::unique_ptr<QuartcServerEndpoint> server_endpoint_; - std::unique_ptr<QuartcPeer> server_peer_; -}; - -const ReceivedMessage& FindLastMessageFromSource( - const std::vector<ReceivedMessage>& messages, - int32_t source_id) { - const auto& it = std::find_if(messages.rbegin(), messages.rend(), - [source_id](const ReceivedMessage& r) { - return r.frame.source_id == source_id; - }); - return *it; -} - -TEST_F(QuartcPeerTest, SendReceiveMessages) { - QuicTime start_time = simulator_.GetClock()->Now(); - - QuartcDataSource::Config config; - config.id = 1; - - CreatePeers({config}); - Connect(); - WaitForMessages(); - - QuicTime end_time = simulator_.GetClock()->Now(); - - // Sanity checks on messages. - const ReceivedMessage& client_message = client_peer_->received_messages()[0]; - EXPECT_EQ(client_message.frame.source_id, 1); - EXPECT_EQ(client_message.frame.sequence_number, 0); - EXPECT_GE(client_message.frame.send_time, start_time); - EXPECT_LE(client_message.receive_time, end_time); - - const ReceivedMessage& server_message = server_peer_->received_messages()[0]; - EXPECT_EQ(server_message.frame.source_id, 1); - EXPECT_EQ(server_message.frame.sequence_number, 0); - EXPECT_GE(server_message.frame.send_time, start_time); - EXPECT_LE(server_message.receive_time, end_time); -} - -TEST_F(QuartcPeerTest, MaxFrameSizeUnset) { - // Configure the source with no max frame size, and a framerate and max - // bandwidth that allows very large frames (larger than will fit in a packet). - QuartcDataSource::Config config; - config.id = 1; - config.frame_interval = QuicTime::Delta::FromMilliseconds(20); - config.max_bandwidth = QuicBandwidth::FromBytesAndTimeDelta( - 2 * kDefaultMaxPacketSize, config.frame_interval); - - CreatePeers({config}); - Connect(); - RampUpBandwidth(kLinkBandwidth); - WaitForMessages(); - - // The peers generate frames that fit in one packet. - EXPECT_LT(client_peer_->received_messages().back().frame.size, - kDefaultMaxPacketSize); - EXPECT_LT(server_peer_->received_messages().back().frame.size, - kDefaultMaxPacketSize); -} - -TEST_F(QuartcPeerTest, MaxFrameSizeLargerThanPacketSize) { - // Configure the source with a max frame size larger than the packet size. - QuartcDataSource::Config config; - config.id = 1; - config.max_frame_size = 2 * kDefaultMaxPacketSize; - - CreatePeers({config}); - Connect(); - RampUpBandwidth(kLinkBandwidth); - WaitForMessages(); - - // The peers generate frames that fit in one packet. - EXPECT_LT(client_peer_->received_messages().back().frame.size, - kDefaultMaxPacketSize); - EXPECT_LT(server_peer_->received_messages().back().frame.size, - kDefaultMaxPacketSize); -} - -TEST_F(QuartcPeerTest, MaxFrameSizeSmallerThanPacketSize) { - QuartcDataSource::Config config; - config.id = 1; - config.max_frame_size = 100; - // Note that a long frame interval helps to ensure that the test produces - // enough bytes per frame to reach max_frame_size. - config.frame_interval = QuicTime::Delta::FromMilliseconds(100); - - CreatePeers({config}); - Connect(); - RampUpBandwidth(kLinkBandwidth); - WaitForMessages(); - - EXPECT_EQ(client_peer_->received_messages().back().frame.size, 100u); - EXPECT_EQ(server_peer_->received_messages().back().frame.size, 100u); -} - -TEST_F(QuartcPeerTest, MaxFrameSizeSmallerThanFrameHeader) { - QuartcDataSource::Config config; - config.id = 1; - config.max_frame_size = kDataFrameHeaderSize - 1; - - CreatePeers({config}); - Connect(); - RampUpBandwidth(kLinkBandwidth); - WaitForMessages(); - - // Max frame sizes smaller than the header are ignored, and the frame size is - // limited by packet size. - EXPECT_LT(client_peer_->received_messages().back().frame.size, - kDefaultMaxPacketSize); - EXPECT_LT(server_peer_->received_messages().back().frame.size, - kDefaultMaxPacketSize); -} - -TEST_F(QuartcPeerTest, SendReceiveMultipleSources) { - QuicTime start_time = simulator_.GetClock()->Now(); - - // Note: use of really long frame intervals means that each source should send - // one frame during this test. This simplifies expectations for received - // data. - QuartcDataSource::Config config_1; - config_1.id = 1; - config_1.max_bandwidth = QuicBandwidth::FromKBitsPerSecond(32); - config_1.frame_interval = QuicTime::Delta::FromSeconds(10); - - QuartcDataSource::Config config_2; - config_2.id = 2; - config_2.max_bandwidth = QuicBandwidth::FromKBitsPerSecond(64); - config_2.frame_interval = QuicTime::Delta::FromSeconds(10); - - QuartcDataSource::Config config_3; - config_3.id = 3; - config_3.max_bandwidth = QuicBandwidth::FromKBitsPerSecond(128); - config_3.frame_interval = QuicTime::Delta::FromSeconds(10); - - CreatePeers({config_1, config_2, config_3}); - Connect(); - - ASSERT_TRUE(simulator_.RunUntil([this] { - return client_peer_->received_messages().size() == 3 && - server_peer_->received_messages().size() == 3; - })); - - QuicTime end_time = simulator_.GetClock()->Now(); - - // Sanity checks on messages. - const auto& order = [](const ReceivedMessage& lhs, - const ReceivedMessage& rhs) { - return lhs.frame.source_id < rhs.frame.source_id; - }; - - std::vector<ReceivedMessage> client_messages = - client_peer_->received_messages(); - std::sort(client_messages.begin(), client_messages.end(), order); - for (size_t i = 0; i < client_messages.size(); ++i) { - EXPECT_EQ(client_messages[i].frame.source_id, static_cast<int32_t>(i + 1)); - EXPECT_EQ(client_messages[i].frame.sequence_number, 0); - EXPECT_GE(client_messages[i].frame.send_time, start_time); - EXPECT_LE(client_messages[i].receive_time, end_time); - } - if (GetQuicReloadableFlag(quic_advance_ack_timeout_update)) { - // ACK frame bundling changes packet sequencing. - // TODO(fayang): Fix this test. - return; - } - std::vector<ReceivedMessage> server_messages = - server_peer_->received_messages(); - std::sort(server_messages.begin(), server_messages.end(), order); - for (size_t i = 0; i < server_messages.size(); ++i) { - EXPECT_EQ(server_messages[i].frame.source_id, static_cast<int32_t>(i + 1u)); - EXPECT_EQ(server_messages[i].frame.sequence_number, 0); - EXPECT_GE(server_messages[i].frame.send_time, start_time); - EXPECT_LE(server_messages[i].receive_time, end_time); - } -} - -TEST_F(QuartcPeerTest, BandwidthAllocationWithEnoughAvailable) { - QuartcDataSource::Config config_1; - config_1.id = 1; - config_1.max_bandwidth = QuicBandwidth::FromKBitsPerSecond(32); - config_1.frame_interval = QuicTime::Delta::FromMilliseconds(100); - - QuartcDataSource::Config config_2; - config_2.id = 2; - config_2.max_bandwidth = QuicBandwidth::FromKBitsPerSecond(64); - config_2.frame_interval = QuicTime::Delta::FromMilliseconds(25); - - QuartcDataSource::Config config_3; - config_3.id = 3; - config_3.max_bandwidth = QuicBandwidth::FromKBitsPerSecond(128); - config_3.frame_interval = QuicTime::Delta::FromMilliseconds(10); - - CreatePeers({config_1, config_2, config_3}); - Connect(); - RampUpBandwidth(kLinkBandwidth); - WaitForMessages(); - - // The last message from each source should be the size allowed by that - // source's maximum bandwidth and frame interval. - QuicByteCount source_1_size = - config_1.max_bandwidth.ToBytesPerPeriod(config_1.frame_interval); - QuicByteCount source_2_size = - config_2.max_bandwidth.ToBytesPerPeriod(config_2.frame_interval); - QuicByteCount source_3_size = - config_3.max_bandwidth.ToBytesPerPeriod(config_3.frame_interval); - - const std::vector<ReceivedMessage>& client_messages = - client_peer_->received_messages(); - EXPECT_EQ(FindLastMessageFromSource(client_messages, 1).frame.size, - source_1_size); - EXPECT_EQ(FindLastMessageFromSource(client_messages, 2).frame.size, - source_2_size); - EXPECT_EQ(FindLastMessageFromSource(client_messages, 3).frame.size, - source_3_size); - - const std::vector<ReceivedMessage>& server_messages = - server_peer_->received_messages(); - EXPECT_EQ(FindLastMessageFromSource(server_messages, 1).frame.size, - source_1_size); - EXPECT_EQ(FindLastMessageFromSource(server_messages, 2).frame.size, - source_2_size); - EXPECT_EQ(FindLastMessageFromSource(server_messages, 3).frame.size, - source_3_size); -} - -TEST_F(QuartcPeerTest, BandwidthAllocationWithoutEnoughAvailable) { - QuartcDataSource::Config config_1; - config_1.id = 1; - config_1.max_bandwidth = client_server_link_.bandwidth() * 0.5; - config_1.frame_interval = QuicTime::Delta::FromMilliseconds(10); - - QuartcDataSource::Config config_2; - config_2.id = 2; - config_2.min_bandwidth = QuicBandwidth::FromKBitsPerSecond(32); - config_2.max_bandwidth = client_server_link_.bandwidth(); - config_2.frame_interval = QuicTime::Delta::FromMilliseconds(5); - - QuartcDataSource::Config config_3; - config_3.id = 3; - config_3.min_bandwidth = QuicBandwidth::FromKBitsPerSecond(32); - config_3.max_bandwidth = client_server_link_.bandwidth() * 2; - config_3.frame_interval = QuicTime::Delta::FromMilliseconds(20); - - CreatePeers({config_1, config_2, config_3}); - Connect(); - RampUpBandwidth(kLinkBandwidth); - WaitForMessages(); - - const std::vector<ReceivedMessage>& client_messages = - client_peer_->received_messages(); - const std::vector<ReceivedMessage>& server_messages = - server_peer_->received_messages(); - - // Source 1 eventually ramps up to full bandwidth. - const QuicByteCount source_1_size = - config_1.max_bandwidth.ToBytesPerPeriod(config_1.frame_interval); - EXPECT_EQ(FindLastMessageFromSource(client_messages, 1).frame.size, - source_1_size); - EXPECT_EQ(FindLastMessageFromSource(server_messages, 1).frame.size, - source_1_size); - - // Source 2 takes the remainder of available bandwidth. However, the exact - // value depends on the bandwidth estimate. - const QuicByteCount source_2_min = - config_2.min_bandwidth.ToBytesPerPeriod(config_2.frame_interval); - const QuicByteCount source_2_max = - config_2.max_bandwidth.ToBytesPerPeriod(config_2.frame_interval); - EXPECT_GT(FindLastMessageFromSource(client_messages, 2).frame.size, - source_2_min); - EXPECT_LT(FindLastMessageFromSource(client_messages, 2).frame.size, - source_2_max); - EXPECT_GT(FindLastMessageFromSource(server_messages, 2).frame.size, - source_2_min); - EXPECT_LT(FindLastMessageFromSource(server_messages, 2).frame.size, - source_2_max); - - // Source 3 gets only its minimum bandwidth. - const QuicByteCount source_3_size = - config_3.min_bandwidth.ToBytesPerPeriod(config_3.frame_interval); - EXPECT_EQ(FindLastMessageFromSource(client_messages, 3).frame.size, - source_3_size); - EXPECT_EQ(FindLastMessageFromSource(server_messages, 3).frame.size, - source_3_size); -} - -TEST_F(QuartcPeerTest, DisableAndDrainMessages) { - QuartcDataSource::Config config; - config.id = 1; - config.max_bandwidth = client_server_link_.bandwidth() * 0.5; - config.frame_interval = QuicTime::Delta::FromMilliseconds(10); - - CreatePeers({config}); - Connect(); - WaitForMessages(); - - // After these calls, we should observe no new messages. - server_peer_->SetEnabled(false); - client_peer_->SetEnabled(false); - - std::map<int32_t, int64_t> last_sent_by_client = - client_peer_->GetLastSequenceNumbers(); - std::map<int32_t, int64_t> last_sent_by_server = - server_peer_->GetLastSequenceNumbers(); - - // Note: this time is completely arbitrary, to allow time for the peers to - // generate new messages after being disabled. The point of the test is that - // they should not do that. - simulator_.RunFor(QuicTime::Delta::FromSeconds(10)); - - // Messages sent prior to disabling the peers are eventually received. - EXPECT_TRUE(simulator_.RunUntilOrTimeout( - [this, last_sent_by_client, last_sent_by_server]() mutable -> bool { - return !client_peer_->received_messages().empty() && - client_peer_->received_messages().back().frame.sequence_number == - last_sent_by_server[1] && - !server_peer_->received_messages().empty() && - server_peer_->received_messages().back().frame.sequence_number == - last_sent_by_client[1]; - }, - QuicTime::Delta::FromSeconds(60))); -} - -} // namespace -} // namespace test -} // namespace quic
diff --git a/quic/quartc/test/quic_trace_interceptor.cc b/quic/quartc/test/quic_trace_interceptor.cc deleted file mode 100644 index 6550a6f..0000000 --- a/quic/quartc/test/quic_trace_interceptor.cc +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/test/quic_trace_interceptor.h" - -#include <string> -#include <utility> - -#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test_output.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace test { - -QuicTraceInterceptor::QuicTraceInterceptor(quiche::QuicheStringPiece identifier) - : identifier_(identifier.data(), identifier.size()), delegate_(nullptr) {} - -QuicTraceInterceptor::~QuicTraceInterceptor() { - if (trace_visitor_) { - QuicRecordTrace(identifier_, trace_visitor_->trace()->SerializeAsString()); - } -} - -void QuicTraceInterceptor::OnSessionCreated(QuartcSession* session) { - trace_visitor_ = std::make_unique<QuicTraceVisitor>(session->connection()); - session->connection()->set_debug_visitor(trace_visitor_.get()); - - delegate_->OnSessionCreated(session); -} - -void QuicTraceInterceptor::OnCryptoHandshakeComplete() { - delegate_->OnCryptoHandshakeComplete(); -} - -void QuicTraceInterceptor::OnConnectionWritable() { - delegate_->OnConnectionWritable(); -} - -void QuicTraceInterceptor::OnIncomingStream(QuartcStream* stream) { - delegate_->OnIncomingStream(stream); -} - -void QuicTraceInterceptor::OnCongestionControlChange( - QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) { - delegate_->OnCongestionControlChange(bandwidth_estimate, pacing_rate, - latest_rtt); -} - -void QuicTraceInterceptor::OnConnectionClosed( - const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) { - delegate_->OnConnectionClosed(frame, source); -} - -void QuicTraceInterceptor::OnMessageReceived( - quiche::QuicheStringPiece message) { - delegate_->OnMessageReceived(message); -} - -void QuicTraceInterceptor::OnMessageSent(int64_t datagram_id) { - delegate_->OnMessageSent(datagram_id); -} - -void QuicTraceInterceptor::OnMessageAcked(int64_t datagram_id, - QuicTime receive_timestamp) { - delegate_->OnMessageAcked(datagram_id, receive_timestamp); -} - -void QuicTraceInterceptor::OnMessageLost(int64_t datagram_id) { - delegate_->OnMessageLost(datagram_id); -} - -void QuicTraceInterceptor::SetDelegate(QuartcEndpoint::Delegate* delegate) { - DCHECK(delegate != nullptr); - delegate_ = delegate; -} - -} // namespace test -} // namespace quic
diff --git a/quic/quartc/test/quic_trace_interceptor.h b/quic/quartc/test/quic_trace_interceptor.h deleted file mode 100644 index 378133d..0000000 --- a/quic/quartc/test/quic_trace_interceptor.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright (c) 2019 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 QUICHE_QUIC_QUARTC_TEST_QUIC_TRACE_INTERCEPTOR_H_ -#define QUICHE_QUIC_QUARTC_TEST_QUIC_TRACE_INTERCEPTOR_H_ - -#include <string> - -#include "net/third_party/quiche/src/quic/core/quic_connection.h" -#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/core/quic_trace_visitor.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" -#include "net/third_party/quiche/src/quic/quartc/quartc_session.h" -#include "net/third_party/quiche/src/quic/quartc/test/bidi_test_runner.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace quic { -namespace test { - -class QuicTraceInterceptor : public QuartcEndpointInterceptor { - public: - // Creates a trace visitor that records its output using the given identifier. - // |identifier| is combined with the test name and timestamp to form a - // filename for the trace. - explicit QuicTraceInterceptor(quiche::QuicheStringPiece identifier); - ~QuicTraceInterceptor() override; - - // QuartcEndpointIntercept overrides. - void OnSessionCreated(QuartcSession* session) override; - void OnCryptoHandshakeComplete() override; - void OnConnectionWritable() override; - void OnIncomingStream(QuartcStream* stream) override; - void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, - QuicBandwidth pacing_rate, - QuicTime::Delta latest_rtt) override; - void OnConnectionClosed(const QuicConnectionCloseFrame& frame, - ConnectionCloseSource source) override; - void OnMessageReceived(quiche::QuicheStringPiece message) override; - void OnMessageSent(int64_t datagram_id) override; - void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp) override; - void OnMessageLost(int64_t datagram_id) override; - void SetDelegate(QuartcEndpoint::Delegate* delegate) override; - - private: - const std::string identifier_; - std::unique_ptr<QuicTraceVisitor> trace_visitor_; - QuartcEndpoint::Delegate* delegate_; -}; - -} // namespace test -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_TEST_QUIC_TRACE_INTERCEPTOR_H_
diff --git a/quic/quartc/test/random_delay_link.cc b/quic/quartc/test/random_delay_link.cc deleted file mode 100644 index e4cfcac..0000000 --- a/quic/quartc/test/random_delay_link.cc +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/test/random_delay_link.h" - -#include <cmath> -#include <cstdint> - -#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/port.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" - -namespace quic { -namespace simulator { -namespace { - -// Number of buckets used to define an exponential distribution. -constexpr int64_t kNumBuckets = static_cast<int64_t>(2) << 32; - -} // namespace - -RandomDelayLink::RandomDelayLink(Simulator* simulator, - std::string name, - UnconstrainedPortInterface* sink, - QuicBandwidth bandwidth, - QuicTime::Delta propagation_delay) - : OneWayLink(simulator, name, sink, bandwidth, propagation_delay), - median_random_delay_(QuicTime::Delta::Zero()) {} - -RandomDelayLink::~RandomDelayLink() {} - -QuicTime::Delta RandomDelayLink::GetRandomDelay( - QuicTime::Delta /*transfer_time*/) { - // Computes a random delay following an exponential distribution, with median - // value |median_random_delay_|. Choose a uniform random value between 1 and - // kNumBuckets, convert this to an exponential, then scale it such that a - // random value from the middle of the distribution (0.5) corresponds to - // |median_random_delay_|. - return std::log( - static_cast<double>( - simulator_->GetRandomGenerator()->RandUint64() % kNumBuckets + - 1) / - kNumBuckets) / - std::log(0.5) * median_random_delay_; -} - -SymmetricRandomDelayLink::SymmetricRandomDelayLink( - Simulator* simulator, - std::string name, - UnconstrainedPortInterface* sink_a, - UnconstrainedPortInterface* sink_b, - QuicBandwidth bandwidth, - QuicTime::Delta propagation_delay) - : a_to_b_link_(simulator, - quiche::QuicheStringPrintf("%s (A-to-B)", name.c_str()), - sink_b, - bandwidth, - propagation_delay), - b_to_a_link_(simulator, - quiche::QuicheStringPrintf("%s (B-to-A)", name.c_str()), - sink_a, - bandwidth, - propagation_delay) {} - -SymmetricRandomDelayLink::SymmetricRandomDelayLink( - Endpoint* endpoint_a, - Endpoint* endpoint_b, - QuicBandwidth bandwidth, - QuicTime::Delta propagation_delay) - : SymmetricRandomDelayLink( - endpoint_a->simulator(), - quiche::QuicheStringPrintf("Link [%s]<->[%s]", - endpoint_a->name().c_str(), - endpoint_b->name().c_str()), - endpoint_a->GetRxPort(), - endpoint_b->GetRxPort(), - bandwidth, - propagation_delay) { - endpoint_a->SetTxPort(&a_to_b_link_); - endpoint_b->SetTxPort(&b_to_a_link_); -} - -} // namespace simulator -} // namespace quic
diff --git a/quic/quartc/test/random_delay_link.h b/quic/quartc/test/random_delay_link.h deleted file mode 100644 index 45f978e..0000000 --- a/quic/quartc/test/random_delay_link.h +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright (c) 2019 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 QUICHE_QUIC_QUARTC_TEST_RANDOM_DELAY_LINK_H_ -#define QUICHE_QUIC_QUARTC_TEST_RANDOM_DELAY_LINK_H_ - -#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" -#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" -#include "net/third_party/quiche/src/quic/core/quic_time.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/port.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" - -namespace quic { -namespace simulator { - -// A reliable simplex link between two endpoints with constrained bandwidth. A -// random delay is added to each packet. The random values are chosen -// separately for each packet, following an exponential distribution. -class RandomDelayLink : public OneWayLink { - public: - RandomDelayLink(Simulator* simulator, - std::string name, - UnconstrainedPortInterface* sink, - QuicBandwidth bandwidth, - QuicTime::Delta propagation_delay); - RandomDelayLink(const RandomDelayLink&) = delete; - RandomDelayLink& operator=(const RandomDelayLink&) = delete; - ~RandomDelayLink() override; - - // Sets the median value of the random delay introduced by this link. Random - // delays are chosen according to an exponential distribution, clipped and - // scaled to reach this as a median value. - inline void set_median_random_delay(QuicTime::Delta delta) { - median_random_delay_ = delta; - } - - protected: - QuicTime::Delta GetRandomDelay(QuicTime::Delta transfer_time) override; - - private: - QuicTime::Delta median_random_delay_; -}; - -// A full-duplex link between two endpoints, functionally equivalent to two -// RandomDelayLink objects tied together. -class SymmetricRandomDelayLink { - public: - SymmetricRandomDelayLink(Simulator* simulator, - std::string name, - UnconstrainedPortInterface* sink_a, - UnconstrainedPortInterface* sink_b, - QuicBandwidth bandwidth, - QuicTime::Delta propagation_delay); - SymmetricRandomDelayLink(Endpoint* endpoint_a, - Endpoint* endpoint_b, - QuicBandwidth bandwidth, - QuicTime::Delta propagation_delay); - SymmetricRandomDelayLink(const SymmetricRandomDelayLink&) = delete; - SymmetricRandomDelayLink& operator=(const SymmetricRandomDelayLink&) = delete; - - inline QuicBandwidth bandwidth() { return a_to_b_link_.bandwidth(); } - - inline void set_median_random_delay(QuicTime::Delta delay) { - a_to_b_link_.set_median_random_delay(delay); - b_to_a_link_.set_median_random_delay(delay); - } - - private: - RandomDelayLink a_to_b_link_; - RandomDelayLink b_to_a_link_; -}; - -} // namespace simulator -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_TEST_RANDOM_DELAY_LINK_H_
diff --git a/quic/quartc/test/random_packet_filter.cc b/quic/quartc/test/random_packet_filter.cc deleted file mode 100644 index a40748f..0000000 --- a/quic/quartc/test/random_packet_filter.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright (c) 2019 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/third_party/quiche/src/quic/quartc/test/random_packet_filter.h" - -namespace quic { -namespace simulator { - -RandomPacketFilter::RandomPacketFilter(Simulator* simulator, - const std::string& name, - Endpoint* endpoint) - : PacketFilter(simulator, name, endpoint), simulator_(simulator) {} - -bool RandomPacketFilter::FilterPacket(const Packet& /*packet*/) { - uint64_t random = simulator_->GetRandomGenerator()->RandUint64(); - return 100 * static_cast<double>(random) / - std::numeric_limits<uint64_t>::max() >= - loss_percent_; -} - -} // namespace simulator -} // namespace quic
diff --git a/quic/quartc/test/random_packet_filter.h b/quic/quartc/test/random_packet_filter.h deleted file mode 100644 index b97d498..0000000 --- a/quic/quartc/test/random_packet_filter.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright (c) 2019 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 QUICHE_QUIC_QUARTC_TEST_RANDOM_PACKET_FILTER_H_ -#define QUICHE_QUIC_QUARTC_TEST_RANDOM_PACKET_FILTER_H_ - -#include "net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/port.h" -#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" - -namespace quic { -namespace simulator { - -// Packet filter which randomly drops packets. -class RandomPacketFilter : public PacketFilter { - public: - RandomPacketFilter(Simulator* simulator, - const std::string& name, - Endpoint* endpoint); - - void set_loss_percent(double loss_percent) { - DCHECK_GE(loss_percent, 0); - DCHECK_LE(loss_percent, 100); - loss_percent_ = loss_percent; - } - - protected: - bool FilterPacket(const Packet& packet) override; - - private: - Simulator* simulator_; - double loss_percent_ = 0; -}; - -} // namespace simulator -} // namespace quic - -#endif // QUICHE_QUIC_QUARTC_TEST_RANDOM_PACKET_FILTER_H_