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