| // Copyright (c) 2019 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_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_ |
| #define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_ |
| |
| #include <cstdint> |
| #include <memory> |
| |
| #include "absl/strings/string_view.h" |
| #include "url/gurl.h" |
| #include "url/origin.h" |
| #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" |
| #include "net/third_party/quiche/src/quic/core/quic_config.h" |
| #include "net/third_party/quiche/src/quic/core/quic_connection.h" |
| #include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h" |
| #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" |
| #include "net/third_party/quiche/src/quic/core/quic_datagram_queue.h" |
| #include "net/third_party/quiche/src/quic/core/quic_server_id.h" |
| #include "net/third_party/quiche/src/quic/core/quic_session.h" |
| #include "net/third_party/quiche/src/quic/core/quic_stream.h" |
| #include "net/third_party/quiche/src/quic/core/quic_versions.h" |
| #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" |
| #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" |
| #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h" |
| #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h" |
| #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h" |
| |
| namespace quic { |
| |
| // A client session for the QuicTransport protocol. |
| class QUIC_EXPORT_PRIVATE QuicTransportClientSession |
| : public QuicSession, |
| public QuicTransportSessionInterface, |
| public QuicCryptoClientStream::ProofHandler { |
| public: |
| class QUIC_EXPORT_PRIVATE ClientVisitor { |
| public: |
| virtual ~ClientVisitor() {} |
| |
| // Notifies the visitor when the client indication has been sent and the |
| // connection is ready to exchange application data. |
| virtual void OnSessionReady() = 0; |
| |
| // Notifies the visitor when a new stream has been received. The stream in |
| // question can be retrieved using AcceptIncomingBidirectionalStream() or |
| // AcceptIncomingUnidirectionalStream(). |
| virtual void OnIncomingBidirectionalStreamAvailable() = 0; |
| virtual void OnIncomingUnidirectionalStreamAvailable() = 0; |
| |
| // Notifies the visitor when a new datagram has been received. |
| virtual void OnDatagramReceived(absl::string_view datagram) = 0; |
| |
| // Notifies the visitor that a new outgoing stream can now be created. |
| virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0; |
| virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0; |
| }; |
| |
| QuicTransportClientSession( |
| QuicConnection* connection, |
| Visitor* owner, |
| const QuicConfig& config, |
| const ParsedQuicVersionVector& supported_versions, |
| const GURL& url, |
| QuicCryptoClientConfig* crypto_config, |
| url::Origin origin, |
| ClientVisitor* visitor, |
| std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer); |
| |
| std::vector<std::string> GetAlpnsToOffer() const override { |
| return std::vector<std::string>({QuicTransportAlpn()}); |
| } |
| void OnAlpnSelected(absl::string_view alpn) override; |
| bool alpn_received() const { return alpn_received_; } |
| |
| void CryptoConnect() { crypto_stream_->CryptoConnect(); } |
| |
| bool ShouldKeepConnectionAlive() const override { return true; } |
| |
| QuicCryptoStream* GetMutableCryptoStream() override { |
| return crypto_stream_.get(); |
| } |
| const QuicCryptoStream* GetCryptoStream() const override { |
| return crypto_stream_.get(); |
| } |
| |
| // Returns true once the encryption has been established and the client |
| // indication has been sent. No application data will be read or written |
| // before the connection is ready. Once the connection becomes ready, this |
| // method will never return false. |
| bool IsSessionReady() const override { return ready_; } |
| |
| QuicStream* CreateIncomingStream(QuicStreamId id) override; |
| QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override { |
| QUIC_BUG << "QuicTransportClientSession::CreateIncomingStream(" |
| "PendingStream) not implemented"; |
| return nullptr; |
| } |
| |
| void SetDefaultEncryptionLevel(EncryptionLevel level) override; |
| void OnTlsHandshakeComplete() override; |
| void OnMessageReceived(absl::string_view message) override; |
| |
| // Return the earliest incoming stream that has been received by the session |
| // but has not been accepted. Returns nullptr if there are no incoming |
| // streams. |
| QuicTransportStream* AcceptIncomingBidirectionalStream(); |
| QuicTransportStream* AcceptIncomingUnidirectionalStream(); |
| |
| using QuicSession::CanOpenNextOutgoingBidirectionalStream; |
| using QuicSession::CanOpenNextOutgoingUnidirectionalStream; |
| QuicTransportStream* OpenOutgoingBidirectionalStream(); |
| QuicTransportStream* OpenOutgoingUnidirectionalStream(); |
| |
| using QuicSession::datagram_queue; |
| |
| // QuicCryptoClientStream::ProofHandler implementation. |
| void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override; |
| void OnProofVerifyDetailsAvailable( |
| const ProofVerifyDetails& verify_details) override; |
| |
| protected: |
| class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream { |
| public: |
| using QuicStream::QuicStream; |
| |
| // This method should never be called, since the stream is client-initiated |
| // unidirectional. |
| void OnDataAvailable() override { |
| QUIC_BUG << "Received data on a write-only stream"; |
| } |
| }; |
| |
| // Creates and activates a QuicTransportStream for the given ID. |
| QuicTransportStream* CreateStream(QuicStreamId id); |
| |
| // Serializes the client indication as described in |
| // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2 |
| std::string SerializeClientIndication(); |
| // Creates the client indication stream and sends the client indication on it. |
| void SendClientIndication(); |
| |
| void OnCanCreateNewOutgoingStream(bool unidirectional) override; |
| |
| std::unique_ptr<QuicCryptoClientStream> crypto_stream_; |
| GURL url_; |
| url::Origin origin_; |
| ClientVisitor* visitor_; // not owned |
| bool client_indication_sent_ = false; |
| bool alpn_received_ = false; |
| bool ready_ = false; |
| |
| // Contains all of the streams that has been received by the session but have |
| // not been processed by the application. |
| // TODO(vasilvv): currently, we always send MAX_STREAMS as long as the overall |
| // maximum number of streams for the connection has not been exceeded. We |
| // should also limit the maximum number of streams that the consuming code |
| // has not accepted to a smaller number, by checking the size of |
| // |incoming_bidirectional_streams_| and |incoming_unidirectional_streams_| |
| // before sending MAX_STREAMS. |
| QuicCircularDeque<QuicTransportStream*> incoming_bidirectional_streams_; |
| QuicCircularDeque<QuicTransportStream*> incoming_unidirectional_streams_; |
| }; |
| |
| } // namespace quic |
| |
| #endif // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_ |