vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 1 | // Copyright (c) 2019 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_ |
| 6 | #define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_ |
| 7 | |
| 8 | #include <cstdint> |
| 9 | #include <memory> |
| 10 | |
vasilvv | 74b1661 | 2020-10-09 11:42:53 -0700 | [diff] [blame] | 11 | #include "absl/strings/string_view.h" |
vasilvv | e58d0f1 | 2019-12-04 14:35:25 -0800 | [diff] [blame] | 12 | #include "url/gurl.h" |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 13 | #include "url/origin.h" |
QUICHE team | 5be974e | 2020-12-29 18:35:24 -0500 | [diff] [blame] | 14 | #include "quic/core/crypto/quic_crypto_client_config.h" |
| 15 | #include "quic/core/quic_config.h" |
| 16 | #include "quic/core/quic_connection.h" |
| 17 | #include "quic/core/quic_crypto_client_stream.h" |
| 18 | #include "quic/core/quic_crypto_stream.h" |
| 19 | #include "quic/core/quic_datagram_queue.h" |
| 20 | #include "quic/core/quic_server_id.h" |
| 21 | #include "quic/core/quic_session.h" |
| 22 | #include "quic/core/quic_stream.h" |
| 23 | #include "quic/core/quic_versions.h" |
| 24 | #include "quic/platform/api/quic_bug_tracker.h" |
| 25 | #include "quic/platform/api/quic_containers.h" |
| 26 | #include "quic/quic_transport/quic_transport_protocol.h" |
| 27 | #include "quic/quic_transport/quic_transport_session_interface.h" |
| 28 | #include "quic/quic_transport/quic_transport_stream.h" |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 29 | |
| 30 | namespace quic { |
| 31 | |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 32 | // A client session for the QuicTransport protocol. |
dschinazi | f25169a | 2019-10-23 08:12:18 -0700 | [diff] [blame] | 33 | class QUIC_EXPORT_PRIVATE QuicTransportClientSession |
vasilvv | 59dc4b6 | 2019-10-11 12:56:14 -0700 | [diff] [blame] | 34 | : public QuicSession, |
vasilvv | 636b7f2 | 2020-08-07 10:37:19 -0700 | [diff] [blame] | 35 | public QuicTransportSessionInterface, |
| 36 | public QuicCryptoClientStream::ProofHandler { |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 37 | public: |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 38 | class QUIC_EXPORT_PRIVATE ClientVisitor { |
| 39 | public: |
| 40 | virtual ~ClientVisitor() {} |
| 41 | |
vasilvv | 467b422 | 2019-12-09 16:22:11 -0800 | [diff] [blame] | 42 | // Notifies the visitor when the client indication has been sent and the |
| 43 | // connection is ready to exchange application data. |
| 44 | virtual void OnSessionReady() = 0; |
| 45 | |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 46 | // Notifies the visitor when a new stream has been received. The stream in |
| 47 | // question can be retrieved using AcceptIncomingBidirectionalStream() or |
| 48 | // AcceptIncomingUnidirectionalStream(). |
| 49 | virtual void OnIncomingBidirectionalStreamAvailable() = 0; |
| 50 | virtual void OnIncomingUnidirectionalStreamAvailable() = 0; |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 51 | |
| 52 | // Notifies the visitor when a new datagram has been received. |
vasilvv | 74b1661 | 2020-10-09 11:42:53 -0700 | [diff] [blame] | 53 | virtual void OnDatagramReceived(absl::string_view datagram) = 0; |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 54 | |
| 55 | // Notifies the visitor that a new outgoing stream can now be created. |
| 56 | virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0; |
| 57 | virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0; |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 58 | }; |
| 59 | |
QUICHE team | 20456ed | 2020-11-18 22:24:42 -0800 | [diff] [blame] | 60 | QuicTransportClientSession( |
| 61 | QuicConnection* connection, |
| 62 | Visitor* owner, |
| 63 | const QuicConfig& config, |
| 64 | const ParsedQuicVersionVector& supported_versions, |
| 65 | const GURL& url, |
| 66 | QuicCryptoClientConfig* crypto_config, |
| 67 | url::Origin origin, |
| 68 | ClientVisitor* visitor, |
| 69 | std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer); |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 70 | |
| 71 | std::vector<std::string> GetAlpnsToOffer() const override { |
vasilvv | eba61c4 | 2019-10-08 14:23:14 -0700 | [diff] [blame] | 72 | return std::vector<std::string>({QuicTransportAlpn()}); |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 73 | } |
vasilvv | 74b1661 | 2020-10-09 11:42:53 -0700 | [diff] [blame] | 74 | void OnAlpnSelected(absl::string_view alpn) override; |
vasilvv | 467b422 | 2019-12-09 16:22:11 -0800 | [diff] [blame] | 75 | bool alpn_received() const { return alpn_received_; } |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 76 | |
| 77 | void CryptoConnect() { crypto_stream_->CryptoConnect(); } |
| 78 | |
| 79 | bool ShouldKeepConnectionAlive() const override { return true; } |
| 80 | |
| 81 | QuicCryptoStream* GetMutableCryptoStream() override { |
| 82 | return crypto_stream_.get(); |
| 83 | } |
| 84 | const QuicCryptoStream* GetCryptoStream() const override { |
| 85 | return crypto_stream_.get(); |
| 86 | } |
| 87 | |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 88 | // Returns true once the encryption has been established and the client |
| 89 | // indication has been sent. No application data will be read or written |
| 90 | // before the connection is ready. Once the connection becomes ready, this |
| 91 | // method will never return false. |
vasilvv | 59dc4b6 | 2019-10-11 12:56:14 -0700 | [diff] [blame] | 92 | bool IsSessionReady() const override { return ready_; } |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 93 | |
vasilvv | 312e3a5 | 2019-10-18 15:06:14 -0700 | [diff] [blame] | 94 | QuicStream* CreateIncomingStream(QuicStreamId id) override; |
| 95 | QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override { |
| 96 | QUIC_BUG << "QuicTransportClientSession::CreateIncomingStream(" |
| 97 | "PendingStream) not implemented"; |
| 98 | return nullptr; |
| 99 | } |
| 100 | |
fayang | d58736d | 2019-11-27 13:35:31 -0800 | [diff] [blame] | 101 | void SetDefaultEncryptionLevel(EncryptionLevel level) override; |
renjietang | c50cc4a | 2020-08-17 18:33:30 -0700 | [diff] [blame] | 102 | void OnTlsHandshakeComplete() override; |
vasilvv | 74b1661 | 2020-10-09 11:42:53 -0700 | [diff] [blame] | 103 | void OnMessageReceived(absl::string_view message) override; |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 104 | |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 105 | // Return the earliest incoming stream that has been received by the session |
| 106 | // but has not been accepted. Returns nullptr if there are no incoming |
| 107 | // streams. |
| 108 | QuicTransportStream* AcceptIncomingBidirectionalStream(); |
| 109 | QuicTransportStream* AcceptIncomingUnidirectionalStream(); |
| 110 | |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 111 | using QuicSession::CanOpenNextOutgoingBidirectionalStream; |
| 112 | using QuicSession::CanOpenNextOutgoingUnidirectionalStream; |
| 113 | QuicTransportStream* OpenOutgoingBidirectionalStream(); |
| 114 | QuicTransportStream* OpenOutgoingUnidirectionalStream(); |
| 115 | |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 116 | using QuicSession::datagram_queue; |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 117 | |
vasilvv | 636b7f2 | 2020-08-07 10:37:19 -0700 | [diff] [blame] | 118 | // QuicCryptoClientStream::ProofHandler implementation. |
| 119 | void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override; |
| 120 | void OnProofVerifyDetailsAvailable( |
| 121 | const ProofVerifyDetails& verify_details) override; |
| 122 | |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 123 | protected: |
dschinazi | f25169a | 2019-10-23 08:12:18 -0700 | [diff] [blame] | 124 | class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream { |
vasilvv | ddf5247 | 2019-10-04 15:14:02 -0700 | [diff] [blame] | 125 | public: |
| 126 | using QuicStream::QuicStream; |
| 127 | |
| 128 | // This method should never be called, since the stream is client-initiated |
| 129 | // unidirectional. |
| 130 | void OnDataAvailable() override { |
| 131 | QUIC_BUG << "Received data on a write-only stream"; |
| 132 | } |
| 133 | }; |
| 134 | |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 135 | // Creates and activates a QuicTransportStream for the given ID. |
| 136 | QuicTransportStream* CreateStream(QuicStreamId id); |
| 137 | |
vasilvv | ddf5247 | 2019-10-04 15:14:02 -0700 | [diff] [blame] | 138 | // Serializes the client indication as described in |
| 139 | // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2 |
| 140 | std::string SerializeClientIndication(); |
| 141 | // Creates the client indication stream and sends the client indication on it. |
| 142 | void SendClientIndication(); |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 143 | |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 144 | void OnCanCreateNewOutgoingStream(bool unidirectional) override; |
| 145 | |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 146 | std::unique_ptr<QuicCryptoClientStream> crypto_stream_; |
vasilvv | e58d0f1 | 2019-12-04 14:35:25 -0800 | [diff] [blame] | 147 | GURL url_; |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 148 | url::Origin origin_; |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 149 | ClientVisitor* visitor_; // not owned |
vasilvv | ddf5247 | 2019-10-04 15:14:02 -0700 | [diff] [blame] | 150 | bool client_indication_sent_ = false; |
vasilvv | 467b422 | 2019-12-09 16:22:11 -0800 | [diff] [blame] | 151 | bool alpn_received_ = false; |
vasilvv | 59dc4b6 | 2019-10-11 12:56:14 -0700 | [diff] [blame] | 152 | bool ready_ = false; |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 153 | |
| 154 | // Contains all of the streams that has been received by the session but have |
| 155 | // not been processed by the application. |
| 156 | // TODO(vasilvv): currently, we always send MAX_STREAMS as long as the overall |
| 157 | // maximum number of streams for the connection has not been exceeded. We |
| 158 | // should also limit the maximum number of streams that the consuming code |
| 159 | // has not accepted to a smaller number, by checking the size of |
| 160 | // |incoming_bidirectional_streams_| and |incoming_unidirectional_streams_| |
| 161 | // before sending MAX_STREAMS. |
wub | a750aab | 2020-02-10 06:43:15 -0800 | [diff] [blame] | 162 | QuicCircularDeque<QuicTransportStream*> incoming_bidirectional_streams_; |
| 163 | QuicCircularDeque<QuicTransportStream*> incoming_unidirectional_streams_; |
vasilvv | e6472f6 | 2019-10-02 06:50:56 -0700 | [diff] [blame] | 164 | }; |
| 165 | |
| 166 | } // namespace quic |
| 167 | |
| 168 | #endif // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_ |