// 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 "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"
#include "net/third_party/quiche/src/quic/platform/api/quic_string.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 QuicString& 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),
      chlo_packet_size_, std::move(cb));
}

void StatelessRejector::ProcessClientHelloDone(
    QuicErrorCode error,
    const QuicString& 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
