| // 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_SERVER_SESSION_H_ | 
 | #define QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_ | 
 |  | 
 | #include <list> | 
 | #include <memory> | 
 |  | 
 | #include "absl/strings/string_view.h" | 
 | #include "quiche/quic/core/crypto/quic_compressed_certs_cache.h" | 
 | #include "quiche/quic/core/crypto/quic_crypto_server_config.h" | 
 | #include "quiche/quic/core/frames/quic_connection_close_frame.h" | 
 | #include "quiche/quic/core/http/http_frames.h" | 
 | #include "quiche/quic/core/http/quic_spdy_session.h" | 
 | #include "quiche/quic/core/http/quic_spdy_stream.h" | 
 | #include "quiche/quic/core/io/quic_event_loop.h" | 
 | #include "quiche/quic/core/quic_config.h" | 
 | #include "quiche/quic/core/quic_connection.h" | 
 | #include "quiche/quic/core/quic_crypto_server_stream_base.h" | 
 | #include "quiche/quic/core/quic_session.h" | 
 | #include "quiche/quic/core/quic_time.h" | 
 | #include "quiche/quic/core/quic_types.h" | 
 | #include "quiche/quic/core/quic_udp_socket.h" | 
 | #include "quiche/quic/core/quic_versions.h" | 
 | #include "quiche/quic/masque/masque_server_backend.h" | 
 | #include "quiche/quic/masque/masque_utils.h" | 
 | #include "quiche/quic/platform/api/quic_export.h" | 
 | #include "quiche/quic/platform/api/quic_ip_address.h" | 
 | #include "quiche/quic/platform/api/quic_socket_address.h" | 
 | #include "quiche/quic/tools/quic_backend_response.h" | 
 | #include "quiche/quic/tools/quic_simple_server_backend.h" | 
 | #include "quiche/quic/tools/quic_simple_server_session.h" | 
 | #include "quiche/common/capsule.h" | 
 | #include "quiche/spdy/core/http2_header_block.h" | 
 |  | 
 | namespace quic { | 
 |  | 
 | // QUIC server session for connection to MASQUE proxy. | 
 | class QUIC_NO_EXPORT MasqueServerSession | 
 |     : public QuicSimpleServerSession, | 
 |       public MasqueServerBackend::BackendClient, | 
 |       public QuicSocketEventListener { | 
 |  public: | 
 |   explicit MasqueServerSession( | 
 |       MasqueMode masque_mode, const QuicConfig& config, | 
 |       const ParsedQuicVersionVector& supported_versions, | 
 |       QuicConnection* connection, QuicSession::Visitor* visitor, | 
 |       QuicEventLoop* event_loop, QuicCryptoServerStreamBase::Helper* helper, | 
 |       const QuicCryptoServerConfig* crypto_config, | 
 |       QuicCompressedCertsCache* compressed_certs_cache, | 
 |       MasqueServerBackend* masque_server_backend); | 
 |  | 
 |   // Disallow copy and assign. | 
 |   MasqueServerSession(const MasqueServerSession&) = delete; | 
 |   MasqueServerSession& operator=(const MasqueServerSession&) = 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 MasqueServerBackend::BackendClient. | 
 |   std::unique_ptr<QuicBackendResponse> HandleMasqueRequest( | 
 |       const spdy::Http2HeaderBlock& request_headers, | 
 |       QuicSimpleServerBackend::RequestHandler* request_handler) override; | 
 |  | 
 |   // From QuicSocketEventListener. | 
 |   void OnSocketEvent(QuicEventLoop* event_loop, QuicUdpSocketFd fd, | 
 |                      QuicSocketEventMask events) override; | 
 |  | 
 |   QuicEventLoop* event_loop() const { return event_loop_; } | 
 |  | 
 |  private: | 
 |   bool HandleConnectUdpSocketEvent(QuicUdpSocketFd fd, | 
 |                                    QuicSocketEventMask events); | 
 |   bool HandleConnectIpSocketEvent(QuicUdpSocketFd fd, | 
 |                                   QuicSocketEventMask events); | 
 |   bool HandleConnectEthernetSocketEvent(QuicUdpSocketFd fd, | 
 |                                         QuicSocketEventMask events); | 
 |   std::unique_ptr<QuicBackendResponse> MaybeCheckConcealedAuth( | 
 |       const spdy::Http2HeaderBlock& request_headers, | 
 |       absl::string_view authority, absl::string_view scheme, | 
 |       QuicSimpleServerBackend::RequestHandler* request_handler); | 
 |  | 
 |   // State that the MasqueServerSession keeps for each CONNECT-UDP request. | 
 |   class QUIC_NO_EXPORT ConnectUdpServerState | 
 |       : public QuicSpdyStream::Http3DatagramVisitor { | 
 |    public: | 
 |     // ConnectUdpServerState takes ownership of |fd|. It will unregister it | 
 |     // from |event_loop| and close the file descriptor when destructed. | 
 |     explicit ConnectUdpServerState( | 
 |         QuicSpdyStream* stream, const QuicSocketAddress& target_server_address, | 
 |         QuicUdpSocketFd fd, MasqueServerSession* masque_session); | 
 |  | 
 |     ~ConnectUdpServerState(); | 
 |  | 
 |     // Disallow copy but allow move. | 
 |     ConnectUdpServerState(const ConnectUdpServerState&) = delete; | 
 |     ConnectUdpServerState(ConnectUdpServerState&&); | 
 |     ConnectUdpServerState& operator=(const ConnectUdpServerState&) = delete; | 
 |     ConnectUdpServerState& operator=(ConnectUdpServerState&&); | 
 |  | 
 |     QuicSpdyStream* stream() const { return stream_; } | 
 |     const QuicSocketAddress& target_server_address() const { | 
 |       return target_server_address_; | 
 |     } | 
 |     QuicUdpSocketFd fd() const { return fd_; } | 
 |  | 
 |     // From QuicSpdyStream::Http3DatagramVisitor. | 
 |     void OnHttp3Datagram(QuicStreamId stream_id, | 
 |                          absl::string_view payload) override; | 
 |     void OnUnknownCapsule(QuicStreamId /*stream_id*/, | 
 |                           const quiche::UnknownCapsule& /*capsule*/) override {} | 
 |  | 
 |    private: | 
 |     QuicSpdyStream* stream_; | 
 |     QuicSocketAddress target_server_address_; | 
 |     QuicUdpSocketFd fd_;                   // Owned. | 
 |     MasqueServerSession* masque_session_;  // Unowned. | 
 |   }; | 
 |  | 
 |   // State that the MasqueServerSession keeps for each CONNECT-IP request. | 
 |   class QUIC_NO_EXPORT ConnectIpServerState | 
 |       : public QuicSpdyStream::Http3DatagramVisitor, | 
 |         public QuicSpdyStream::ConnectIpVisitor { | 
 |    public: | 
 |     // ConnectIpServerState takes ownership of |fd|. It will unregister it | 
 |     // from |event_loop| and close the file descriptor when destructed. | 
 |     explicit ConnectIpServerState(QuicIpAddress client_ip, | 
 |                                   QuicSpdyStream* stream, QuicUdpSocketFd fd, | 
 |                                   MasqueServerSession* masque_session); | 
 |  | 
 |     ~ConnectIpServerState(); | 
 |  | 
 |     // Disallow copy but allow move. | 
 |     ConnectIpServerState(const ConnectIpServerState&) = delete; | 
 |     ConnectIpServerState(ConnectIpServerState&&); | 
 |     ConnectIpServerState& operator=(const ConnectIpServerState&) = delete; | 
 |     ConnectIpServerState& operator=(ConnectIpServerState&&); | 
 |  | 
 |     QuicSpdyStream* stream() const { return stream_; } | 
 |     QuicUdpSocketFd fd() const { return fd_; } | 
 |  | 
 |     // From QuicSpdyStream::Http3DatagramVisitor. | 
 |     void OnHttp3Datagram(QuicStreamId stream_id, | 
 |                          absl::string_view payload) override; | 
 |     void OnUnknownCapsule(QuicStreamId /*stream_id*/, | 
 |                           const quiche::UnknownCapsule& /*capsule*/) override {} | 
 |  | 
 |     // From QuicSpdyStream::ConnectIpVisitor. | 
 |     bool OnAddressAssignCapsule( | 
 |         const quiche::AddressAssignCapsule& capsule) override; | 
 |     bool OnAddressRequestCapsule( | 
 |         const quiche::AddressRequestCapsule& capsule) override; | 
 |     bool OnRouteAdvertisementCapsule( | 
 |         const quiche::RouteAdvertisementCapsule& capsule) override; | 
 |     void OnHeadersWritten() override; | 
 |  | 
 |    private: | 
 |     QuicIpAddress client_ip_; | 
 |     QuicSpdyStream* stream_; | 
 |     QuicUdpSocketFd fd_;                   // Owned. | 
 |     MasqueServerSession* masque_session_;  // Unowned. | 
 |   }; | 
 |  | 
 |   // State that the MasqueServerSession keeps for each CONNECT-ETHERNET request. | 
 |   class QUIC_NO_EXPORT ConnectEthernetServerState | 
 |       : public QuicSpdyStream::Http3DatagramVisitor { | 
 |    public: | 
 |     // ConnectEthernetServerState takes ownership of |fd|. It will unregister it | 
 |     // from |event_loop| and close the file descriptor when destructed. | 
 |     explicit ConnectEthernetServerState(QuicSpdyStream* stream, | 
 |                                         QuicUdpSocketFd fd, | 
 |                                         MasqueServerSession* masque_session); | 
 |  | 
 |     ~ConnectEthernetServerState(); | 
 |  | 
 |     // Disallow copy but allow move. | 
 |     ConnectEthernetServerState(const ConnectEthernetServerState&) = delete; | 
 |     ConnectEthernetServerState(ConnectEthernetServerState&&); | 
 |     ConnectEthernetServerState& operator=(const ConnectEthernetServerState&) = | 
 |         delete; | 
 |     ConnectEthernetServerState& operator=(ConnectEthernetServerState&&); | 
 |  | 
 |     QuicSpdyStream* stream() const { return stream_; } | 
 |     QuicUdpSocketFd fd() const { return fd_; } | 
 |  | 
 |     // From QuicSpdyStream::Http3DatagramVisitor. | 
 |     void OnHttp3Datagram(QuicStreamId stream_id, | 
 |                          absl::string_view payload) override; | 
 |     void OnUnknownCapsule(QuicStreamId /*stream_id*/, | 
 |                           const quiche::UnknownCapsule& /*capsule*/) override {} | 
 |  | 
 |    private: | 
 |     QuicSpdyStream* stream_; | 
 |     QuicUdpSocketFd fd_;                   // Owned. | 
 |     MasqueServerSession* masque_session_;  // Unowned. | 
 |   }; | 
 |  | 
 |   // From QuicSpdySession. | 
 |   bool OnSettingsFrame(const SettingsFrame& frame) override; | 
 |   HttpDatagramSupport LocalHttpDatagramSupport() override { | 
 |     return HttpDatagramSupport::kRfc; | 
 |   } | 
 |  | 
 |   MasqueServerBackend* masque_server_backend_;  // Unowned. | 
 |   QuicEventLoop* event_loop_;                   // Unowned. | 
 |   MasqueMode masque_mode_; | 
 |   std::list<ConnectUdpServerState> connect_udp_server_states_; | 
 |   std::list<ConnectIpServerState> connect_ip_server_states_; | 
 |   std::list<ConnectEthernetServerState> connect_ethernet_server_states_; | 
 | }; | 
 |  | 
 | }  // namespace quic | 
 |  | 
 | #endif  // QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_ |