/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "p2p/base/stun_request.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <span>
#include <string>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/environment/environment.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "api/task_queue/task_queue_base.h"
#include "api/transport/stun.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/byte_buffer.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/string_utils.h"

namespace webrtc {

// RFC 5389 says SHOULD be 500ms.
// For years, this was 100ms, but for networks that
// experience moments of high RTT (such as 2G networks), this doesn't
// work well.
const int STUN_INITIAL_RTO = 250;  // milliseconds

// The timeout doubles each retransmission, up to this many times
// RFC 5389 says SHOULD retransmit 7 times.
// This has been 8 for years (not sure why).
const int STUN_MAX_RETRANSMISSIONS = 8;  // Total sends: 9

// We also cap the doubling, even though the standard doesn't say to.
// This has been 1.6 seconds for years, but for networks that
// experience moments of high RTT (such as 2G networks), this doesn't
// work well.
const int STUN_MAX_RTO = 8000;  // milliseconds, or 5 doublings

StunRequestManager::StunRequestManager(
    TaskQueueBase* thread,
    std::function<void(std::span<const uint8_t>, StunRequest*)> send_packet)
    : thread_(thread), send_packet_(std::move(send_packet)) {}

StunRequestManager::~StunRequestManager() = default;

void StunRequestManager::Send(std::unique_ptr<StunRequest> request,
                              TimeDelta delay) {
  RTC_DCHECK_RUN_ON(thread_);
  RTC_DCHECK_EQ(this, request->manager());
  RTC_DCHECK(!request->AuthenticationRequired() ||
             request->msg()->integrity() !=
                 StunMessage::IntegrityStatus::kNotSet)
      << "Sending request w/o integrity!";
  auto [iter, was_inserted] =
      requests_.emplace(request->id(), std::move(request));
  RTC_DCHECK(was_inserted);
  iter->second->Send(delay);
}

void StunRequestManager::FlushForTest(int msg_type) {
  RTC_DCHECK_RUN_ON(thread_);
  for (const auto& [unused, request] : requests_) {
    if (msg_type == kAllRequestsForTest || msg_type == request->type()) {
      // Calling `Send` implies starting the send operation which may be posted
      // on a timer and be repeated on a timer until timeout. To make sure that
      // a call to `Send` doesn't conflict with a previously started `Send`
      // operation, we reset the `task_safety_` flag here, which has the effect
      // of canceling any outstanding tasks and prepare a new flag for
      // operations related to this call to `Send`.
      request->ResetTasksForTest();
      request->Send(TimeDelta::Zero());
    }
  }
}

bool StunRequestManager::HasRequestForTest(int msg_type) {
  RTC_DCHECK_RUN_ON(thread_);
  RTC_DCHECK_NE(msg_type, kAllRequestsForTest);
  for (const auto& [unused, request] : requests_) {
    if (msg_type == request->type()) {
      return true;
    }
  }
  return false;
}

void StunRequestManager::Clear() {
  RTC_DCHECK_RUN_ON(thread_);
  requests_.clear();
}

bool StunRequestManager::CheckResponse(StunMessage* msg) {
  RTC_DCHECK_RUN_ON(thread_);
  RequestMap::iterator iter = requests_.find(msg->transaction_id());
  if (iter == requests_.end())
    return false;

  StunRequest* request = iter->second.get();

  // Now that we know the request, we can see if the response is
  // integrity-protected or not. Some requests explicitly disables
  // integrity checks using SetAuthenticationRequired.
  // TODO(chromium:1177125): Remove below!
  // And we suspect that for some tests, the message integrity is not set in the
  // request. Complain, and then don't check.
  bool skip_integrity_checking =
      (request->msg()->integrity() == StunMessage::IntegrityStatus::kNotSet);
  if (!request->AuthenticationRequired()) {
    if (request->type() != STUN_BINDING_REQUEST) {
      if (msg->type() == GetStunSuccessResponseType(request->type())) {
        RTC_LOG(LS_WARNING)
            << "Discarding unauthenticated success response (0x"
            << ToHex(msg->type()) << ") to TURN request of type 0x"
            << ToHex(request->type())
            << ", id=" << hex_encode(msg->transaction_id());
        return false;
      }
      if (msg->type() == GetStunErrorResponseType(request->type())) {
        int error_code = msg->GetErrorCodeValue();
        if (error_code != STUN_ERROR_UNAUTHORIZED &&
            error_code != STUN_ERROR_TRY_ALTERNATE) {
          RTC_LOG(LS_WARNING)
              << "Discarding unauthenticated error response with code "
              << error_code << " to TURN request of type 0x"
              << ToHex(request->type())
              << ", id=" << hex_encode(msg->transaction_id());
          return false;
        }
      }
    }
  } else if (skip_integrity_checking) {
    // TODO(chromium:1177125): Remove below!
    // This indicates lazy test writing (not adding integrity attribute).
    // Complain, but only in debug mode (while developing).
    RTC_LOG(LS_ERROR)
        << "CheckResponse called on a passwordless request. Fix test!";
    RTC_DCHECK(false)
        << "CheckResponse called on a passwordless request. Fix test!";
  } else {
    if (msg->integrity() == StunMessage::IntegrityStatus::kNotSet) {
      // Checking status for the first time. Normal.
      msg->ValidateMessageIntegrity(request->msg()->password());
    } else if (msg->password() == request->msg()->password()) {
      // Status is already checked, with the same password. This is the case
      // we would want to see happen.
    } else {
      // This indicates that the original check had a different password
      // (e.g. ice-pwd changed between ping and response).
      // Bad design, needs revisiting.
      // TODO(crbug.com/1177125): Fix this.
      msg->RevalidateMessageIntegrity(request->msg()->password());
    }
  }

  if (!msg->GetNonComprehendedAttributes().empty()) {
    // If a response contains unknown comprehension-required attributes, it's
    // simply discarded and the transaction is considered failed. See RFC5389
    // sections 7.3.3 and 7.3.4.
    RTC_LOG(LS_ERROR) << ": Discarding response due to unknown "
                         "comprehension-required attribute.";
    requests_.erase(iter);
    return false;
  } else if (msg->type() == GetStunSuccessResponseType(request->type())) {
    if (!msg->IntegrityOk() && !skip_integrity_checking) {
      return false;
    }
    // Erase element from hash before calling callback. This ensures
    // that the callback can modify the StunRequestManager any way it
    // sees fit.
    std::unique_ptr<StunRequest> owned_request = std::move(iter->second);
    requests_.erase(iter);
    owned_request->OnResponse(msg);
    return true;
  } else if (msg->type() == GetStunErrorResponseType(request->type())) {
    // Erase element from hash before calling callback. This ensures
    // that the callback can modify the StunRequestManager any way it
    // sees fit.
    std::unique_ptr<StunRequest> owned_request = std::move(iter->second);
    requests_.erase(iter);
    owned_request->OnErrorResponse(msg);
    return true;
  } else {
    RTC_LOG(LS_ERROR) << "Received response with wrong type: " << msg->type()
                      << " (expecting "
                      << GetStunSuccessResponseType(request->type()) << ")";
    return false;
  }
}

bool StunRequestManager::empty() const {
  RTC_DCHECK_RUN_ON(thread_);
  return requests_.empty();
}

bool StunRequestManager::CheckResponse(std::span<const uint8_t> payload) {
  RTC_DCHECK_RUN_ON(thread_);
  // Check the appropriate bytes of the stream to see if they match the
  // transaction ID of a response we are expecting.

  if (payload.size() < 20)
    return false;

  absl::string_view id(
      reinterpret_cast<const char*>(payload.data()) + kStunTransactionIdOffset,
      kStunTransactionIdLength);
  RequestMap::iterator iter = requests_.find(id);
  if (iter == requests_.end())
    return false;

  // Parse the STUN message and continue processing as usual.

  ByteBufferReader buf(payload);
  std::unique_ptr<StunMessage> response(iter->second->msg_->CreateNew());
  if (!response->Read(&buf)) {
    RTC_LOG(LS_WARNING) << "Failed to read STUN response " << hex_encode(id);
    return false;
  }

  return CheckResponse(response.get());
}

void StunRequestManager::OnRequestTimedOut(StunRequest* request) {
  RTC_DCHECK_RUN_ON(thread_);
  requests_.erase(request->id());
}

void StunRequestManager::SendPacket(std::span<const uint8_t> data,
                                    StunRequest* request) {
  RTC_DCHECK_EQ(this, request->manager());
  send_packet_(data, request);
}

StunRequest::StunRequest(const Environment& env, StunRequestManager& manager)
    : env_(env),
      manager_(manager),
      msg_(std::make_unique<StunMessage>(STUN_INVALID_MESSAGE_TYPE)),
      tstamp_(Timestamp::Zero()),
      count_(0),
      timeout_(false) {
  RTC_DCHECK_RUN_ON(network_thread());
}

StunRequest::StunRequest(const Environment& env,
                         StunRequestManager& manager,
                         std::unique_ptr<StunMessage> message)
    : env_(env),
      manager_(manager),
      msg_(std::move(message)),
      tstamp_(Timestamp::Zero()),
      count_(0),
      timeout_(false) {
  RTC_DCHECK_RUN_ON(network_thread());
  RTC_DCHECK(!msg_->transaction_id().empty());
}

StunRequest::~StunRequest() {}

int StunRequest::type() {
  RTC_DCHECK(msg_ != nullptr);
  return msg_->type();
}

const StunMessage* StunRequest::msg() const {
  return msg_.get();
}

TimeDelta StunRequest::Elapsed() const {
  RTC_DCHECK_RUN_ON(network_thread());
  return env_.clock().CurrentTime() - tstamp_;
}

void StunRequest::SendInternal() {
  RTC_DCHECK_RUN_ON(network_thread());
  if (timeout_) {
    OnTimeout();
    manager_.OnRequestTimedOut(this);
    return;
  }

  tstamp_ = env_.clock().CurrentTime();

  ByteBufferWriter buf;
  msg_->Write(&buf);
  manager_.SendPacket(buf.DataView(), this);

  OnSent();
  SendDelayed(TimeDelta::Millis(resend_delay()));
}

void StunRequest::SendDelayed(TimeDelta delay) {
  network_thread()->PostDelayedTask(
      SafeTask(task_safety_.flag(), [this]() { SendInternal(); }), delay);
}

void StunRequest::Send(TimeDelta delay) {
  RTC_DCHECK_RUN_ON(network_thread());
  RTC_DCHECK_GE(delay.ms(), 0);

  RTC_DCHECK(!task_safety_.flag()->alive()) << "Send already called?";
  task_safety_.flag()->SetAlive();

  delay.IsZero() ? SendInternal() : SendDelayed(delay);
}

void StunRequest::ResetTasksForTest() {
  RTC_DCHECK_RUN_ON(network_thread());
  task_safety_.reset(PendingTaskSafetyFlag::CreateDetachedInactive());
  count_ = 0;
  RTC_DCHECK(!timeout_);
}

void StunRequest::OnSent() {
  RTC_DCHECK_RUN_ON(network_thread());
  count_ += 1;
  int retransmissions = (count_ - 1);
  if (retransmissions >= STUN_MAX_RETRANSMISSIONS) {
    timeout_ = true;
  }
  RTC_DLOG(LS_VERBOSE) << "Sent STUN request " << count_
                       << "; resend delay = " << resend_delay();
}

int StunRequest::resend_delay() {
  RTC_DCHECK_RUN_ON(network_thread());
  if (count_ == 0) {
    return 0;
  }
  int retransmissions = (count_ - 1);
  int rto = STUN_INITIAL_RTO << retransmissions;
  return std::min(rto, STUN_MAX_RTO);
}

void StunRequest::set_timed_out() {
  RTC_DCHECK_RUN_ON(network_thread());
  timeout_ = true;
}

}  // namespace webrtc
