blob: 51f35ce9f37db61536176c58e6b94d265cf518ac [file] [log] [blame]
// 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_error_codes.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_clock.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.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"
namespace quic {
// Private implementation of QuartcEndpoint. Enables different implementations
// for client and server endpoints.
class QuartcEndpointImpl {
public:
virtual ~QuartcEndpointImpl() = default;
virtual QuicStringPiece server_crypto_config() const = 0;
};
// 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,
QuicStringPiece 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(QuicStringPiece 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().
QuicStringPiece 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_