// Copyright 2022 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.

#include "quiche/quic/tools/connect_tunnel.h"

#include <cstdint>
#include <limits>
#include <string>
#include <utility>
#include <vector>

#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/span.h"
#include "url/third_party/mozilla/url_parse.h"
#include "quiche/quic/core/io/socket_factory.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/tools/quic_backend_response.h"
#include "quiche/quic/tools/quic_name_lookup.h"
#include "quiche/quic/tools/quic_simple_server_backend.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/platform/api/quiche_mem_slice.h"
#include "quiche/spdy/core/http2_header_block.h"

namespace quic {

namespace {

// Arbitrarily chosen. No effort has been made to figure out an optimal size.
constexpr size_t kReadSize = 4 * 1024;

absl::optional<ConnectTunnel::HostAndPort> ValidateAndParseAuthorityString(
    absl::string_view authority_string) {
  url::Component username_component;
  url::Component password_component;
  url::Component host_component;
  url::Component port_component;

  url::ParseAuthority(authority_string.data(),
                      url::Component(0, authority_string.size()),
                      &username_component, &password_component, &host_component,
                      &port_component);

  // A valid CONNECT authority must contain host and port and nothing else, per
  // https://www.rfc-editor.org/rfc/rfc9110.html#name-connect.
  if (username_component.is_valid() || password_component.is_valid() ||
      !host_component.is_nonempty() || !port_component.is_nonempty()) {
    QUICHE_DVLOG(1) << "CONNECT request authority is malformed: "
                    << authority_string;
    return absl::nullopt;
  }

  QUICHE_DCHECK_LT(static_cast<size_t>(host_component.end()),
                   authority_string.length());
  if (authority_string.length() > 2 &&
      authority_string.data()[host_component.begin] == '[' &&
      authority_string.data()[host_component.end() - 1] == ']') {
    // Strip "[]" off IPv6 literals.
    host_component.begin += 1;
    host_component.len -= 2;
  }
  std::string hostname(authority_string.data() + host_component.begin,
                       host_component.len);

  int parsed_port_number =
      url::ParsePort(authority_string.data(), port_component);
  // Negative result is either invalid or unspecified, either of which is
  // disallowed for a CONNECT authority. Port 0 is technically valid but
  // reserved and not really usable in practice, so easiest to just disallow it
  // here.
  if (parsed_port_number <= 0) {
    QUICHE_DVLOG(1) << "CONNECT request authority port is malformed: "
                    << authority_string;
    return absl::nullopt;
  }
  QUICHE_DCHECK_LE(parsed_port_number, std::numeric_limits<uint16_t>::max());

  return ConnectTunnel::HostAndPort(std::move(hostname),
                                    static_cast<uint16_t>(parsed_port_number));
}

absl::optional<ConnectTunnel::HostAndPort> ValidateHeadersAndGetAuthority(
    const spdy::Http2HeaderBlock& request_headers) {
  QUICHE_DCHECK(request_headers.contains(":method"));
  QUICHE_DCHECK(request_headers.find(":method")->second == "CONNECT");
  QUICHE_DCHECK(!request_headers.contains(":protocol"));

  auto scheme_it = request_headers.find(":scheme");
  if (scheme_it != request_headers.end()) {
    QUICHE_DVLOG(1) << "CONNECT request contains unexpected scheme: "
                    << scheme_it->second;
    return absl::nullopt;
  }

  auto path_it = request_headers.find(":path");
  if (path_it != request_headers.end()) {
    QUICHE_DVLOG(1) << "CONNECT request contains unexpected path: "
                    << path_it->second;
    return absl::nullopt;
  }

  auto authority_it = request_headers.find(":authority");
  if (authority_it == request_headers.end() || authority_it->second.empty()) {
    QUICHE_DVLOG(1) << "CONNECT request missing authority";
    return absl::nullopt;
  }

  return ValidateAndParseAuthorityString(authority_it->second);
}

bool ValidateAuthority(const ConnectTunnel::HostAndPort& authority,
                       const absl::flat_hash_set<ConnectTunnel::HostAndPort>&
                           acceptable_destinations) {
  if (acceptable_destinations.contains(authority)) {
    return true;
  }

  QUICHE_DVLOG(1) << "CONNECT request authority: "
                  << absl::StrCat(authority.host, ":", authority.port)
                  << " is not an acceptable allow-listed destiation ";
  return false;
}

}  // namespace

ConnectTunnel::HostAndPort::HostAndPort(std::string host, uint16_t port)
    : host(std::move(host)), port(port) {}

bool ConnectTunnel::HostAndPort::operator==(const HostAndPort& other) const {
  return host == other.host && port == other.port;
}

ConnectTunnel::ConnectTunnel(
    QuicSimpleServerBackend::RequestHandler* client_stream_request_handler,
    SocketFactory* socket_factory,
    absl::flat_hash_set<HostAndPort> acceptable_destinations)
    : acceptable_destinations_(std::move(acceptable_destinations)),
      socket_factory_(socket_factory),
      client_stream_request_handler_(client_stream_request_handler) {
  QUICHE_DCHECK(client_stream_request_handler_);
  QUICHE_DCHECK(socket_factory_);
}

ConnectTunnel::~ConnectTunnel() {
  // Expect client and destination sides of tunnel to both be closed before
  // destruction.
  QUICHE_DCHECK_EQ(client_stream_request_handler_, nullptr);
  QUICHE_DCHECK(!IsConnectedToDestination());
  QUICHE_DCHECK(!receive_started_);
}

void ConnectTunnel::OpenTunnel(const spdy::Http2HeaderBlock& request_headers) {
  QUICHE_DCHECK(!IsConnectedToDestination());

  absl::optional<HostAndPort> authority =
      ValidateHeadersAndGetAuthority(request_headers);
  if (!authority) {
    TerminateClientStream(
        "invalid request headers",
        QuicResetStreamError::FromIetf(QuicHttp3ErrorCode::MESSAGE_ERROR));
    return;
  }

  if (!ValidateAuthority(authority.value(), acceptable_destinations_)) {
    TerminateClientStream(
        "disallowed request authority",
        QuicResetStreamError::FromIetf(QuicHttp3ErrorCode::REQUEST_REJECTED));
    return;
  }

  QuicSocketAddress address = tools::LookupAddress(
      AF_UNSPEC, authority->host, absl::StrCat(authority->port));
  if (!address.IsInitialized()) {
    TerminateClientStream("host resolution error");
    return;
  }

  destination_socket_ =
      socket_factory_->CreateTcpClientSocket(address,
                                             /*receive_buffer_size=*/0,
                                             /*send_buffer_size=*/0,
                                             /*async_visitor=*/this);
  QUICHE_DCHECK(destination_socket_);

  absl::Status connect_result = destination_socket_->ConnectBlocking();
  if (!connect_result.ok()) {
    TerminateClientStream(
        "error connecting TCP socket to destination server: " +
        connect_result.ToString());
    return;
  }

  QUICHE_DVLOG(1) << "CONNECT tunnel opened from stream "
                  << client_stream_request_handler_->stream_id() << " to "
                  << authority->host << ":" << authority->port;

  SendConnectResponse();
  BeginAsyncReadFromDestination();
}

bool ConnectTunnel::IsConnectedToDestination() const {
  return !!destination_socket_;
}

void ConnectTunnel::SendDataToDestination(absl::string_view data) {
  QUICHE_DCHECK(IsConnectedToDestination());
  QUICHE_DCHECK(!data.empty());

  absl::Status send_result =
      destination_socket_->SendBlocking(std::string(data));
  if (!send_result.ok()) {
    TerminateClientStream("TCP error sending data to destination server: " +
                          send_result.ToString());
  }
}

void ConnectTunnel::OnClientStreamClose() {
  QUICHE_DCHECK(client_stream_request_handler_);

  QUICHE_DVLOG(1) << "CONNECT stream "
                  << client_stream_request_handler_->stream_id() << " closed";

  client_stream_request_handler_ = nullptr;

  if (IsConnectedToDestination()) {
    // TODO(ericorth): Consider just calling shutdown() on the socket rather
    // than fully disconnecting in order to allow a graceful TCP FIN stream
    // shutdown per
    // https://www.rfc-editor.org/rfc/rfc9114.html#name-the-connect-method.
    // Would require shutdown support in the socket library, and would need to
    // deal with the tunnel/socket outliving the client stream.
    destination_socket_->Disconnect();
  }

  // Clear socket pointer.
  destination_socket_.reset();
}

void ConnectTunnel::ConnectComplete(absl::Status /*status*/) {
  // Async connect not expected.
  QUICHE_NOTREACHED();
}

void ConnectTunnel::ReceiveComplete(
    absl::StatusOr<quiche::QuicheMemSlice> data) {
  QUICHE_DCHECK(IsConnectedToDestination());
  QUICHE_DCHECK(receive_started_);

  receive_started_ = false;

  if (!data.ok()) {
    if (client_stream_request_handler_) {
      TerminateClientStream("TCP error receiving data from destination server");
    } else {
      // This typically just means a receive operation was cancelled on calling
      // destination_socket_->Disconnect().
      QUICHE_DVLOG(1) << "TCP error receiving data from destination server "
                         "after stream already closed.";
    }
    return;
  } else if (data.value().empty()) {
    OnDestinationConnectionClosed();
    return;
  }

  QUICHE_DCHECK(client_stream_request_handler_);
  client_stream_request_handler_->SendStreamData(data.value().AsStringView(),
                                                 /*close_stream=*/false);

  BeginAsyncReadFromDestination();
}

void ConnectTunnel::SendComplete(absl::Status /*status*/) {
  // Async send not expected.
  QUICHE_NOTREACHED();
}

void ConnectTunnel::BeginAsyncReadFromDestination() {
  QUICHE_DCHECK(IsConnectedToDestination());
  QUICHE_DCHECK(client_stream_request_handler_);
  QUICHE_DCHECK(!receive_started_);

  receive_started_ = true;
  destination_socket_->ReceiveAsync(kReadSize);
}

void ConnectTunnel::OnDestinationConnectionClosed() {
  QUICHE_DCHECK(IsConnectedToDestination());
  QUICHE_DCHECK(client_stream_request_handler_);

  QUICHE_DVLOG(1) << "CONNECT stream "
                  << client_stream_request_handler_->stream_id()
                  << " destination connection closed";
  destination_socket_->Disconnect();

  // Clear socket pointer.
  destination_socket_.reset();

  // Extra check that nothing in the Disconnect could lead to terminating the
  // stream.
  QUICHE_DCHECK(client_stream_request_handler_);

  client_stream_request_handler_->SendStreamData("", /*close_stream=*/true);
}

void ConnectTunnel::SendConnectResponse() {
  QUICHE_DCHECK(IsConnectedToDestination());
  QUICHE_DCHECK(client_stream_request_handler_);

  spdy::Http2HeaderBlock response_headers;
  response_headers[":status"] = "200";

  QuicBackendResponse response;
  response.set_headers(std::move(response_headers));
  // Need to leave the stream open after sending the CONNECT response.
  response.set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);

  client_stream_request_handler_->OnResponseBackendComplete(&response);
}

void ConnectTunnel::TerminateClientStream(absl::string_view error_description,
                                          QuicResetStreamError error_code) {
  QUICHE_DCHECK(client_stream_request_handler_);

  std::string error_description_str =
      error_description.empty() ? ""
                                : absl::StrCat(" due to ", error_description);
  QUICHE_DVLOG(1) << "Terminating CONNECT stream "
                  << client_stream_request_handler_->stream_id()
                  << " with error code " << error_code.ietf_application_code()
                  << error_description_str;

  client_stream_request_handler_->TerminateStreamWithError(error_code);
}

}  // namespace quic
