blob: b16cc6aedcaefa34a1b97cd4b8cd6c3572c91972 [file] [log] [blame]
// 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 "quic/core/quic_constants.h"
#include "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 incresed packet size targeted when doing path MTU discovery.
const QuicByteCount kMtuDiscoveryTargetPacketSizeHigh = 1450;
const QuicByteCount kMtuDiscoveryTargetPacketSizeLow = 1430;
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_