| // 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/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: | 
 |     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 a session delegate, before | 
 |     // returning.  |session| is owned by the endpoint, but remains safe to use | 
 |     // until another call to |OnSessionCreated| occurs, at which point previous | 
 |     // session is destroyed. | 
 |     virtual void OnSessionCreated(QuartcSession* session) = 0; | 
 |  | 
 |     // Called if the endpoint fails to establish a session after a call to | 
 |     // Connect.  (The most likely cause is a network idle timeout.) | 
 |     virtual void OnConnectError(QuicErrorCode error, | 
 |                                 const std::string& error_details) = 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: | 
 |   // |alarm_factory|, |clock|, and |delegate| are owned by the caller and must | 
 |   // outlive the endpoint. | 
 |   QuartcClientEndpoint( | 
 |       QuicAlarmFactory* alarm_factory, | 
 |       const QuicClock* clock, | 
 |       QuicRandom* random, | 
 |       Delegate* delegate, | 
 |       const QuartcSessionConfig& config, | 
 |       QuicStringPiece serialized_server_config, | 
 |       std::unique_ptr<QuicVersionManager> version_manager = nullptr); | 
 |  | 
 |   void Connect(QuartcPacketTransport* packet_transport) 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_; | 
 |  | 
 |   // 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_ |