blob: 9de95d8a37d4bef330950dee57e07bcf18c9eaea [file] [log] [blame]
// 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 "quiche/quic/tools/quic_simple_client_session.h"
#include <utility>
#include "quiche/quic/core/quic_path_validator.h"
namespace quic {
namespace {
class QUICHE_EXPORT ServerPreferredAddressResultDelegateWithWriter
: public QuicPathValidator::ResultDelegate {
public:
explicit ServerPreferredAddressResultDelegateWithWriter(
QuicConnection* connection)
: connection_(connection) {}
// Overridden to transfer the ownership of the new writer.
void OnPathValidationSuccess(
std::unique_ptr<QuicPathValidationContext> /*context*/,
QuicTime /*start_time*/) override {
// TODO(danzh) hand over the ownership of the released writer to client and
// call the connection to migrate.
}
void OnPathValidationFailure(
std::unique_ptr<QuicPathValidationContext> context) override {
connection_->OnPathValidationFailureAtClient(/*is_multi_port=*/false,
*context);
}
private:
QuicConnection* connection_ = nullptr;
};
} // namespace
QuicSimpleClientSession::QuicSimpleClientSession(
const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
QuicConnection* connection, QuicClientBase::NetworkHelper* network_helper,
const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config,
QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body,
bool enable_web_transport)
: QuicSpdyClientSession(config, supported_versions, connection, server_id,
crypto_config, push_promise_index),
network_helper_(network_helper),
drop_response_body_(drop_response_body),
enable_web_transport_(enable_web_transport) {}
std::unique_ptr<QuicSpdyClientStream>
QuicSimpleClientSession::CreateClientStream() {
return std::make_unique<QuicSimpleClientStream>(
GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL,
drop_response_body_);
}
bool QuicSimpleClientSession::ShouldNegotiateWebTransport() {
return enable_web_transport_;
}
HttpDatagramSupport QuicSimpleClientSession::LocalHttpDatagramSupport() {
return enable_web_transport_ ? HttpDatagramSupport::kDraft04
: HttpDatagramSupport::kNone;
}
std::unique_ptr<QuicPathValidationContext>
QuicSimpleClientSession::CreateContextForMultiPortPath() {
if (!network_helper_ || connection()->multi_port_stats() == nullptr) {
return nullptr;
}
auto self_address = connection()->self_address();
auto server_address = connection()->peer_address();
if (!network_helper_->CreateUDPSocketAndBind(
server_address, self_address.host(), self_address.port() + 1)) {
return nullptr;
}
QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
if (writer == nullptr) {
return nullptr;
}
return std::make_unique<PathMigrationContext>(
std::unique_ptr<QuicPacketWriter>(writer),
network_helper_->GetLatestClientAddress(), peer_address());
}
void QuicSimpleClientSession::OnServerPreferredAddressAvailable(
const QuicSocketAddress& server_preferred_address) {
const auto self_address = connection()->self_address();
if (network_helper_ == nullptr ||
!network_helper_->CreateUDPSocketAndBind(server_preferred_address,
self_address.host(), 0)) {
return;
}
QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
if (writer == nullptr) {
return;
}
connection()->ValidatePath(
std::make_unique<PathMigrationContext>(
std::unique_ptr<QuicPacketWriter>(writer),
network_helper_->GetLatestClientAddress(), server_preferred_address),
std::make_unique<ServerPreferredAddressResultDelegateWithWriter>(
connection()));
}
} // namespace quic