blob: 66c7e2ee35a224338234a40c5d87b69602e3b7f0 [file] [log] [blame]
// 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_