xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // 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 
8 #include <list>
9 #include <optional>
10 #include <string>
11 
12 #include "absl/container/flat_hash_map.h"
13 #include "absl/strings/string_view.h"
14 #include "quiche/quic/core/crypto/quic_crypto_client_config.h"
15 #include "quiche/quic/core/frames/quic_connection_close_frame.h"
16 #include "quiche/quic/core/http/http_frames.h"
17 #include "quiche/quic/core/http/quic_spdy_client_session.h"
18 #include "quiche/quic/core/http/quic_spdy_client_stream.h"
19 #include "quiche/quic/core/http/quic_spdy_session.h"
20 #include "quiche/quic/core/http/quic_spdy_stream.h"
21 #include "quiche/quic/core/quic_config.h"
22 #include "quiche/quic/core/quic_error_codes.h"
23 #include "quiche/quic/core/quic_time.h"
24 #include "quiche/quic/core/quic_types.h"
25 #include "quiche/quic/core/quic_versions.h"
26 #include "quiche/quic/masque/masque_utils.h"
27 #include "quiche/quic/platform/api/quic_export.h"
28 #include "quiche/quic/platform/api/quic_socket_address.h"
29 #include "quiche/quic/tools/quic_url.h"
30 #include "quiche/common/capsule.h"
31 #include "quiche/common/quiche_ip_address.h"
32 #include "quiche/spdy/core/http2_header_block.h"
33 
34 namespace quic {
35 
36 // QUIC client session for connection to MASQUE proxy. This session establishes
37 // a connection to a MASQUE proxy and handles sending and receiving DATAGRAM
38 // frames for operation of the MASQUE protocol. Multiple end-to-end encapsulated
39 // sessions can then coexist inside this session. Once these are created, they
40 // need to be registered with this session.
41 class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession,
42                                            public QuicSpdyStream::Visitor {
43  public:
44   // Interface meant to be implemented by the owner of the
45   // MasqueClientSession instance.
46   class QUIC_NO_EXPORT Owner {
47    public:
~Owner()48     virtual ~Owner() {}
49 
50     // Notifies the owner that a settings frame has been received.
51     virtual void OnSettingsReceived() = 0;
52   };
53 
54   // Interface meant to be implemented by client sessions encapsulated inside
55   // CONNECT-UDP, i.e. the end-to-end QUIC client sessions that run inside
56   // CONNECT-UDP encapsulation.
57   class QUIC_NO_EXPORT EncapsulatedClientSession {
58    public:
~EncapsulatedClientSession()59     virtual ~EncapsulatedClientSession() {}
60 
61     // Process UDP packet that was just decapsulated. |packet| contains the UDP
62     // payload.
63     virtual void ProcessPacket(absl::string_view packet,
64                                QuicSocketAddress target_server_address) = 0;
65 
66     // Close the encapsulated connection.
67     virtual void CloseConnection(
68         QuicErrorCode error, const std::string& details,
69         ConnectionCloseBehavior connection_close_behavior) = 0;
70   };
71 
72   // Interface meant to be implemented by client sessions encapsulated inside
73   // CONNECT-IP, i.e. the end-to-end QUIC client sessions that run inside
74   // CONNECT-IP encapsulation.
75   class QUIC_NO_EXPORT EncapsulatedIpSession {
76    public:
~EncapsulatedIpSession()77     virtual ~EncapsulatedIpSession() {}
78 
79     // Process packet that was just decapsulated. |packet| contains the IP
80     // header and payload.
81     virtual void ProcessIpPacket(absl::string_view packet) = 0;
82 
83     // Close the encapsulated connection.
84     virtual void CloseIpSession(const std::string& details) = 0;
85 
86     virtual bool OnAddressAssignCapsule(
87         const quiche::AddressAssignCapsule& capsule) = 0;
88     virtual bool OnAddressRequestCapsule(
89         const quiche::AddressRequestCapsule& capsule) = 0;
90     virtual bool OnRouteAdvertisementCapsule(
91         const quiche::RouteAdvertisementCapsule& capsule) = 0;
92   };
93 
94   // CONNECT-ETHERNET.
95   class QUIC_NO_EXPORT EncapsulatedEthernetSession {
96    public:
~EncapsulatedEthernetSession()97     virtual ~EncapsulatedEthernetSession() {}
98 
99     // Process packet that was just decapsulated. |frame| contains the
100     // Ethernet header and payload.
101     virtual void ProcessEthernetFrame(absl::string_view frame) = 0;
102 
103     // Close the encapsulated connection.
104     virtual void CloseEthernetSession(const std::string& details) = 0;
105   };
106 
107   // Takes ownership of |connection|, but not of |crypto_config| or |owner|.
108   // All pointers must be non-null. Caller must ensure that |owner| stays valid
109   // for the lifetime of the newly created MasqueClientSession.
110   MasqueClientSession(MasqueMode masque_mode, const std::string& uri_template,
111                       const QuicConfig& config,
112                       const ParsedQuicVersionVector& supported_versions,
113                       QuicConnection* connection, const QuicServerId& server_id,
114                       QuicCryptoClientConfig* crypto_config, Owner* owner);
115 
116   // Disallow copy and assign.
117   MasqueClientSession(const MasqueClientSession&) = delete;
118   MasqueClientSession& operator=(const MasqueClientSession&) = delete;
119 
120   // From QuicSession.
121   void OnMessageAcked(QuicMessageId message_id,
122                       QuicTime receive_timestamp) override;
123   void OnMessageLost(QuicMessageId message_id) override;
124   void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
125                           ConnectionCloseSource source) override;
126   void OnStreamClosed(QuicStreamId stream_id) override;
127 
128   // From QuicSpdySession.
129   bool OnSettingsFrame(const SettingsFrame& frame) override;
130 
131   // Send encapsulated UDP packet. |packet| contains the UDP payload.
132   void SendPacket(absl::string_view packet,
133                   const QuicSocketAddress& target_server_address,
134                   EncapsulatedClientSession* encapsulated_client_session);
135 
136   // Send encapsulated IP packet. |packet| contains the IP header and payload.
137   void SendIpPacket(absl::string_view packet,
138                     EncapsulatedIpSession* encapsulated_ip_session);
139 
140   // Send encapsulated Ethernet frame. |frame| contains the Ethernet
141   // header and payload.
142   void SendEthernetFrame(
143       absl::string_view frame,
144       EncapsulatedEthernetSession* encapsulated_ethernet_session);
145 
146   // Close CONNECT-UDP stream tied to this encapsulated client session.
147   void CloseConnectUdpStream(
148       EncapsulatedClientSession* encapsulated_client_session);
149 
150   // Close CONNECT-IP stream tied to this encapsulated client session.
151   void CloseConnectIpStream(EncapsulatedIpSession* encapsulated_ip_session);
152 
153   // Close CONNECT-ETHERNET stream tied to this encapsulated client session.
154   void CloseConnectEthernetStream(
155       EncapsulatedEthernetSession* encapsulated_ethernet_session);
156 
157   // Generate a random Unique Local Address and register a mapping from
158   // that address to the corresponding hostname. The returned address should be
159   // removed by calling RemoveFakeAddress() once it is no longer needed.
160   quiche::QuicheIpAddress GetFakeAddress(absl::string_view hostname);
161 
162   // Removes a fake address that was previously created by GetFakeAddress().
163   void RemoveFakeAddress(const quiche::QuicheIpAddress& fake_address);
164 
165   // Set additional HTTP headers that will be sent on all requests to the MASQUE
166   // proxy. Separated with colons and semicolons.
167   // For example: "name1:value1;name2:value2".
set_additional_headers(absl::string_view additional_headers)168   void set_additional_headers(absl::string_view additional_headers) {
169     additional_headers_ = additional_headers;
170   }
171 
172   // Send a GET request to the MASQUE proxy itself.
173   QuicSpdyClientStream* SendGetRequest(absl::string_view path);
174 
175   // QuicSpdyStream::Visitor
176   void OnClose(QuicSpdyStream* stream) override;
177 
178   // Set the signature auth key ID and private key. key_id MUST be non-empty,
179   // private_key MUST be ED25519_PRIVATE_KEY_LEN bytes long and public_key MUST
180   // be ED25519_PUBLIC_KEY_LEN bytes long.
181   void EnableSignatureAuth(absl::string_view key_id,
182                            absl::string_view private_key,
183                            absl::string_view public_key);
184 
185  private:
186   // State that the MasqueClientSession keeps for each CONNECT-UDP request.
187   class QUIC_NO_EXPORT ConnectUdpClientState
188       : public QuicSpdyStream::Http3DatagramVisitor {
189    public:
190     // |stream| and |encapsulated_client_session| must be valid for the lifetime
191     // of the ConnectUdpClientState.
192     explicit ConnectUdpClientState(
193         QuicSpdyClientStream* stream,
194         EncapsulatedClientSession* encapsulated_client_session,
195         MasqueClientSession* masque_session,
196         const QuicSocketAddress& target_server_address);
197 
198     ~ConnectUdpClientState();
199 
200     // Disallow copy but allow move.
201     ConnectUdpClientState(const ConnectUdpClientState&) = delete;
202     ConnectUdpClientState(ConnectUdpClientState&&);
203     ConnectUdpClientState& operator=(const ConnectUdpClientState&) = delete;
204     ConnectUdpClientState& operator=(ConnectUdpClientState&&);
205 
stream()206     QuicSpdyClientStream* stream() const { return stream_; }
encapsulated_client_session()207     EncapsulatedClientSession* encapsulated_client_session() const {
208       return encapsulated_client_session_;
209     }
target_server_address()210     const QuicSocketAddress& target_server_address() const {
211       return target_server_address_;
212     }
213 
214     // From QuicSpdyStream::Http3DatagramVisitor.
215     void OnHttp3Datagram(QuicStreamId stream_id,
216                          absl::string_view payload) override;
OnUnknownCapsule(QuicStreamId,const quiche::UnknownCapsule &)217     void OnUnknownCapsule(QuicStreamId /*stream_id*/,
218                           const quiche::UnknownCapsule& /*capsule*/) override {}
219 
220    private:
221     QuicSpdyClientStream* stream_;                            // Unowned.
222     EncapsulatedClientSession* encapsulated_client_session_;  // Unowned.
223     MasqueClientSession* masque_session_;                     // Unowned.
224     QuicSocketAddress target_server_address_;
225   };
226 
227   // State that the MasqueClientSession keeps for each CONNECT-IP request.
228   class QUIC_NO_EXPORT ConnectIpClientState
229       : public QuicSpdyStream::Http3DatagramVisitor,
230         public QuicSpdyStream::ConnectIpVisitor {
231    public:
232     // |stream| and |encapsulated_client_session| must be valid for the lifetime
233     // of the ConnectUdpClientState.
234     explicit ConnectIpClientState(
235         QuicSpdyClientStream* stream,
236         EncapsulatedIpSession* encapsulated_ip_session,
237         MasqueClientSession* masque_session);
238 
239     ~ConnectIpClientState();
240 
241     // Disallow copy but allow move.
242     ConnectIpClientState(const ConnectIpClientState&) = delete;
243     ConnectIpClientState(ConnectIpClientState&&);
244     ConnectIpClientState& operator=(const ConnectIpClientState&) = delete;
245     ConnectIpClientState& operator=(ConnectIpClientState&&);
246 
stream()247     QuicSpdyClientStream* stream() const { return stream_; }
encapsulated_ip_session()248     EncapsulatedIpSession* encapsulated_ip_session() const {
249       return encapsulated_ip_session_;
250     }
251 
252     // From QuicSpdyStream::Http3DatagramVisitor.
253     void OnHttp3Datagram(QuicStreamId stream_id,
254                          absl::string_view payload) override;
OnUnknownCapsule(QuicStreamId,const quiche::UnknownCapsule &)255     void OnUnknownCapsule(QuicStreamId /*stream_id*/,
256                           const quiche::UnknownCapsule& /*capsule*/) override {}
257 
258     // From QuicSpdyStream::ConnectIpVisitor.
259     bool OnAddressAssignCapsule(
260         const quiche::AddressAssignCapsule& capsule) override;
261     bool OnAddressRequestCapsule(
262         const quiche::AddressRequestCapsule& capsule) override;
263     bool OnRouteAdvertisementCapsule(
264         const quiche::RouteAdvertisementCapsule& capsule) override;
265     void OnHeadersWritten() override;
266 
267    private:
268     QuicSpdyClientStream* stream_;                    // Unowned.
269     EncapsulatedIpSession* encapsulated_ip_session_;  // Unowned.
270     MasqueClientSession* masque_session_;             // Unowned.
271   };
272 
273   // State that the MasqueClientSession keeps for each CONNECT-ETHERNET request.
274   class QUIC_NO_EXPORT ConnectEthernetClientState
275       : public QuicSpdyStream::Http3DatagramVisitor {
276    public:
277     // |stream| and |encapsulated_client_session| must be valid for the lifetime
278     // of the ConnectUdpClientState.
279     explicit ConnectEthernetClientState(
280         QuicSpdyClientStream* stream,
281         EncapsulatedEthernetSession* encapsulated_ethernet_session,
282         MasqueClientSession* masque_session);
283 
284     ~ConnectEthernetClientState();
285 
286     // Disallow copy but allow move.
287     ConnectEthernetClientState(const ConnectEthernetClientState&) = delete;
288     ConnectEthernetClientState(ConnectEthernetClientState&&);
289     ConnectEthernetClientState& operator=(const ConnectEthernetClientState&) =
290         delete;
291     ConnectEthernetClientState& operator=(ConnectEthernetClientState&&);
292 
stream()293     QuicSpdyClientStream* stream() const { return stream_; }
encapsulated_ethernet_session()294     EncapsulatedEthernetSession* encapsulated_ethernet_session() const {
295       return encapsulated_ethernet_session_;
296     }
297 
298     // From QuicSpdyStream::Http3DatagramVisitor.
299     void OnHttp3Datagram(QuicStreamId stream_id,
300                          absl::string_view payload) override;
OnUnknownCapsule(QuicStreamId,const quiche::UnknownCapsule &)301     void OnUnknownCapsule(QuicStreamId /*stream_id*/,
302                           const quiche::UnknownCapsule& /*capsule*/) override {}
303 
304    private:
305     QuicSpdyClientStream* stream_;                                // Unowned.
306     EncapsulatedEthernetSession* encapsulated_ethernet_session_;  // Unowned.
307     MasqueClientSession* masque_session_;                         // Unowned.
308   };
309 
LocalHttpDatagramSupport()310   HttpDatagramSupport LocalHttpDatagramSupport() override {
311     return HttpDatagramSupport::kRfc;
312   }
313 
314   const ConnectUdpClientState* GetOrCreateConnectUdpClientState(
315       const QuicSocketAddress& target_server_address,
316       EncapsulatedClientSession* encapsulated_client_session);
317 
318   const ConnectIpClientState* GetOrCreateConnectIpClientState(
319       EncapsulatedIpSession* encapsulated_ip_session);
320 
321   const ConnectEthernetClientState* GetOrCreateConnectEthernetClientState(
322       EncapsulatedEthernetSession* encapsulated_ethernet_session);
323 
324   std::optional<std::string> ComputeSignatureAuthHeader(const QuicUrl& url);
325   void AddAdditionalHeaders(spdy::Http2HeaderBlock& headers,
326                             const QuicUrl& url);
327 
328   MasqueMode masque_mode_;
329   std::string uri_template_;
330   std::string additional_headers_;
331   std::string signature_auth_key_id_;
332   std::string signature_auth_private_key_;
333   std::string signature_auth_public_key_;
334   std::list<ConnectUdpClientState> connect_udp_client_states_;
335   std::list<ConnectIpClientState> connect_ip_client_states_;
336   std::list<ConnectEthernetClientState> connect_ethernet_client_states_;
337   // Maps fake addresses generated by GetFakeAddress() to their corresponding
338   // hostnames.
339   absl::flat_hash_map<std::string, std::string> fake_addresses_;
340   Owner* owner_;  // Unowned;
341 };
342 
343 }  // namespace quic
344 
345 #endif  // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
346