// Copyright (c) 2020 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.

#ifndef QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
#define QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_

#include <memory>
#include <ostream>

#include "absl/container/inlined_vector.h"
#include "quiche/quic/core/crypto/quic_random.h"
#include "quiche/quic/core/quic_alarm.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_arena_scoped_ptr.h"
#include "quiche/quic/core/quic_clock.h"
#include "quiche/quic/core/quic_connection_context.h"
#include "quiche/quic/core/quic_one_block_arena.h"
#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_socket_address.h"

namespace quic {

namespace test {
class QuicPathValidatorPeer;
}

class QuicConnection;

enum class PathValidationReason {
  kReasonUnknown,
  kMultiPort,
  kReversePathValidation,
  kServerPreferredAddressMigration,
  kPortMigration,
  kConnectionMigration,
  kMaxValue,
};

// Interface to provide the information of the path to be validated.
class QUIC_EXPORT_PRIVATE QuicPathValidationContext {
 public:
  QuicPathValidationContext(const QuicSocketAddress& self_address,
                            const QuicSocketAddress& peer_address)
      : self_address_(self_address),
        peer_address_(peer_address),
        effective_peer_address_(peer_address) {}

  QuicPathValidationContext(const QuicSocketAddress& self_address,
                            const QuicSocketAddress& peer_address,
                            const QuicSocketAddress& effective_peer_address)
      : self_address_(self_address),
        peer_address_(peer_address),
        effective_peer_address_(effective_peer_address) {}

  virtual ~QuicPathValidationContext() = default;

  virtual QuicPacketWriter* WriterToUse() = 0;

  const QuicSocketAddress& self_address() const { return self_address_; }
  const QuicSocketAddress& peer_address() const { return peer_address_; }
  const QuicSocketAddress& effective_peer_address() const {
    return effective_peer_address_;
  }

 private:
  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
      std::ostream& os, const QuicPathValidationContext& context);

  QuicSocketAddress self_address_;
  // The address to send PATH_CHALLENGE.
  QuicSocketAddress peer_address_;
  // The actual peer address which is different from |peer_address_| if the peer
  // is behind a proxy.
  QuicSocketAddress effective_peer_address_;
};

// Used to validate a path by sending up to 3 PATH_CHALLENGE frames before
// declaring a path validation failure.
class QUIC_EXPORT_PRIVATE QuicPathValidator {
 public:
  static const uint16_t kMaxRetryTimes = 2;

  // Used to write PATH_CHALLENGE on the path to be validated and to get retry
  // timeout.
  class QUIC_EXPORT_PRIVATE SendDelegate {
   public:
    virtual ~SendDelegate() = default;

    // Send a PATH_CHALLENGE with |data_buffer| as the frame payload using given
    // path information. Return false if the delegate doesn't want to continue
    // the validation.
    virtual bool SendPathChallenge(
        const QuicPathFrameBuffer& data_buffer,
        const QuicSocketAddress& self_address,
        const QuicSocketAddress& peer_address,
        const QuicSocketAddress& effective_peer_address,
        QuicPacketWriter* writer) = 0;
    // Return the time to retry sending PATH_CHALLENGE again based on given peer
    // address and writer.
    virtual QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address,
                                     QuicPacketWriter* writer) const = 0;
  };

  // Handles the validation result.
  // TODO(danzh) consider to simplify this interface and its life time to
  // outlive a validation.
  class QUIC_EXPORT_PRIVATE ResultDelegate {
   public:
    virtual ~ResultDelegate() = default;

    // Called when a PATH_RESPONSE is received with a matching PATH_CHALLANGE.
    // |start_time| is the time when the matching PATH_CHALLANGE was sent.
    virtual void OnPathValidationSuccess(
        std::unique_ptr<QuicPathValidationContext> context,
        QuicTime start_time) = 0;

    virtual void OnPathValidationFailure(
        std::unique_ptr<QuicPathValidationContext> context) = 0;
  };

  QuicPathValidator(QuicAlarmFactory* alarm_factory, QuicConnectionArena* arena,
                    SendDelegate* delegate, QuicRandom* random,
                    const QuicClock* clock, QuicConnectionContext* context);

  // Send PATH_CHALLENGE and start the retry timer.
  void StartPathValidation(std::unique_ptr<QuicPathValidationContext> context,
                           std::unique_ptr<ResultDelegate> result_delegate,
                           PathValidationReason reason);

  // Called when a PATH_RESPONSE frame has been received. Matches the received
  // PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE
  // frames and the self address on which it was sent.
  void OnPathResponse(const QuicPathFrameBuffer& probing_data,
                      QuicSocketAddress self_address);

  // Cancel the retry timer and reset the path and result delegate.
  void CancelPathValidation();

  bool HasPendingPathValidation() const;

  QuicPathValidationContext* GetContext() const;

  // Pass the ownership of path_validation context to the caller and reset the
  // validator.
  std::unique_ptr<QuicPathValidationContext> ReleaseContext();

  PathValidationReason GetPathValidationReason() const { return reason_; }

  // Send another PATH_CHALLENGE on the same path. After retrying
  // |kMaxRetryTimes| times, fail the current path validation.
  void OnRetryTimeout();

  bool IsValidatingPeerAddress(const QuicSocketAddress& effective_peer_address);

  // Called to send packet to |peer_address| if the path validation to this
  // address is pending.
  void MaybeWritePacketToAddress(const char* buffer, size_t buf_len,
                                 const QuicSocketAddress& peer_address);

 private:
  friend class test::QuicPathValidatorPeer;

  // Return the payload to be used in the next PATH_CHALLENGE frame.
  const QuicPathFrameBuffer& GeneratePathChallengePayload();

  void SendPathChallengeAndSetAlarm();

  void ResetPathValidation();

  struct QUIC_NO_EXPORT ProbingData {
    explicit ProbingData(QuicTime send_time) : send_time(send_time) {}
    QuicPathFrameBuffer frame_buffer;
    QuicTime send_time;
  };

  // Has at most 3 entries due to validation timeout.
  absl::InlinedVector<ProbingData, 3> probing_data_;
  SendDelegate* send_delegate_;
  QuicRandom* random_;
  const QuicClock* clock_;
  std::unique_ptr<QuicPathValidationContext> path_context_;
  std::unique_ptr<ResultDelegate> result_delegate_;
  QuicArenaScopedPtr<QuicAlarm> retry_timer_;
  size_t retry_count_;
  PathValidationReason reason_ = PathValidationReason::kReasonUnknown;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
