1 // Copyright 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 #include "quiche/quic/core/uber_received_packet_manager.h"
6
7 #include "quiche/quic/core/quic_types.h"
8 #include "quiche/quic/core/quic_utils.h"
9 #include "quiche/quic/platform/api/quic_bug_tracker.h"
10
11 namespace quic {
12
UberReceivedPacketManager(QuicConnectionStats * stats)13 UberReceivedPacketManager::UberReceivedPacketManager(QuicConnectionStats* stats)
14 : supports_multiple_packet_number_spaces_(false) {
15 for (auto& received_packet_manager : received_packet_managers_) {
16 received_packet_manager.set_connection_stats(stats);
17 }
18 }
19
~UberReceivedPacketManager()20 UberReceivedPacketManager::~UberReceivedPacketManager() {}
21
SetFromConfig(const QuicConfig & config,Perspective perspective)22 void UberReceivedPacketManager::SetFromConfig(const QuicConfig& config,
23 Perspective perspective) {
24 for (auto& received_packet_manager : received_packet_managers_) {
25 received_packet_manager.SetFromConfig(config, perspective);
26 }
27 }
28
IsAwaitingPacket(EncryptionLevel decrypted_packet_level,QuicPacketNumber packet_number) const29 bool UberReceivedPacketManager::IsAwaitingPacket(
30 EncryptionLevel decrypted_packet_level,
31 QuicPacketNumber packet_number) const {
32 if (!supports_multiple_packet_number_spaces_) {
33 return received_packet_managers_[0].IsAwaitingPacket(packet_number);
34 }
35 return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
36 decrypted_packet_level)]
37 .IsAwaitingPacket(packet_number);
38 }
39
GetUpdatedAckFrame(PacketNumberSpace packet_number_space,QuicTime approximate_now)40 const QuicFrame UberReceivedPacketManager::GetUpdatedAckFrame(
41 PacketNumberSpace packet_number_space, QuicTime approximate_now) {
42 if (!supports_multiple_packet_number_spaces_) {
43 return received_packet_managers_[0].GetUpdatedAckFrame(approximate_now);
44 }
45 return received_packet_managers_[packet_number_space].GetUpdatedAckFrame(
46 approximate_now);
47 }
48
RecordPacketReceived(EncryptionLevel decrypted_packet_level,const QuicPacketHeader & header,QuicTime receipt_time,QuicEcnCodepoint ecn_codepoint)49 void UberReceivedPacketManager::RecordPacketReceived(
50 EncryptionLevel decrypted_packet_level, const QuicPacketHeader& header,
51 QuicTime receipt_time, QuicEcnCodepoint ecn_codepoint) {
52 if (!supports_multiple_packet_number_spaces_) {
53 received_packet_managers_[0].RecordPacketReceived(header, receipt_time,
54 ecn_codepoint);
55 return;
56 }
57 received_packet_managers_[QuicUtils::GetPacketNumberSpace(
58 decrypted_packet_level)]
59 .RecordPacketReceived(header, receipt_time, ecn_codepoint);
60 }
61
DontWaitForPacketsBefore(EncryptionLevel decrypted_packet_level,QuicPacketNumber least_unacked)62 void UberReceivedPacketManager::DontWaitForPacketsBefore(
63 EncryptionLevel decrypted_packet_level, QuicPacketNumber least_unacked) {
64 if (!supports_multiple_packet_number_spaces_) {
65 received_packet_managers_[0].DontWaitForPacketsBefore(least_unacked);
66 return;
67 }
68 received_packet_managers_[QuicUtils::GetPacketNumberSpace(
69 decrypted_packet_level)]
70 .DontWaitForPacketsBefore(least_unacked);
71 }
72
MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,EncryptionLevel decrypted_packet_level,QuicPacketNumber last_received_packet_number,QuicTime last_packet_receipt_time,QuicTime now,const RttStats * rtt_stats)73 void UberReceivedPacketManager::MaybeUpdateAckTimeout(
74 bool should_last_packet_instigate_acks,
75 EncryptionLevel decrypted_packet_level,
76 QuicPacketNumber last_received_packet_number,
77 QuicTime last_packet_receipt_time, QuicTime now,
78 const RttStats* rtt_stats) {
79 if (!supports_multiple_packet_number_spaces_) {
80 received_packet_managers_[0].MaybeUpdateAckTimeout(
81 should_last_packet_instigate_acks, last_received_packet_number,
82 last_packet_receipt_time, now, rtt_stats);
83 return;
84 }
85 received_packet_managers_[QuicUtils::GetPacketNumberSpace(
86 decrypted_packet_level)]
87 .MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
88 last_received_packet_number,
89 last_packet_receipt_time, now, rtt_stats);
90 }
91
ResetAckStates(EncryptionLevel encryption_level)92 void UberReceivedPacketManager::ResetAckStates(
93 EncryptionLevel encryption_level) {
94 if (!supports_multiple_packet_number_spaces_) {
95 received_packet_managers_[0].ResetAckStates();
96 return;
97 }
98 received_packet_managers_[QuicUtils::GetPacketNumberSpace(encryption_level)]
99 .ResetAckStates();
100 if (encryption_level == ENCRYPTION_INITIAL) {
101 // After one Initial ACK is sent, the others should be sent 'immediately'.
102 received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
103 kAlarmGranularity);
104 }
105 }
106
EnableMultiplePacketNumberSpacesSupport(Perspective perspective)107 void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport(
108 Perspective perspective) {
109 if (supports_multiple_packet_number_spaces_) {
110 QUIC_BUG(quic_bug_10495_1)
111 << "Multiple packet number spaces has already been enabled";
112 return;
113 }
114 if (received_packet_managers_[0].GetLargestObserved().IsInitialized()) {
115 QUIC_BUG(quic_bug_10495_2)
116 << "Try to enable multiple packet number spaces support after any "
117 "packet has been received.";
118 return;
119 }
120 // In IETF QUIC, the peer is expected to acknowledge packets in Initial and
121 // Handshake packets with minimal delay.
122 if (perspective == Perspective::IS_CLIENT) {
123 // Delay the first server ACK, because server ACKs are padded to
124 // full size and count towards the amplification limit.
125 received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
126 kAlarmGranularity);
127 }
128 received_packet_managers_[HANDSHAKE_DATA].set_local_max_ack_delay(
129 kAlarmGranularity);
130
131 supports_multiple_packet_number_spaces_ = true;
132 }
133
IsAckFrameUpdated() const134 bool UberReceivedPacketManager::IsAckFrameUpdated() const {
135 if (!supports_multiple_packet_number_spaces_) {
136 return received_packet_managers_[0].ack_frame_updated();
137 }
138 for (const auto& received_packet_manager : received_packet_managers_) {
139 if (received_packet_manager.ack_frame_updated()) {
140 return true;
141 }
142 }
143 return false;
144 }
145
GetLargestObserved(EncryptionLevel decrypted_packet_level) const146 QuicPacketNumber UberReceivedPacketManager::GetLargestObserved(
147 EncryptionLevel decrypted_packet_level) const {
148 if (!supports_multiple_packet_number_spaces_) {
149 return received_packet_managers_[0].GetLargestObserved();
150 }
151 return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
152 decrypted_packet_level)]
153 .GetLargestObserved();
154 }
155
GetAckTimeout(PacketNumberSpace packet_number_space) const156 QuicTime UberReceivedPacketManager::GetAckTimeout(
157 PacketNumberSpace packet_number_space) const {
158 if (!supports_multiple_packet_number_spaces_) {
159 return received_packet_managers_[0].ack_timeout();
160 }
161 return received_packet_managers_[packet_number_space].ack_timeout();
162 }
163
GetEarliestAckTimeout() const164 QuicTime UberReceivedPacketManager::GetEarliestAckTimeout() const {
165 QuicTime ack_timeout = QuicTime::Zero();
166 // Returns the earliest non-zero ack timeout.
167 for (const auto& received_packet_manager : received_packet_managers_) {
168 const QuicTime timeout = received_packet_manager.ack_timeout();
169 if (!ack_timeout.IsInitialized()) {
170 ack_timeout = timeout;
171 continue;
172 }
173 if (timeout.IsInitialized()) {
174 ack_timeout = std::min(ack_timeout, timeout);
175 }
176 }
177 return ack_timeout;
178 }
179
IsAckFrameEmpty(PacketNumberSpace packet_number_space) const180 bool UberReceivedPacketManager::IsAckFrameEmpty(
181 PacketNumberSpace packet_number_space) const {
182 if (!supports_multiple_packet_number_spaces_) {
183 return received_packet_managers_[0].IsAckFrameEmpty();
184 }
185 return received_packet_managers_[packet_number_space].IsAckFrameEmpty();
186 }
187
peer_least_packet_awaiting_ack() const188 QuicPacketNumber UberReceivedPacketManager::peer_least_packet_awaiting_ack()
189 const {
190 QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
191 return received_packet_managers_[0].peer_least_packet_awaiting_ack();
192 }
193
min_received_before_ack_decimation() const194 size_t UberReceivedPacketManager::min_received_before_ack_decimation() const {
195 return received_packet_managers_[0].min_received_before_ack_decimation();
196 }
197
set_min_received_before_ack_decimation(size_t new_value)198 void UberReceivedPacketManager::set_min_received_before_ack_decimation(
199 size_t new_value) {
200 for (auto& received_packet_manager : received_packet_managers_) {
201 received_packet_manager.set_min_received_before_ack_decimation(new_value);
202 }
203 }
204
set_ack_frequency(size_t new_value)205 void UberReceivedPacketManager::set_ack_frequency(size_t new_value) {
206 for (auto& received_packet_manager : received_packet_managers_) {
207 received_packet_manager.set_ack_frequency(new_value);
208 }
209 }
210
ack_frame() const211 const QuicAckFrame& UberReceivedPacketManager::ack_frame() const {
212 QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
213 return received_packet_managers_[0].ack_frame();
214 }
215
GetAckFrame(PacketNumberSpace packet_number_space) const216 const QuicAckFrame& UberReceivedPacketManager::GetAckFrame(
217 PacketNumberSpace packet_number_space) const {
218 QUICHE_DCHECK(supports_multiple_packet_number_spaces_);
219 return received_packet_managers_[packet_number_space].ack_frame();
220 }
221
set_max_ack_ranges(size_t max_ack_ranges)222 void UberReceivedPacketManager::set_max_ack_ranges(size_t max_ack_ranges) {
223 for (auto& received_packet_manager : received_packet_managers_) {
224 received_packet_manager.set_max_ack_ranges(max_ack_ranges);
225 }
226 }
227
set_save_timestamps(bool save_timestamps)228 void UberReceivedPacketManager::set_save_timestamps(bool save_timestamps) {
229 for (auto& received_packet_manager : received_packet_managers_) {
230 received_packet_manager.set_save_timestamps(
231 save_timestamps, supports_multiple_packet_number_spaces_);
232 }
233 }
234
OnAckFrequencyFrame(const QuicAckFrequencyFrame & frame)235 void UberReceivedPacketManager::OnAckFrequencyFrame(
236 const QuicAckFrequencyFrame& frame) {
237 if (!supports_multiple_packet_number_spaces_) {
238 QUIC_BUG(quic_bug_10495_3)
239 << "Received AckFrequencyFrame when multiple packet number spaces "
240 "is not supported";
241 return;
242 }
243 received_packet_managers_[APPLICATION_DATA].OnAckFrequencyFrame(frame);
244 }
245
246 } // namespace quic
247