// Copyright (c) 2019 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_MTU_DISCOVERY_H_
#define QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_

#include <iostream>

#include "quiche/quic/core/quic_constants.h"
#include "quiche/quic/core/quic_types.h"

namespace quic {

// The initial number of packets between MTU probes.  After each attempt the
// number is doubled.
inline constexpr QuicPacketCount kPacketsBetweenMtuProbesBase = 100;

// The number of MTU probes that get sent before giving up.
inline constexpr size_t kMtuDiscoveryAttempts = 3;

// Ensure that exponential back-off does not result in an integer overflow.
// The number of packets can be potentially capped, but that is not useful at
// current kMtuDiscoveryAttempts value, and hence is not implemented at present.
static_assert(kMtuDiscoveryAttempts + 8 < 8 * sizeof(QuicPacketNumber),
              "The number of MTU discovery attempts is too high");
static_assert(kPacketsBetweenMtuProbesBase < (1 << 8),
              "The initial number of packets between MTU probes is too high");

// The increased packet size targeted when doing path MTU discovery.
inline constexpr QuicByteCount kMtuDiscoveryTargetPacketSizeHigh = 1400;
inline constexpr QuicByteCount kMtuDiscoveryTargetPacketSizeLow = 1380;

static_assert(kMtuDiscoveryTargetPacketSizeLow <= kMaxOutgoingPacketSize,
              "MTU discovery target is too large");
static_assert(kMtuDiscoveryTargetPacketSizeHigh <= kMaxOutgoingPacketSize,
              "MTU discovery target is too large");

static_assert(kMtuDiscoveryTargetPacketSizeLow > kDefaultMaxPacketSize,
              "MTU discovery target does not exceed the default packet size");
static_assert(kMtuDiscoveryTargetPacketSizeHigh > kDefaultMaxPacketSize,
              "MTU discovery target does not exceed the default packet size");

// QuicConnectionMtuDiscoverer is a MTU discovery controller, it answers two
// questions:
// 1) Probe scheduling: Whether a connection should send a MTU probe packet
//    right now.
// 2) MTU search stradegy: When it is time to send, what should be the size of
//    the probing packet.
// Note the discoverer does not actually send or process probing packets.
//
// Unit tests are in QuicConnectionTest.MtuDiscovery*.
class QUICHE_EXPORT QuicConnectionMtuDiscoverer {
 public:
  // Construct a discoverer in the disabled state.
  QuicConnectionMtuDiscoverer() = default;

  // Construct a discoverer in the disabled state, with the given parameters.
  QuicConnectionMtuDiscoverer(QuicPacketCount packets_between_probes_base,
                              QuicPacketNumber next_probe_at);

  // Enable the discoverer by setting the probe target.
  // max_packet_length: The max packet length currently used.
  // target_max_packet_length: The target max packet length to probe.
  void Enable(QuicByteCount max_packet_length,
              QuicByteCount target_max_packet_length);

  // Disable the discoverer by unsetting the probe target.
  void Disable();

  // Whether a MTU probe packet should be sent right now.
  // Always return false if disabled.
  bool ShouldProbeMtu(QuicPacketNumber largest_sent_packet) const;

  // Called immediately before a probing packet is sent, to get the size of the
  // packet.
  // REQUIRES: ShouldProbeMtu(largest_sent_packet) == true.
  QuicPacketLength GetUpdatedMtuProbeSize(QuicPacketNumber largest_sent_packet);

  // Called after the max packet length is updated, which is triggered by a ack
  // of a probing packet.
  void OnMaxPacketLengthUpdated(QuicByteCount old_value,
                                QuicByteCount new_value);

  QuicPacketCount packets_between_probes() const {
    return packets_between_probes_;
  }

  QuicPacketNumber next_probe_at() const { return next_probe_at_; }

  QUICHE_EXPORT friend std::ostream& operator<<(
      std::ostream& os, const QuicConnectionMtuDiscoverer& d);

 private:
  bool IsEnabled() const;
  QuicPacketLength next_probe_packet_length() const;

  QuicPacketLength min_probe_length_ = 0;
  QuicPacketLength max_probe_length_ = 0;

  QuicPacketLength last_probe_length_ = 0;

  uint16_t remaining_probe_count_ = kMtuDiscoveryAttempts;

  // The number of packets between MTU probes.
  QuicPacketCount packets_between_probes_ = kPacketsBetweenMtuProbesBase;

  // The packet number of the packet after which the next MTU probe will be
  // sent.
  QuicPacketNumber next_probe_at_ =
      QuicPacketNumber(kPacketsBetweenMtuProbesBase);
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
