|  | // 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 { | 
|  |  | 
|  | // 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_ |