/*
 *  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 <memory>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "rtc_base/checks.h"
#include "rtc_base/helpers.h"
#include "rtc_base/logging.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/time_utils.h"  // For TimeMillis

namespace cricket {
using ::webrtc::SafeTask;

// 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(
    webrtc::TaskQueueBase* thread,
    std::function<void(const void*, size_t, StunRequest*)> send_packet)
    : thread_(thread), send_packet_(std::move(send_packet)) {}

StunRequestManager::~StunRequestManager() = default;

void StunRequestManager::Send(StunRequest* request) {
  SendDelayed(request, 0);
}

void StunRequestManager::SendDelayed(StunRequest* request, int 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(), absl::WrapUnique(request));
  RTC_DCHECK(was_inserted);
  request->Send(webrtc::TimeDelta::Millis(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(webrtc::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()) {
    // This is a STUN_BINDING to from stun_port.cc or
    // the initial (unauthenticated) TURN_ALLOCATE_REQUEST.
  } 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->integrity() == StunMessage::IntegrityStatus::kIntegrityOk &&
               msg->password() == request->msg()->password()) {
      // Status is already checked, with the same password. This is the case
      // we would want to see happen.
    } else if (msg->integrity() ==
               StunMessage::IntegrityStatus::kIntegrityBad) {
      // This indicates that the original check had the wrong password.
      // Bad design, needs revisiting.
      // TODO(crbug.com/1177125): Fix this.
      msg->RevalidateMessageIntegrity(request->msg()->password());
    } else {
      RTC_CHECK_NOTREACHED();
    }
  }

  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(const char* data, size_t size) {
  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 (size < 20)
    return false;

  std::string id;
  id.append(data + kStunTransactionIdOffset, kStunTransactionIdLength);

  RequestMap::iterator iter = requests_.find(id);
  if (iter == requests_.end())
    return false;

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

  rtc::ByteBufferReader buf(data, size);
  std::unique_ptr<StunMessage> response(iter->second->msg_->CreateNew());
  if (!response->Read(&buf)) {
    RTC_LOG(LS_WARNING) << "Failed to read STUN response "
                        << rtc::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(const void* data,
                                    size_t size,
                                    StunRequest* request) {
  RTC_DCHECK_EQ(this, request->manager());
  send_packet_(data, size, request);
}

StunRequest::StunRequest(StunRequestManager& manager)
    : manager_(manager),
      msg_(new StunMessage(STUN_INVALID_MESSAGE_TYPE)),
      tstamp_(0),
      count_(0),
      timeout_(false) {
  RTC_DCHECK_RUN_ON(network_thread());
}

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

StunRequest::~StunRequest() {}

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

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

int StunRequest::Elapsed() const {
  RTC_DCHECK_RUN_ON(network_thread());
  return static_cast<int>(rtc::TimeMillis() - tstamp_);
}

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

  tstamp_ = rtc::TimeMillis();

  rtc::ByteBufferWriter buf;
  msg_->Write(&buf);
  manager_.SendPacket(buf.Data(), buf.Length(), this);

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

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

void StunRequest::Send(webrtc::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(webrtc::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 cricket
