1 // Copyright (c) 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_ 6 #define QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_ 7 8 #include <iostream> 9 10 #include "net/third_party/quiche/src/quic/core/quic_constants.h" 11 #include "net/third_party/quiche/src/quic/core/quic_types.h" 12 13 namespace quic { 14 15 // The initial number of packets between MTU probes. After each attempt the 16 // number is doubled. 17 const QuicPacketCount kPacketsBetweenMtuProbesBase = 100; 18 19 // The number of MTU probes that get sent before giving up. 20 const size_t kMtuDiscoveryAttempts = 3; 21 22 // Ensure that exponential back-off does not result in an integer overflow. 23 // The number of packets can be potentially capped, but that is not useful at 24 // current kMtuDiscoveryAttempts value, and hence is not implemented at present. 25 static_assert(kMtuDiscoveryAttempts + 8 < 8 * sizeof(QuicPacketNumber), 26 "The number of MTU discovery attempts is too high"); 27 static_assert(kPacketsBetweenMtuProbesBase < (1 << 8), 28 "The initial number of packets between MTU probes is too high"); 29 30 // The incresed packet size targeted when doing path MTU discovery. 31 const QuicByteCount kMtuDiscoveryTargetPacketSizeHigh = 1450; 32 const QuicByteCount kMtuDiscoveryTargetPacketSizeLow = 1430; 33 34 static_assert(kMtuDiscoveryTargetPacketSizeLow <= kMaxOutgoingPacketSize, 35 "MTU discovery target is too large"); 36 static_assert(kMtuDiscoveryTargetPacketSizeHigh <= kMaxOutgoingPacketSize, 37 "MTU discovery target is too large"); 38 39 static_assert(kMtuDiscoveryTargetPacketSizeLow > kDefaultMaxPacketSize, 40 "MTU discovery target does not exceed the default packet size"); 41 static_assert(kMtuDiscoveryTargetPacketSizeHigh > kDefaultMaxPacketSize, 42 "MTU discovery target does not exceed the default packet size"); 43 44 // QuicConnectionMtuDiscoverer is a MTU discovery controller, it answers two 45 // questions: 46 // 1) Probe scheduling: Whether a connection should send a MTU probe packet 47 // right now. 48 // 2) MTU search stradegy: When it is time to send, what should be the size of 49 // the probing packet. 50 // Note the discoverer does not actually send or process probing packets. 51 // 52 // Unit tests are in QuicConnectionTest.MtuDiscovery*. 53 class QUIC_EXPORT_PRIVATE QuicConnectionMtuDiscoverer { 54 public: 55 // Construct a discoverer in the disabled state. 56 QuicConnectionMtuDiscoverer() = default; 57 58 // Construct a discoverer in the disabled state, with the given parameters. 59 QuicConnectionMtuDiscoverer(QuicPacketCount packets_between_probes_base, 60 QuicPacketNumber next_probe_at); 61 62 // Enable the discoverer by setting the probe target. 63 // max_packet_length: The max packet length currently used. 64 // target_max_packet_length: The target max packet length to probe. 65 void Enable(QuicByteCount max_packet_length, 66 QuicByteCount target_max_packet_length); 67 68 // Disable the discoverer by unsetting the probe target. 69 void Disable(); 70 71 // Whether a MTU probe packet should be sent right now. 72 // Always return false if disabled. 73 bool ShouldProbeMtu(QuicPacketNumber largest_sent_packet) const; 74 75 // Called immediately before a probing packet is sent, to get the size of the 76 // packet. 77 // REQUIRES: ShouldProbeMtu(largest_sent_packet) == true. 78 QuicPacketLength GetUpdatedMtuProbeSize(QuicPacketNumber largest_sent_packet); 79 80 // Called after the max packet length is updated, which is triggered by a ack 81 // of a probing packet. 82 void OnMaxPacketLengthUpdated(QuicByteCount old_value, 83 QuicByteCount new_value); 84 packets_between_probes()85 QuicPacketCount packets_between_probes() const { 86 return packets_between_probes_; 87 } 88 next_probe_at()89 QuicPacketNumber next_probe_at() const { return next_probe_at_; } 90 91 QUIC_EXPORT_PRIVATE friend std::ostream& operator<<( 92 std::ostream& os, 93 const QuicConnectionMtuDiscoverer& d); 94 95 private: 96 bool IsEnabled() const; 97 QuicPacketLength next_probe_packet_length() const; 98 99 QuicPacketLength min_probe_length_ = 0; 100 QuicPacketLength max_probe_length_ = 0; 101 102 QuicPacketLength last_probe_length_ = 0; 103 104 uint16_t remaining_probe_count_ = kMtuDiscoveryAttempts; 105 106 // The number of packets between MTU probes. 107 QuicPacketCount packets_between_probes_ = kPacketsBetweenMtuProbesBase; 108 109 // The packet number of the packet after which the next MTU probe will be 110 // sent. 111 QuicPacketNumber next_probe_at_ = 112 QuicPacketNumber(kPacketsBetweenMtuProbesBase); 113 }; 114 115 } // namespace quic 116 117 #endif // QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_ 118