blob: e055a7699be807d777c96982b7c2bc703f095194 [file] [log] [blame]
dschinazi1c99fcf2019-12-13 11:54:22 -08001// Copyright 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_MASQUE_MASQUE_CLIENT_SESSION_H_
6#define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
7
vasilvv45a59fe2021-02-02 12:07:25 -08008#include "absl/container/flat_hash_map.h"
vasilvv3049b2b2020-10-08 08:18:31 -07009#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050010#include "quic/core/http/quic_spdy_client_session.h"
11#include "quic/masque/masque_compression_engine.h"
dschinazida88cd12021-02-25 11:44:05 -080012#include "quic/masque/masque_utils.h"
QUICHE team5be974e2020-12-29 18:35:24 -050013#include "quic/platform/api/quic_export.h"
14#include "quic/platform/api/quic_socket_address.h"
dschinazi1c99fcf2019-12-13 11:54:22 -080015
16namespace quic {
17
18// QUIC client session for connection to MASQUE proxy. This session establishes
19// a connection to a MASQUE proxy and handles sending and receiving DATAGRAM
20// frames for operation of the MASQUE protocol. Multiple end-to-end encapsulated
21// sessions can then coexist inside this session. Once these are created, they
22// need to be registered with this session.
23class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
24 public:
25 // Interface meant to be implemented by the owner of the
26 // MasqueClientSession instance.
27 class QUIC_NO_EXPORT Owner {
28 public:
29 virtual ~Owner() {}
30
31 // Notifies the owner that the client connection ID is no longer in use.
32 virtual void UnregisterClientConnectionId(
33 QuicConnectionId client_connection_id) = 0;
34 };
35 // Interface meant to be implemented by encapsulated client sessions, i.e.
36 // the end-to-end QUIC client sessions that run inside MASQUE encapsulation.
37 class QUIC_NO_EXPORT EncapsulatedClientSession {
38 public:
39 virtual ~EncapsulatedClientSession() {}
40
41 // Process packet that was just decapsulated.
vasilvv3049b2b2020-10-08 08:18:31 -070042 virtual void ProcessPacket(absl::string_view packet,
dschinazida88cd12021-02-25 11:44:05 -080043 QuicSocketAddress target_server_address) = 0;
44
45 // Close the encapsulated connection.
46 virtual void CloseConnection(
47 QuicErrorCode error,
48 const std::string& details,
49 ConnectionCloseBehavior connection_close_behavior) = 0;
dschinazi1c99fcf2019-12-13 11:54:22 -080050 };
51
52 // Takes ownership of |connection|, but not of |crypto_config| or
53 // |push_promise_index| or |owner|. All pointers must be non-null. Caller
54 // must ensure that |push_promise_index| and |owner| stay valid for the
55 // lifetime of the newly created MasqueClientSession.
dschinazida88cd12021-02-25 11:44:05 -080056 MasqueClientSession(MasqueMode masque_mode,
57 const QuicConfig& config,
dschinazi1c99fcf2019-12-13 11:54:22 -080058 const ParsedQuicVersionVector& supported_versions,
59 QuicConnection* connection,
60 const QuicServerId& server_id,
61 QuicCryptoClientConfig* crypto_config,
62 QuicClientPushPromiseIndex* push_promise_index,
63 Owner* owner);
64
65 // Disallow copy and assign.
66 MasqueClientSession(const MasqueClientSession&) = delete;
67 MasqueClientSession& operator=(const MasqueClientSession&) = delete;
68
69 // From QuicSession.
vasilvv3049b2b2020-10-08 08:18:31 -070070 void OnMessageReceived(absl::string_view message) override;
dschinazi1c99fcf2019-12-13 11:54:22 -080071 void OnMessageAcked(QuicMessageId message_id,
72 QuicTime receive_timestamp) override;
dschinazi1c99fcf2019-12-13 11:54:22 -080073 void OnMessageLost(QuicMessageId message_id) override;
dschinazida88cd12021-02-25 11:44:05 -080074 void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
75 ConnectionCloseSource source) override;
76 void OnStreamClosed(QuicStreamId stream_id) override;
dschinazi1c99fcf2019-12-13 11:54:22 -080077
78 // Send encapsulated packet.
79 void SendPacket(QuicConnectionId client_connection_id,
80 QuicConnectionId server_connection_id,
vasilvv3049b2b2020-10-08 08:18:31 -070081 absl::string_view packet,
dschinazida88cd12021-02-25 11:44:05 -080082 const QuicSocketAddress& target_server_address,
83 EncapsulatedClientSession* encapsulated_client_session);
dschinazi1c99fcf2019-12-13 11:54:22 -080084
85 // Register encapsulated client. This allows clients that are encapsulated
86 // within this MASQUE session to indicate they own a given client connection
87 // ID so incoming packets with that connection ID are routed back to them.
88 // Callers must not register a second different |encapsulated_client_session|
89 // with the same |client_connection_id|. Every call must be matched with a
90 // call to UnregisterConnectionId.
91 void RegisterConnectionId(
92 QuicConnectionId client_connection_id,
93 EncapsulatedClientSession* encapsulated_client_session);
94
95 // Unregister encapsulated client. |client_connection_id| must match a
96 // value previously passed to RegisterConnectionId.
dschinazida88cd12021-02-25 11:44:05 -080097 void UnregisterConnectionId(
98 QuicConnectionId client_connection_id,
99 EncapsulatedClientSession* encapsulated_client_session);
dschinazi1c99fcf2019-12-13 11:54:22 -0800100
101 private:
dschinazida88cd12021-02-25 11:44:05 -0800102 // State that the MasqueClientSession keeps for each CONNECT-UDP request.
dschinazi9ff30da2021-02-26 18:17:39 -0800103 class QUIC_NO_EXPORT ConnectUdpClientState
104 : public QuicSpdySession::Http3DatagramVisitor {
dschinazida88cd12021-02-25 11:44:05 -0800105 public:
106 // |stream| and |encapsulated_client_session| must be valid for the lifetime
107 // of the ConnectUdpClientState.
108 explicit ConnectUdpClientState(
109 QuicSpdyClientStream* stream,
110 EncapsulatedClientSession* encapsulated_client_session,
dschinazi9ff30da2021-02-26 18:17:39 -0800111 MasqueClientSession* masque_session,
dschinazida88cd12021-02-25 11:44:05 -0800112 QuicDatagramFlowId flow_id,
dschinazi9ff30da2021-02-26 18:17:39 -0800113 const QuicSocketAddress& target_server_address);
114
115 ~ConnectUdpClientState();
116
117 // Disallow copy but allow move.
118 ConnectUdpClientState(const ConnectUdpClientState&) = delete;
119 ConnectUdpClientState(ConnectUdpClientState&&);
120 ConnectUdpClientState& operator=(const ConnectUdpClientState&) = delete;
121 ConnectUdpClientState& operator=(ConnectUdpClientState&&);
dschinazida88cd12021-02-25 11:44:05 -0800122
123 QuicSpdyClientStream* stream() const { return stream_; }
124 EncapsulatedClientSession* encapsulated_client_session() const {
125 return encapsulated_client_session_;
126 }
dschinazi9ff30da2021-02-26 18:17:39 -0800127 QuicDatagramFlowId flow_id() const {
128 QUICHE_DCHECK(flow_id_.has_value());
129 return *flow_id_;
130 }
dschinazida88cd12021-02-25 11:44:05 -0800131 const QuicSocketAddress& target_server_address() const {
132 return target_server_address_;
133 }
134
dschinazi9ff30da2021-02-26 18:17:39 -0800135 // From QuicSpdySession::Http3DatagramVisitor.
136 void OnHttp3Datagram(QuicDatagramFlowId flow_id,
137 absl::string_view payload) override;
138
dschinazida88cd12021-02-25 11:44:05 -0800139 private:
140 QuicSpdyClientStream* stream_; // Unowned.
141 EncapsulatedClientSession* encapsulated_client_session_; // Unowned.
dschinazi9ff30da2021-02-26 18:17:39 -0800142 MasqueClientSession* masque_session_; // Unowned.
143 absl::optional<QuicDatagramFlowId> flow_id_;
dschinazida88cd12021-02-25 11:44:05 -0800144 QuicSocketAddress target_server_address_;
145 };
146
147 const ConnectUdpClientState* GetOrCreateConnectUdpClientState(
148 const QuicSocketAddress& target_server_address,
149 EncapsulatedClientSession* encapsulated_client_session);
150
151 MasqueMode masque_mode_;
152 std::list<ConnectUdpClientState> connect_udp_client_states_;
vasilvv45a59fe2021-02-02 12:07:25 -0800153 absl::flat_hash_map<QuicConnectionId,
154 EncapsulatedClientSession*,
155 QuicConnectionIdHash>
dschinazi1c99fcf2019-12-13 11:54:22 -0800156 client_connection_id_registrations_;
157 Owner* owner_; // Unowned;
158 MasqueCompressionEngine compression_engine_;
159};
160
161} // namespace quic
162
163#endif // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_