summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h
blob: a0b5199b254d3718b1a894ed1061e9f598c64067 (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// Copyright 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_CONGESTION_CONTROL_BBR2_SENDER_H_
#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_

#include <cstdint>

#include "quic/core/congestion_control/bandwidth_sampler.h"
#include "quic/core/congestion_control/bbr2_drain.h"
#include "quic/core/congestion_control/bbr2_misc.h"
#include "quic/core/congestion_control/bbr2_probe_bw.h"
#include "quic/core/congestion_control/bbr2_probe_rtt.h"
#include "quic/core/congestion_control/bbr2_startup.h"
#include "quic/core/congestion_control/bbr_sender.h"
#include "quic/core/congestion_control/rtt_stats.h"
#include "quic/core/congestion_control/send_algorithm_interface.h"
#include "quic/core/congestion_control/windowed_filter.h"
#include "quic/core/quic_bandwidth.h"
#include "quic/core/quic_types.h"
#include "quic/platform/api/quic_export.h"
#include "quic/platform/api/quic_flags.h"

namespace quic {

class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface {
 public:
  Bbr2Sender(QuicTime now,
             const RttStats* rtt_stats,
             const QuicUnackedPacketMap* unacked_packets,
             QuicPacketCount initial_cwnd_in_packets,
             QuicPacketCount max_cwnd_in_packets,
             QuicRandom* random,
             QuicConnectionStats* stats,
             BbrSender* old_sender);

  ~Bbr2Sender() override = default;

  // Start implementation of SendAlgorithmInterface.
  bool InSlowStart() const override { return mode_ == Bbr2Mode::STARTUP; }

  bool InRecovery() const override {
    // TODO(wub): Implement Recovery.
    return false;
  }

  bool ShouldSendProbingPacket() const override;

  void SetFromConfig(const QuicConfig& config,
                     Perspective perspective) override;

  void ApplyConnectionOptions(const QuicTagVector& connection_options) override;

  void AdjustNetworkParameters(const NetworkParams& params) override;

  void SetInitialCongestionWindowInPackets(
      QuicPacketCount congestion_window) override;

  void OnCongestionEvent(bool rtt_updated,
                         QuicByteCount prior_in_flight,
                         QuicTime event_time,
                         const AckedPacketVector& acked_packets,
                         const LostPacketVector& lost_packets) override;

  void OnPacketSent(QuicTime sent_time,
                    QuicByteCount bytes_in_flight,
                    QuicPacketNumber packet_number,
                    QuicByteCount bytes,
                    HasRetransmittableData is_retransmittable) override;

  void OnPacketNeutered(QuicPacketNumber packet_number) override;

  void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}

  void OnConnectionMigration() override {}

  bool CanSend(QuicByteCount bytes_in_flight) override;

  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;

  QuicBandwidth BandwidthEstimate() const override {
    return model_.BandwidthEstimate();
  }

  QuicByteCount GetCongestionWindow() const override;

  QuicByteCount GetSlowStartThreshold() const override { return 0; }

  CongestionControlType GetCongestionControlType() const override {
    return kBBRv2;
  }

  std::string GetDebugState() const override;

  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;

  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
  // End implementation of SendAlgorithmInterface.

  const Bbr2Params& Params() const { return params_; }

  QuicByteCount GetMinimumCongestionWindow() const {
    return cwnd_limits().Min();
  }

  // Returns the min of BDP and congestion window.
  QuicByteCount GetTargetBytesInflight() const;

  bool IsBandwidthOverestimateAvoidanceEnabled() const {
    return model_.IsBandwidthOverestimateAvoidanceEnabled();
  }

  struct QUIC_EXPORT_PRIVATE DebugState {
    Bbr2Mode mode;

    // Shared states.
    QuicRoundTripCount round_trip_count;
    QuicBandwidth bandwidth_hi = QuicBandwidth::Zero();
    QuicBandwidth bandwidth_lo = QuicBandwidth::Zero();
    QuicBandwidth bandwidth_est = QuicBandwidth::Zero();
    QuicByteCount inflight_hi;
    QuicByteCount inflight_lo;
    QuicByteCount max_ack_height;
    QuicTime::Delta min_rtt = QuicTime::Delta::Zero();
    QuicTime min_rtt_timestamp = QuicTime::Zero();
    QuicByteCount congestion_window;
    QuicBandwidth pacing_rate = QuicBandwidth::Zero();
    bool last_sample_is_app_limited;
    QuicPacketNumber end_of_app_limited_phase;

    // Mode-specific debug states.
    Bbr2StartupMode::DebugState startup;
    Bbr2DrainMode::DebugState drain;
    Bbr2ProbeBwMode::DebugState probe_bw;
    Bbr2ProbeRttMode::DebugState probe_rtt;
  };

  DebugState ExportDebugState() const;

 private:
  void UpdatePacingRate(QuicByteCount bytes_acked);
  void UpdateCongestionWindow(QuicByteCount bytes_acked);
  QuicByteCount GetTargetCongestionWindow(float gain) const;
  void OnEnterQuiescence(QuicTime now);
  void OnExitQuiescence(QuicTime now);

  // Helper function for BBR2_MODE_DISPATCH.
  Bbr2ProbeRttMode& probe_rtt_or_die() {
    QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
    return probe_rtt_;
  }

  const Bbr2ProbeRttMode& probe_rtt_or_die() const {
    QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
    return probe_rtt_;
  }

  uint64_t RandomUint64(uint64_t max) const {
    return random_->RandUint64() % max;
  }

  // Cwnd limits imposed by the current Bbr2 mode.
  Limits<QuicByteCount> GetCwndLimitsByMode() const;

  // Cwnd limits imposed by caller.
  const Limits<QuicByteCount>& cwnd_limits() const;

  const Bbr2Params& params() const { return params_; }

  Bbr2Mode mode_;

  const RttStats* const rtt_stats_;
  const QuicUnackedPacketMap* const unacked_packets_;
  QuicRandom* random_;
  QuicConnectionStats* connection_stats_;

  // Don't use it directly outside of SetFromConfig and ApplyConnectionOptions.
  // Instead, use params() to get read-only access.
  Bbr2Params params_;

  // Max congestion window when adjusting network parameters.
  QuicByteCount max_cwnd_when_network_parameters_adjusted_ =
      kMaxInitialCongestionWindow * kDefaultTCPMSS;

  Bbr2NetworkModel model_;

  const QuicByteCount initial_cwnd_;

  // Current cwnd and pacing rate.
  QuicByteCount cwnd_;
  QuicBandwidth pacing_rate_;

  QuicTime last_quiescence_start_ = QuicTime::Zero();

  Bbr2StartupMode startup_;
  Bbr2DrainMode drain_;
  Bbr2ProbeBwMode probe_bw_;
  Bbr2ProbeRttMode probe_rtt_;

  // Debug only.
  bool last_sample_is_app_limited_;

  friend class Bbr2StartupMode;
  friend class Bbr2DrainMode;
  friend class Bbr2ProbeBwMode;
  friend class Bbr2ProbeRttMode;
};

QUIC_EXPORT_PRIVATE std::ostream& operator<<(
    std::ostream& os,
    const Bbr2Sender::DebugState& state);

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_