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