// Copyright 2016 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 "net/third_party/quiche/src/quic/core/stateless_rejector.h"

#include <string>

#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"

namespace quic {

class StatelessRejector::ValidateCallback
    : public ValidateClientHelloResultCallback {
 public:
  explicit ValidateCallback(
      std::unique_ptr<StatelessRejector> rejector,
      std::unique_ptr<StatelessRejector::ProcessDoneCallback> cb)
      : rejector_(std::move(rejector)), cb_(std::move(cb)) {}

  ~ValidateCallback() override = default;

  void Run(QuicReferenceCountedPointer<Result> result,
           std::unique_ptr<ProofSource::Details> /* proof_source_details */)
      override {
    StatelessRejector* rejector_ptr = rejector_.get();
    rejector_ptr->ProcessClientHello(std::move(result), std::move(rejector_),
                                     std::move(cb_));
  }

 private:
  std::unique_ptr<StatelessRejector> rejector_;
  std::unique_ptr<StatelessRejector::ProcessDoneCallback> cb_;
};

StatelessRejector::StatelessRejector(
    ParsedQuicVersion version,
    const ParsedQuicVersionVector& versions,
    const QuicCryptoServerConfig* crypto_config,
    QuicCompressedCertsCache* compressed_certs_cache,
    const QuicClock* clock,
    QuicRandom* random,
    QuicByteCount chlo_packet_size,
    const QuicSocketAddress& client_address,
    const QuicSocketAddress& server_address)
    : state_(UNKNOWN),
      error_(QUIC_INTERNAL_ERROR),
      version_(version),
      versions_(versions),
      connection_id_(EmptyQuicConnectionId()),
      chlo_packet_size_(chlo_packet_size),
      client_address_(client_address),
      server_address_(server_address),
      clock_(clock),
      random_(random),
      crypto_config_(crypto_config),
      compressed_certs_cache_(compressed_certs_cache),
      signed_config_(new QuicSignedServerConfig),
      params_(new QuicCryptoNegotiatedParameters) {}

StatelessRejector::~StatelessRejector() = default;

void StatelessRejector::OnChlo(QuicTransportVersion version,
                               QuicConnectionId connection_id,
                               QuicConnectionId server_designated_connection_id,
                               const CryptoHandshakeMessage& message) {
  DCHECK_EQ(kCHLO, message.tag());
  DCHECK_NE(connection_id, server_designated_connection_id);
  DCHECK_EQ(state_, UNKNOWN);

  if (!GetQuicReloadableFlag(enable_quic_stateless_reject_support) ||
      !GetQuicReloadableFlag(quic_use_cheap_stateless_rejects) ||
      !QuicCryptoServerStream::DoesPeerSupportStatelessRejects(message)) {
    state_ = UNSUPPORTED;
    return;
  }

  connection_id_ = connection_id;
  server_designated_connection_id_ = server_designated_connection_id;
  chlo_ = message;  // Note: copies the message
}

void StatelessRejector::Process(std::unique_ptr<StatelessRejector> rejector,
                                std::unique_ptr<ProcessDoneCallback> done_cb) {
  QUIC_BUG_IF(rejector->state() != UNKNOWN) << "StatelessRejector::Process "
                                               "called for a rejector which "
                                               "has already made a decision";
  StatelessRejector* rejector_ptr = rejector.get();
  rejector_ptr->crypto_config_->ValidateClientHello(
      rejector_ptr->chlo_, rejector_ptr->client_address_.host(),
      rejector_ptr->server_address_, rejector_ptr->version_.transport_version,
      rejector_ptr->clock_, rejector_ptr->signed_config_,
      std::unique_ptr<ValidateCallback>(
          new ValidateCallback(std::move(rejector), std::move(done_cb))));
}

class StatelessRejector::ProcessClientHelloCallback
    : public ProcessClientHelloResultCallback {
 public:
  ProcessClientHelloCallback(
      std::unique_ptr<StatelessRejector> rejector,
      std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb)
      : rejector_(std::move(rejector)), done_cb_(std::move(done_cb)) {}

  void Run(QuicErrorCode error,
           const std::string& error_details,
           std::unique_ptr<CryptoHandshakeMessage> message,
           std::unique_ptr<DiversificationNonce> diversification_nonce,
           std::unique_ptr<ProofSource::Details> /* proof_source_details */)
      override {
    StatelessRejector* rejector_ptr = rejector_.get();
    rejector_ptr->ProcessClientHelloDone(
        error, error_details, std::move(message), std::move(rejector_),
        std::move(done_cb_));
  }

 private:
  std::unique_ptr<StatelessRejector> rejector_;
  std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb_;
};

void StatelessRejector::ProcessClientHello(
    QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
        result,
    std::unique_ptr<StatelessRejector> rejector,
    std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb) {
  std::unique_ptr<ProcessClientHelloCallback> cb(
      new ProcessClientHelloCallback(std::move(rejector), std::move(done_cb)));
  crypto_config_->ProcessClientHello(
      result,
      /*reject_only=*/true, connection_id_, server_address_, client_address_,
      version_, versions_,
      /*use_stateless_rejects=*/true, server_designated_connection_id_, clock_,
      random_, compressed_certs_cache_, params_, signed_config_,
      QuicCryptoStream::CryptoMessageFramingOverhead(version_.transport_version,
                                                     connection_id_),
      chlo_packet_size_, std::move(cb));
}

void StatelessRejector::ProcessClientHelloDone(
    QuicErrorCode error,
    const std::string& error_details,
    std::unique_ptr<CryptoHandshakeMessage> message,
    std::unique_ptr<StatelessRejector> rejector,
    std::unique_ptr<StatelessRejector::ProcessDoneCallback> done_cb) {
  reply_ = std::move(message);

  if (error != QUIC_NO_ERROR) {
    error_ = error;
    error_details_ = error_details;
    state_ = FAILED;
  } else if (reply_->tag() == kSREJ) {
    state_ = REJECTED;
  } else {
    state_ = ACCEPTED;
  }
  done_cb->Run(std::move(rejector));
}

}  // namespace quic
