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