summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/quic_mtu_discovery.h
blob: b16cc6aedcaefa34a1b97cd4b8cd6c3572c91972 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// 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_