OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "net/quic/quic_multipath_sent_packet_manager.h" | |
6 | |
7 #include <cstdint> | |
8 | |
9 #include "base/strings/string_number_conversions.h" | |
10 #include "net/quic/quic_bug_tracker.h" | |
11 | |
12 using std::string; | |
13 using std::max; | |
14 | |
15 namespace net { | |
16 | |
17 QuicMultipathSentPacketManager::QuicMultipathSentPacketManager( | |
18 QuicSentPacketManagerInterface* manager, | |
19 QuicConnectionCloseDelegateInterface* delegate) | |
20 : delegate_(delegate) { | |
21 path_managers_info_.push_back(PathSentPacketManagerInfo(manager, ACTIVE)); | |
22 } | |
23 | |
24 QuicMultipathSentPacketManager::~QuicMultipathSentPacketManager() { | |
25 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
26 delete path_manager_info.manager; | |
27 } | |
28 } | |
29 | |
30 void QuicMultipathSentPacketManager::SetFromConfig(const QuicConfig& config) { | |
31 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
32 if (path_manager_info.manager != nullptr) { | |
33 path_manager_info.manager->SetFromConfig(config); | |
34 } | |
35 } | |
36 } | |
37 | |
38 void QuicMultipathSentPacketManager::ResumeConnectionState( | |
39 const CachedNetworkParameters& cached_network_params, | |
40 bool max_bandwidth_resumption) { | |
41 QuicSentPacketManagerInterface* path_manager = | |
42 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
43 if (path_manager == nullptr) { | |
44 OnUnrecoverablePathError(kDefaultPathId); | |
45 return; | |
46 } | |
47 path_manager->ResumeConnectionState(cached_network_params, | |
48 max_bandwidth_resumption); | |
49 } | |
50 | |
51 void QuicMultipathSentPacketManager::SetNumOpenStreams(size_t num_streams) { | |
52 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
53 if (path_manager_info.manager != nullptr) { | |
54 path_manager_info.manager->SetNumOpenStreams(num_streams); | |
55 } | |
56 } | |
57 } | |
58 | |
59 void QuicMultipathSentPacketManager::SetMaxPacingRate( | |
60 QuicBandwidth max_pacing_rate) { | |
61 QuicSentPacketManagerInterface* path_manager = | |
62 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
63 if (path_manager == nullptr) { | |
64 OnUnrecoverablePathError(kDefaultPathId); | |
65 return; | |
66 } | |
67 path_manager->SetMaxPacingRate(max_pacing_rate); | |
68 } | |
69 | |
70 void QuicMultipathSentPacketManager::SetHandshakeConfirmed() { | |
71 QuicSentPacketManagerInterface* path_manager = | |
72 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
73 if (path_manager == nullptr) { | |
74 OnUnrecoverablePathError(kDefaultPathId); | |
75 return; | |
76 } | |
77 path_manager->SetHandshakeConfirmed(); | |
78 } | |
79 | |
80 void QuicMultipathSentPacketManager::OnIncomingAck( | |
81 const QuicAckFrame& ack_frame, | |
82 QuicTime ack_receive_time) { | |
83 if (ack_frame.path_id >= path_managers_info_.size() || | |
84 path_managers_info_[ack_frame.path_id].state != ACTIVE) { | |
85 return; | |
86 } | |
87 path_managers_info_[ack_frame.path_id].manager->OnIncomingAck( | |
88 ack_frame, ack_receive_time); | |
89 } | |
90 | |
91 void QuicMultipathSentPacketManager::RetransmitUnackedPackets( | |
92 TransmissionType retransmission_type) { | |
93 QuicSentPacketManagerInterface* path_manager = | |
94 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
95 if (path_manager == nullptr) { | |
96 OnUnrecoverablePathError(kDefaultPathId); | |
97 return; | |
98 } | |
99 path_manager->RetransmitUnackedPackets(retransmission_type); | |
100 } | |
101 | |
102 bool QuicMultipathSentPacketManager::MaybeRetransmitTailLossProbe() { | |
103 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
104 if (path_manager_info.manager != nullptr && | |
105 path_manager_info.state == ACTIVE) { | |
106 if (path_manager_info.manager->MaybeRetransmitTailLossProbe()) { | |
107 return true; | |
108 } | |
109 } | |
110 } | |
111 return false; | |
112 } | |
113 | |
114 void QuicMultipathSentPacketManager::NeuterUnencryptedPackets() { | |
115 QuicSentPacketManagerInterface* path_manager = | |
116 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
117 if (path_manager == nullptr) { | |
118 OnUnrecoverablePathError(kDefaultPathId); | |
119 return; | |
120 } | |
121 path_manager->NeuterUnencryptedPackets(); | |
122 } | |
123 | |
124 bool QuicMultipathSentPacketManager::HasPendingRetransmissions() const { | |
125 // TODO(fayang): Move pending_retransmissions_ from path sent packet manager | |
126 // to multipath sent packet manager. | |
127 QuicSentPacketManagerInterface* path_manager = | |
128 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
129 return path_manager != nullptr && path_manager->HasPendingRetransmissions(); | |
130 } | |
131 | |
132 PendingRetransmission | |
133 QuicMultipathSentPacketManager::NextPendingRetransmission() { | |
134 // TODO(fayang): Move pending_retransmissions_ from path sent packet manager | |
135 // to multipath sent packet manager. | |
136 QuicSentPacketManagerInterface* path_manager = | |
137 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
138 if (path_manager == nullptr) { | |
139 OnUnrecoverablePathError(kDefaultPathId); | |
140 QuicFrames retransmittable_frames; | |
141 return PendingRetransmission(kInvalidPathId, 0u, NOT_RETRANSMISSION, | |
142 retransmittable_frames, false, 0, | |
143 ENCRYPTION_NONE, PACKET_1BYTE_PACKET_NUMBER); | |
144 } | |
145 return path_manager->NextPendingRetransmission(); | |
146 } | |
147 | |
148 bool QuicMultipathSentPacketManager::HasUnackedPackets() const { | |
149 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
150 if (path_manager_info.manager != nullptr && | |
151 path_manager_info.state == ACTIVE && | |
152 path_manager_info.manager->HasUnackedPackets()) { | |
153 return true; | |
154 } | |
155 } | |
156 return false; | |
157 } | |
158 | |
159 QuicPacketNumber QuicMultipathSentPacketManager::GetLeastUnacked( | |
160 QuicPathId path_id) const { | |
161 QuicSentPacketManagerInterface* path_manager = | |
162 MaybeGetSentPacketManagerForPath(path_id); | |
163 if (path_manager == nullptr) { | |
164 return 0; | |
165 } | |
166 return path_manager->GetLeastUnacked(path_id); | |
167 } | |
168 | |
169 bool QuicMultipathSentPacketManager::OnPacketSent( | |
170 SerializedPacket* serialized_packet, | |
171 QuicPathId original_path_id, | |
172 QuicPacketNumber original_packet_number, | |
173 QuicTime sent_time, | |
174 TransmissionType transmission_type, | |
175 HasRetransmittableData has_retransmittable_data) { | |
176 QuicSentPacketManagerInterface* path_manager = | |
177 MaybeGetSentPacketManagerForActivePath(serialized_packet->path_id); | |
178 // TODO(fayang): Handle packets retransmitted on different path. | |
179 DCHECK(original_packet_number == 0 || | |
180 original_path_id == serialized_packet->path_id); | |
181 if (path_manager == nullptr) { | |
182 OnUnrecoverablePathError(serialized_packet->path_id); | |
183 return false; | |
184 } | |
185 | |
186 return path_manager->OnPacketSent( | |
187 serialized_packet, original_path_id, original_packet_number, sent_time, | |
188 transmission_type, has_retransmittable_data); | |
189 } | |
190 | |
191 void QuicMultipathSentPacketManager::OnRetransmissionTimeout() { | |
192 QuicPathId rto_path = DetermineRetransmissionTimeoutPath(); | |
193 DCHECK_NE(kInvalidPathId, rto_path); | |
194 QuicSentPacketManagerInterface* path_manager = | |
195 MaybeGetSentPacketManagerForActivePath(rto_path); | |
196 if (path_manager == nullptr) { | |
197 OnUnrecoverablePathError(rto_path); | |
198 return; | |
199 } | |
200 path_manager->OnRetransmissionTimeout(); | |
201 } | |
202 | |
203 QuicTime::Delta QuicMultipathSentPacketManager::TimeUntilSend( | |
204 QuicTime now, | |
205 HasRetransmittableData retransmittable, | |
206 QuicPathId* path_id) { | |
207 QuicTime::Delta delay = QuicTime::Delta::Infinite(); | |
208 *path_id = kInvalidPathId; | |
209 for (size_t i = 0; i < path_managers_info_.size(); ++i) { | |
210 if (path_managers_info_[i].manager == nullptr || | |
211 path_managers_info_[i].state != ACTIVE) { | |
212 continue; | |
213 } | |
214 | |
215 QuicTime::Delta path_delay = path_managers_info_[i].manager->TimeUntilSend( | |
216 now, retransmittable, path_id); | |
217 if (!path_delay.IsInfinite() && path_delay < delay) { | |
218 delay = path_delay; | |
219 *path_id = i; | |
220 } | |
221 } | |
222 DCHECK(*path_id == kInvalidPathId || !delay.IsInfinite()); | |
223 return delay; | |
224 } | |
225 | |
226 const QuicTime QuicMultipathSentPacketManager::GetRetransmissionTime() const { | |
227 QuicTime retransmission_time = QuicTime::Zero(); | |
228 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
229 if (path_manager_info.manager == nullptr || | |
230 path_manager_info.state != ACTIVE) { | |
231 continue; | |
232 } | |
233 QuicTime path_retransmission_time = | |
234 path_manager_info.manager->GetRetransmissionTime(); | |
235 if (!path_retransmission_time.IsInitialized()) { | |
236 continue; | |
237 } | |
238 if (!retransmission_time.IsInitialized() || | |
239 path_retransmission_time < retransmission_time) { | |
240 retransmission_time = path_retransmission_time; | |
241 } | |
242 } | |
243 | |
244 return retransmission_time; | |
245 } | |
246 | |
247 const RttStats* QuicMultipathSentPacketManager::GetRttStats() const { | |
248 QuicSentPacketManagerInterface* path_manager = | |
249 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
250 if (path_manager == nullptr) { | |
251 return nullptr; | |
252 } | |
253 return path_manager->GetRttStats(); | |
254 } | |
255 | |
256 QuicBandwidth QuicMultipathSentPacketManager::BandwidthEstimate() const { | |
257 QuicSentPacketManagerInterface* path_manager = | |
258 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
259 if (path_manager == nullptr) { | |
260 return QuicBandwidth::Zero(); | |
261 } | |
262 return path_manager->BandwidthEstimate(); | |
263 } | |
264 | |
265 const QuicSustainedBandwidthRecorder* | |
266 QuicMultipathSentPacketManager::SustainedBandwidthRecorder() const { | |
267 QuicSentPacketManagerInterface* path_manager = | |
268 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
269 if (path_manager == nullptr) { | |
270 return nullptr; | |
271 } | |
272 return path_manager->SustainedBandwidthRecorder(); | |
273 } | |
274 | |
275 QuicPacketCount QuicMultipathSentPacketManager::GetCongestionWindowInTcpMss() | |
276 const { | |
277 QuicSentPacketManagerInterface* path_manager = | |
278 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
279 if (path_manager == nullptr) { | |
280 return 0; | |
281 } | |
282 return path_manager->GetCongestionWindowInTcpMss(); | |
283 } | |
284 | |
285 QuicPacketCount QuicMultipathSentPacketManager::EstimateMaxPacketsInFlight( | |
286 QuicByteCount max_packet_length) const { | |
287 QuicPacketCount max_packets_in_flight = 0; | |
288 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
289 if (path_manager_info.manager != nullptr) { | |
290 max_packets_in_flight = | |
291 max(max_packets_in_flight, | |
292 path_manager_info.manager->EstimateMaxPacketsInFlight( | |
293 max_packet_length)); | |
294 } | |
295 } | |
296 DCHECK_LT(0u, max_packets_in_flight); | |
297 return max_packets_in_flight; | |
298 } | |
299 | |
300 QuicByteCount QuicMultipathSentPacketManager::GetCongestionWindowInBytes() | |
301 const { | |
302 QuicSentPacketManagerInterface* path_manager = | |
303 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
304 if (path_manager == nullptr) { | |
305 return 0; | |
306 } | |
307 return path_manager->GetCongestionWindowInBytes(); | |
308 } | |
309 | |
310 QuicPacketCount QuicMultipathSentPacketManager::GetSlowStartThresholdInTcpMss() | |
311 const { | |
312 QuicSentPacketManagerInterface* path_manager = | |
313 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
314 if (path_manager == nullptr) { | |
315 return 0; | |
316 } | |
317 return path_manager->GetSlowStartThresholdInTcpMss(); | |
318 } | |
319 | |
320 void QuicMultipathSentPacketManager::CancelRetransmissionsForStream( | |
321 QuicStreamId stream_id) { | |
322 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
323 if (path_manager_info.manager != nullptr) { | |
324 path_manager_info.manager->CancelRetransmissionsForStream(stream_id); | |
325 } | |
326 } | |
327 } | |
328 | |
329 void QuicMultipathSentPacketManager::OnConnectionMigration( | |
330 QuicPathId path_id, | |
331 PeerAddressChangeType type) { | |
332 QuicSentPacketManagerInterface* path_manager = | |
333 MaybeGetSentPacketManagerForActivePath(path_id); | |
334 if (path_manager == nullptr) { | |
335 OnUnrecoverablePathError(path_id); | |
336 return; | |
337 } | |
338 path_manager->OnConnectionMigration(path_id, type); | |
339 } | |
340 | |
341 bool QuicMultipathSentPacketManager::IsHandshakeConfirmed() const { | |
342 QuicSentPacketManagerInterface* path_manager = | |
343 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
344 return path_manager != nullptr && path_manager->IsHandshakeConfirmed(); | |
345 } | |
346 | |
347 void QuicMultipathSentPacketManager::SetDebugDelegate( | |
348 DebugDelegate* debug_delegate) { | |
349 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
350 if (path_manager_info.manager == nullptr) { | |
351 continue; | |
352 } | |
353 path_manager_info.manager->SetDebugDelegate(debug_delegate); | |
354 } | |
355 } | |
356 | |
357 QuicPacketNumber QuicMultipathSentPacketManager::GetLargestObserved( | |
358 QuicPathId path_id) const { | |
359 QuicSentPacketManagerInterface* path_manager = | |
360 MaybeGetSentPacketManagerForPath(path_id); | |
361 if (path_manager == nullptr) { | |
362 return 0; | |
363 } | |
364 return path_manager->GetLargestObserved(path_id); | |
365 } | |
366 | |
367 QuicPacketNumber QuicMultipathSentPacketManager::GetLargestSentPacket( | |
368 QuicPathId path_id) const { | |
369 QuicSentPacketManagerInterface* path_manager = | |
370 MaybeGetSentPacketManagerForPath(path_id); | |
371 if (path_manager == nullptr) { | |
372 return 0; | |
373 } | |
374 return path_manager->GetLargestSentPacket(path_id); | |
375 } | |
376 | |
377 QuicPacketNumber QuicMultipathSentPacketManager::GetLeastPacketAwaitedByPeer( | |
378 QuicPathId path_id) const { | |
379 QuicSentPacketManagerInterface* path_manager = | |
380 MaybeGetSentPacketManagerForPath(path_id); | |
381 if (path_manager == nullptr) { | |
382 return 0; | |
383 } | |
384 return path_manager->GetLeastPacketAwaitedByPeer(path_id); | |
385 } | |
386 | |
387 void QuicMultipathSentPacketManager::SetNetworkChangeVisitor( | |
388 NetworkChangeVisitor* visitor) { | |
389 for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { | |
390 if (path_manager_info.manager == nullptr || | |
391 path_manager_info.state != ACTIVE) { | |
392 continue; | |
393 } | |
394 path_manager_info.manager->SetNetworkChangeVisitor(visitor); | |
395 } | |
396 } | |
397 | |
398 bool QuicMultipathSentPacketManager::InSlowStart() const { | |
399 QuicSentPacketManagerInterface* path_manager = | |
400 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
401 return path_manager != nullptr && path_manager->InSlowStart(); | |
402 } | |
403 | |
404 size_t QuicMultipathSentPacketManager::GetConsecutiveRtoCount() const { | |
405 QuicSentPacketManagerInterface* path_manager = | |
406 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
407 if (path_manager == nullptr) { | |
408 return 0; | |
409 } | |
410 return path_manager->GetConsecutiveRtoCount(); | |
411 } | |
412 size_t QuicMultipathSentPacketManager::GetConsecutiveTlpCount() const { | |
413 QuicSentPacketManagerInterface* path_manager = | |
414 MaybeGetSentPacketManagerForActivePath(kDefaultPathId); | |
415 if (path_manager == nullptr) { | |
416 return 0; | |
417 } | |
418 return path_manager->GetConsecutiveTlpCount(); | |
419 } | |
420 | |
421 QuicMultipathSentPacketManager::PathSentPacketManagerInfo:: | |
422 PathSentPacketManagerInfo() | |
423 : manager(nullptr), state(CLOSING) {} | |
424 | |
425 QuicMultipathSentPacketManager::PathSentPacketManagerInfo:: | |
426 PathSentPacketManagerInfo(QuicSentPacketManagerInterface* manager, | |
427 PathSentPacketManagerState state) | |
428 : manager(manager), state(state) {} | |
429 | |
430 QuicMultipathSentPacketManager::PathSentPacketManagerInfo:: | |
431 PathSentPacketManagerInfo(const PathSentPacketManagerInfo& other) = default; | |
432 | |
433 QuicSentPacketManagerInterface* | |
434 QuicMultipathSentPacketManager::MaybeGetSentPacketManagerForPath( | |
435 QuicPathId path_id) const { | |
436 if (path_id >= path_managers_info_.size() || | |
437 path_managers_info_[path_id].manager == nullptr) { | |
438 QUIC_BUG << "Sent packet manager of path: (" + base::IntToString(path_id) + | |
439 ") must exist but does not."; | |
440 return nullptr; | |
441 } | |
442 | |
443 return path_managers_info_[path_id].manager; | |
444 } | |
445 | |
446 QuicSentPacketManagerInterface* | |
447 QuicMultipathSentPacketManager::MaybeGetSentPacketManagerForActivePath( | |
448 QuicPathId path_id) const { | |
449 QuicSentPacketManagerInterface* path_manager = | |
450 MaybeGetSentPacketManagerForPath(path_id); | |
451 if (path_manager == nullptr) { | |
452 return nullptr; | |
453 } | |
454 if (path_managers_info_[path_id].state != ACTIVE) { | |
455 QUIC_BUG << "Sent packet manager of path: (" + base::IntToString(path_id) + | |
456 ") must be active but is not."; | |
457 return nullptr; | |
458 } | |
459 | |
460 return path_manager; | |
461 } | |
462 | |
463 QuicPathId QuicMultipathSentPacketManager::DetermineRetransmissionTimeoutPath() | |
464 const { | |
465 QuicTime retransmission_time = QuicTime::Zero(); | |
466 QuicPathId rto_path = kInvalidPathId; | |
467 for (size_t i = 0; i < path_managers_info_.size(); ++i) { | |
468 if (path_managers_info_[i].manager == nullptr || | |
469 path_managers_info_[i].state != ACTIVE) { | |
470 continue; | |
471 } | |
472 QuicTime path_retransmission_time = | |
473 path_managers_info_[i].manager->GetRetransmissionTime(); | |
474 if (!path_retransmission_time.IsInitialized()) { | |
475 continue; | |
476 } | |
477 if (!retransmission_time.IsInitialized() || | |
478 path_retransmission_time < retransmission_time) { | |
479 retransmission_time = path_retransmission_time; | |
480 rto_path = i; | |
481 } | |
482 } | |
483 return rto_path; | |
484 } | |
485 | |
486 void QuicMultipathSentPacketManager::OnUnrecoverablePathError( | |
487 QuicPathId path_id) { | |
488 if (MaybeGetSentPacketManagerForPath(path_id) == nullptr) { | |
489 const string error_details = "Sent packet manager of path: (" + | |
490 base::IntToString(path_id) + | |
491 ") must exist but does not."; | |
492 delegate_->OnUnrecoverableError(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST, | |
493 error_details, | |
494 ConnectionCloseSource::FROM_SELF); | |
495 return; | |
496 } | |
497 const string error_details = "Sent packet manager of path: (" + | |
498 base::IntToString(path_id) + | |
499 ") must be active but is not."; | |
500 delegate_->OnUnrecoverableError(QUIC_MULTIPATH_PATH_NOT_ACTIVE, error_details, | |
501 ConnectionCloseSource::FROM_SELF); | |
502 } | |
503 | |
504 } // namespace net | |
OLD | NEW |