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 11 #include "url/gurl.h" 12 #include "url/origin.h" 13 #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" 14 #include "net/third_party/quiche/src/quic/core/quic_config.h" 15 #include "net/third_party/quiche/src/quic/core/quic_connection.h" 16 #include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h" 17 #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" 18 #include "net/third_party/quiche/src/quic/core/quic_server_id.h" 19 #include "net/third_party/quiche/src/quic/core/quic_session.h" 20 #include "net/third_party/quiche/src/quic/core/quic_stream.h" 21 #include "net/third_party/quiche/src/quic/core/quic_versions.h" 22 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" 23 #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" 24 #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h" 25 #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h" 26 #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h" 27 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" 28 29 namespace quic { 30 31 // A client session for the QuicTransport protocol. 32 class QUIC_EXPORT_PRIVATE QuicTransportClientSession 33 : public QuicSession, 34 public QuicTransportSessionInterface { 35 public: 36 class QUIC_EXPORT_PRIVATE ClientVisitor { 37 public: ~ClientVisitor()38 virtual ~ClientVisitor() {} 39 40 // Notifies the visitor when the client indication has been sent and the 41 // connection is ready to exchange application data. 42 virtual void OnSessionReady() = 0; 43 44 // Notifies the visitor when a new stream has been received. The stream in 45 // question can be retrieved using AcceptIncomingBidirectionalStream() or 46 // AcceptIncomingUnidirectionalStream(). 47 virtual void OnIncomingBidirectionalStreamAvailable() = 0; 48 virtual void OnIncomingUnidirectionalStreamAvailable() = 0; 49 50 // Notifies the visitor when a new datagram has been received. 51 virtual void OnDatagramReceived(quiche::QuicheStringPiece datagram) = 0; 52 53 // Notifies the visitor that a new outgoing stream can now be created. 54 virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0; 55 virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0; 56 }; 57 58 QuicTransportClientSession(QuicConnection* connection, 59 Visitor* owner, 60 const QuicConfig& config, 61 const ParsedQuicVersionVector& supported_versions, 62 const GURL& url, 63 QuicCryptoClientConfig* crypto_config, 64 url::Origin origin, 65 ClientVisitor* visitor); 66 GetAlpnsToOffer()67 std::vector<std::string> GetAlpnsToOffer() const override { 68 return std::vector<std::string>({QuicTransportAlpn()}); 69 } 70 void OnAlpnSelected(quiche::QuicheStringPiece alpn) override; alpn_received()71 bool alpn_received() const { return alpn_received_; } 72 CryptoConnect()73 void CryptoConnect() { crypto_stream_->CryptoConnect(); } 74 ShouldKeepConnectionAlive()75 bool ShouldKeepConnectionAlive() const override { return true; } 76 GetMutableCryptoStream()77 QuicCryptoStream* GetMutableCryptoStream() override { 78 return crypto_stream_.get(); 79 } GetCryptoStream()80 const QuicCryptoStream* GetCryptoStream() const override { 81 return crypto_stream_.get(); 82 } 83 84 // Returns true once the encryption has been established and the client 85 // indication has been sent. No application data will be read or written 86 // before the connection is ready. Once the connection becomes ready, this 87 // method will never return false. IsSessionReady()88 bool IsSessionReady() const override { return ready_; } 89 90 QuicStream* CreateIncomingStream(QuicStreamId id) override; CreateIncomingStream(PendingStream *)91 QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override { 92 QUIC_BUG << "QuicTransportClientSession::CreateIncomingStream(" 93 "PendingStream) not implemented"; 94 return nullptr; 95 } 96 97 void SetDefaultEncryptionLevel(EncryptionLevel level) override; 98 void OnOneRttKeysAvailable() override; 99 void OnMessageReceived(quiche::QuicheStringPiece message) override; 100 101 // Return the earliest incoming stream that has been received by the session 102 // but has not been accepted. Returns nullptr if there are no incoming 103 // streams. 104 QuicTransportStream* AcceptIncomingBidirectionalStream(); 105 QuicTransportStream* AcceptIncomingUnidirectionalStream(); 106 107 using QuicSession::CanOpenNextOutgoingBidirectionalStream; 108 using QuicSession::CanOpenNextOutgoingUnidirectionalStream; 109 QuicTransportStream* OpenOutgoingBidirectionalStream(); 110 QuicTransportStream* OpenOutgoingUnidirectionalStream(); 111 112 using QuicSession::datagram_queue; 113 114 protected: 115 class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream { 116 public: 117 using QuicStream::QuicStream; 118 119 // This method should never be called, since the stream is client-initiated 120 // unidirectional. OnDataAvailable()121 void OnDataAvailable() override { 122 QUIC_BUG << "Received data on a write-only stream"; 123 } 124 }; 125 126 // Creates and activates a QuicTransportStream for the given ID. 127 QuicTransportStream* CreateStream(QuicStreamId id); 128 129 // Serializes the client indication as described in 130 // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2 131 std::string SerializeClientIndication(); 132 // Creates the client indication stream and sends the client indication on it. 133 void SendClientIndication(); 134 135 void OnCanCreateNewOutgoingStream(bool unidirectional) override; 136 137 std::unique_ptr<QuicCryptoClientStream> crypto_stream_; 138 GURL url_; 139 url::Origin origin_; 140 ClientVisitor* visitor_; // not owned 141 bool client_indication_sent_ = false; 142 bool alpn_received_ = false; 143 bool ready_ = false; 144 145 // Contains all of the streams that has been received by the session but have 146 // not been processed by the application. 147 // TODO(vasilvv): currently, we always send MAX_STREAMS as long as the overall 148 // maximum number of streams for the connection has not been exceeded. We 149 // should also limit the maximum number of streams that the consuming code 150 // has not accepted to a smaller number, by checking the size of 151 // |incoming_bidirectional_streams_| and |incoming_unidirectional_streams_| 152 // before sending MAX_STREAMS. 153 QuicCircularDeque<QuicTransportStream*> incoming_bidirectional_streams_; 154 QuicCircularDeque<QuicTransportStream*> incoming_unidirectional_streams_; 155 }; 156 157 } // namespace quic 158 159 #endif // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_ 160