| // Copyright 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_MASQUE_MASQUE_CLIENT_SESSION_H_ | |
| #define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_ | |
| #include <string> | |
| #include "absl/container/flat_hash_map.h" | |
| #include "absl/strings/string_view.h" | |
| #include "quiche/quic/core/http/quic_spdy_client_session.h" | |
| #include "quiche/quic/masque/masque_utils.h" | |
| #include "quiche/quic/platform/api/quic_export.h" | |
| #include "quiche/quic/platform/api/quic_socket_address.h" | |
| namespace quic { | |
| // QUIC client session for connection to MASQUE proxy. This session establishes | |
| // a connection to a MASQUE proxy and handles sending and receiving DATAGRAM | |
| // frames for operation of the MASQUE protocol. Multiple end-to-end encapsulated | |
| // sessions can then coexist inside this session. Once these are created, they | |
| // need to be registered with this session. | |
| class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession { | |
| public: | |
| // Interface meant to be implemented by the owner of the | |
| // MasqueClientSession instance. | |
| class QUIC_NO_EXPORT Owner { | |
| public: | |
| virtual ~Owner() {} | |
| // Notifies the owner that a settings frame has been received. | |
| virtual void OnSettingsReceived() = 0; | |
| }; | |
| // Interface meant to be implemented by encapsulated client sessions, i.e. | |
| // the end-to-end QUIC client sessions that run inside MASQUE encapsulation. | |
| class QUIC_NO_EXPORT EncapsulatedClientSession { | |
| public: | |
| virtual ~EncapsulatedClientSession() {} | |
| // Process packet that was just decapsulated. | |
| virtual void ProcessPacket(absl::string_view packet, | |
| QuicSocketAddress target_server_address) = 0; | |
| // Close the encapsulated connection. | |
| virtual void CloseConnection( | |
| QuicErrorCode error, const std::string& details, | |
| ConnectionCloseBehavior connection_close_behavior) = 0; | |
| }; | |
| // Takes ownership of |connection|, but not of |crypto_config| or | |
| // |push_promise_index| or |owner|. All pointers must be non-null. Caller | |
| // must ensure that |push_promise_index| and |owner| stay valid for the | |
| // lifetime of the newly created MasqueClientSession. | |
| MasqueClientSession(MasqueMode masque_mode, const std::string& uri_template, | |
| const QuicConfig& config, | |
| const ParsedQuicVersionVector& supported_versions, | |
| QuicConnection* connection, const QuicServerId& server_id, | |
| QuicCryptoClientConfig* crypto_config, | |
| QuicClientPushPromiseIndex* push_promise_index, | |
| Owner* owner); | |
| // Disallow copy and assign. | |
| MasqueClientSession(const MasqueClientSession&) = delete; | |
| MasqueClientSession& operator=(const MasqueClientSession&) = delete; | |
| // From QuicSession. | |
| void OnMessageAcked(QuicMessageId message_id, | |
| QuicTime receive_timestamp) override; | |
| void OnMessageLost(QuicMessageId message_id) override; | |
| void OnConnectionClosed(const QuicConnectionCloseFrame& frame, | |
| ConnectionCloseSource source) override; | |
| void OnStreamClosed(QuicStreamId stream_id) override; | |
| // From QuicSpdySession. | |
| bool OnSettingsFrame(const SettingsFrame& frame) override; | |
| // Send encapsulated packet. | |
| void SendPacket(absl::string_view packet, | |
| const QuicSocketAddress& target_server_address, | |
| EncapsulatedClientSession* encapsulated_client_session); | |
| // Close CONNECT-UDP stream tied to this encapsulated client session. | |
| void CloseConnectUdpStream( | |
| EncapsulatedClientSession* encapsulated_client_session); | |
| private: | |
| // State that the MasqueClientSession keeps for each CONNECT-UDP request. | |
| class QUIC_NO_EXPORT ConnectUdpClientState | |
| : public QuicSpdyStream::Http3DatagramVisitor { | |
| public: | |
| // |stream| and |encapsulated_client_session| must be valid for the lifetime | |
| // of the ConnectUdpClientState. | |
| explicit ConnectUdpClientState( | |
| QuicSpdyClientStream* stream, | |
| EncapsulatedClientSession* encapsulated_client_session, | |
| MasqueClientSession* masque_session, | |
| const QuicSocketAddress& target_server_address); | |
| ~ConnectUdpClientState(); | |
| // Disallow copy but allow move. | |
| ConnectUdpClientState(const ConnectUdpClientState&) = delete; | |
| ConnectUdpClientState(ConnectUdpClientState&&); | |
| ConnectUdpClientState& operator=(const ConnectUdpClientState&) = delete; | |
| ConnectUdpClientState& operator=(ConnectUdpClientState&&); | |
| QuicSpdyClientStream* stream() const { return stream_; } | |
| EncapsulatedClientSession* encapsulated_client_session() const { | |
| return encapsulated_client_session_; | |
| } | |
| const QuicSocketAddress& target_server_address() const { | |
| return target_server_address_; | |
| } | |
| // From QuicSpdyStream::Http3DatagramVisitor. | |
| void OnHttp3Datagram(QuicStreamId stream_id, | |
| absl::string_view payload) override; | |
| private: | |
| QuicSpdyClientStream* stream_; // Unowned. | |
| EncapsulatedClientSession* encapsulated_client_session_; // Unowned. | |
| MasqueClientSession* masque_session_; // Unowned. | |
| QuicSocketAddress target_server_address_; | |
| }; | |
| HttpDatagramSupport LocalHttpDatagramSupport() override { | |
| return HttpDatagramSupport::kDraft09; | |
| } | |
| const ConnectUdpClientState* GetOrCreateConnectUdpClientState( | |
| const QuicSocketAddress& target_server_address, | |
| EncapsulatedClientSession* encapsulated_client_session); | |
| MasqueMode masque_mode_; | |
| std::string uri_template_; | |
| std::list<ConnectUdpClientState> connect_udp_client_states_; | |
| Owner* owner_; // Unowned; | |
| }; | |
| } // namespace quic | |
| #endif // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_ |