// 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.
const QuicPacketCount kPacketsBetweenMtuProbesBase = 100;

// The number of MTU probes that get sent before giving up.
const 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.
const QuicByteCount kMtuDiscoveryTargetPacketSizeHigh = 1400;
const 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 QUIC_EXPORT_PRIVATE 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_; }

  QUIC_EXPORT_PRIVATE 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_
