Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Unified Diff: net/quic/quic_multipath_sent_packet_manager.cc

Issue 2183493002: Add a merely pass-through QuicMultipathSentPacketManager. Protected behind blocked flag FLAGS_quic_… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/quic/quic_multipath_sent_packet_manager.cc
diff --git a/net/quic/quic_multipath_sent_packet_manager.cc b/net/quic/quic_multipath_sent_packet_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0e5e296d80592abdb99831846a50de1972ee35e6
--- /dev/null
+++ b/net/quic/quic_multipath_sent_packet_manager.cc
@@ -0,0 +1,520 @@
+#include "net/quic/quic_multipath_sent_packet_manager.h"
Zhongyi Shi 2016/07/25 22:30:34 ditto
+
+#include <cstdint>
+
+#include "base/strings/string_number_conversions.h"
+#include "net/quic/quic_bug_tracker.h"
+
+using std::string;
+using std::max;
+
+namespace net {
+
+QuicMultipathSentPacketManager::QuicMultipathSentPacketManager(
+ QuicSentPacketManagerInterface* manager,
+ QuicConnectionCloseDelegateInterface* delegate)
+ : delegate_(delegate) {
+ path_managers_info_.push_back(PathSentPacketManagerInfo(manager, ACTIVE));
+}
+
+QuicMultipathSentPacketManager::~QuicMultipathSentPacketManager() {
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ delete path_manager_info.manager;
+ }
+}
+
+void QuicMultipathSentPacketManager::SetFromConfig(const QuicConfig& config) {
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager != nullptr) {
+ path_manager_info.manager->SetFromConfig(config);
+ }
+ }
+}
+
+void QuicMultipathSentPacketManager::ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params,
+ bool max_bandwidth_resumption) {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(kDefaultPathId);
+ return;
+ }
+ path_manager->ResumeConnectionState(cached_network_params,
+ max_bandwidth_resumption);
+}
+
+void QuicMultipathSentPacketManager::SetNumOpenStreams(size_t num_streams) {
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager != nullptr) {
+ path_manager_info.manager->SetNumOpenStreams(num_streams);
+ }
+ }
+}
+
+void QuicMultipathSentPacketManager::SetMaxPacingRate(
+ QuicBandwidth max_pacing_rate) {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(kDefaultPathId);
+ return;
+ }
+ path_manager->SetMaxPacingRate(max_pacing_rate);
+}
+
+void QuicMultipathSentPacketManager::SetHandshakeConfirmed() {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(kDefaultPathId);
+ return;
+ }
+ path_manager->SetHandshakeConfirmed();
+}
+
+void QuicMultipathSentPacketManager::OnIncomingAck(
+ const QuicAckFrame& ack_frame,
+ QuicTime ack_receive_time) {
+ if (ack_frame.path_id >= path_managers_info_.size() ||
+ path_managers_info_[ack_frame.path_id].state != ACTIVE) {
+ return;
+ }
+ path_managers_info_[ack_frame.path_id].manager->OnIncomingAck(
+ ack_frame, ack_receive_time);
+}
+
+bool QuicMultipathSentPacketManager::IsUnacked(
+ QuicPathId path_id,
+ QuicPacketNumber packet_number) const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForPath(path_id);
+ return path_manager != nullptr &&
+ path_manager->IsUnacked(path_id, packet_number);
+}
+
+bool QuicMultipathSentPacketManager::HasRetransmittableFrames(
+ QuicPathId path_id,
+ QuicPacketNumber packet_number) const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForPath(path_id);
+ return path_manager != nullptr &&
+ path_manager->HasRetransmittableFrames(path_id, packet_number);
+}
+
+void QuicMultipathSentPacketManager::RetransmitUnackedPackets(
+ TransmissionType retransmission_type) {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(kDefaultPathId);
+ return;
+ }
+ path_manager->RetransmitUnackedPackets(retransmission_type);
+}
+
+bool QuicMultipathSentPacketManager::MaybeRetransmitTailLossProbe() {
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager != nullptr &&
+ path_manager_info.state == ACTIVE) {
+ if (path_manager_info.manager->MaybeRetransmitTailLossProbe()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void QuicMultipathSentPacketManager::NeuterUnencryptedPackets() {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(kDefaultPathId);
+ return;
+ }
+ path_manager->NeuterUnencryptedPackets();
+}
+
+bool QuicMultipathSentPacketManager::HasPendingRetransmissions() const {
+ // TODO(fayang): Move pending_retransmissions_ from path sent packet manager
+ // to multipath sent packet manager.
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ return path_manager != nullptr && path_manager->HasPendingRetransmissions();
+}
+
+PendingRetransmission
+QuicMultipathSentPacketManager::NextPendingRetransmission() {
+ // TODO(fayang): Move pending_retransmissions_ from path sent packet manager
+ // to multipath sent packet manager.
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(kDefaultPathId);
+ QuicFrames retransmittable_frames;
+ return PendingRetransmission(kInvalidPathId, 0u, NOT_RETRANSMISSION,
+ retransmittable_frames, false, 0,
+ ENCRYPTION_NONE, PACKET_1BYTE_PACKET_NUMBER);
+ }
+ return path_manager->NextPendingRetransmission();
+}
+
+bool QuicMultipathSentPacketManager::HasUnackedPackets() const {
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager != nullptr &&
+ path_manager_info.state == ACTIVE &&
+ path_manager_info.manager->HasUnackedPackets()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+QuicPacketNumber QuicMultipathSentPacketManager::GetLeastUnacked(
+ QuicPathId path_id) const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForPath(path_id);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetLeastUnacked(path_id);
+}
+
+bool QuicMultipathSentPacketManager::OnPacketSent(
+ SerializedPacket* serialized_packet,
+ QuicPathId original_path_id,
+ QuicPacketNumber original_packet_number,
+ QuicTime sent_time,
+ TransmissionType transmission_type,
+ HasRetransmittableData has_retransmittable_data) {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(serialized_packet->path_id);
+ // TODO(fayang): Handle packets retransmitted on different path.
+ DCHECK(original_packet_number == 0 ||
+ original_path_id == serialized_packet->path_id);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(serialized_packet->path_id);
+ return false;
+ }
+
+ return path_manager->OnPacketSent(
+ serialized_packet, original_path_id, original_packet_number, sent_time,
+ transmission_type, has_retransmittable_data);
+}
+
+void QuicMultipathSentPacketManager::OnRetransmissionTimeout() {
+ QuicPathId rto_path = DetermineRetransmissionTimeoutPath();
+ DCHECK_NE(kInvalidPathId, rto_path);
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(rto_path);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(rto_path);
+ return;
+ }
+ path_manager->OnRetransmissionTimeout();
+}
+
+QuicTime::Delta QuicMultipathSentPacketManager::TimeUntilSend(
+ QuicTime now,
+ HasRetransmittableData retransmittable,
+ QuicPathId* path_id) {
+ QuicTime::Delta delay = QuicTime::Delta::Infinite();
+ *path_id = kInvalidPathId;
+ for (size_t i = 0; i < path_managers_info_.size(); ++i) {
+ if (path_managers_info_[i].manager == nullptr ||
+ path_managers_info_[i].state != ACTIVE) {
+ continue;
+ }
+
+ QuicTime::Delta path_delay = path_managers_info_[i].manager->TimeUntilSend(
+ now, retransmittable, path_id);
+ if (!path_delay.IsInfinite() && path_delay < delay) {
+ delay = path_delay;
+ *path_id = i;
+ }
+ }
+ DCHECK(*path_id == kInvalidPathId || !delay.IsInfinite());
+ return delay;
+}
+
+const QuicTime QuicMultipathSentPacketManager::GetRetransmissionTime() const {
+ QuicTime retransmission_time = QuicTime::Zero();
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager == nullptr ||
+ path_manager_info.state != ACTIVE) {
+ continue;
+ }
+ QuicTime path_retransmission_time =
+ path_manager_info.manager->GetRetransmissionTime();
+ if (!path_retransmission_time.IsInitialized()) {
+ continue;
+ }
+ if (!retransmission_time.IsInitialized() ||
+ path_retransmission_time < retransmission_time) {
+ retransmission_time = path_retransmission_time;
+ }
+ }
+
+ return retransmission_time;
+}
+
+const RttStats* QuicMultipathSentPacketManager::GetRttStats() const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ return nullptr;
+ }
+ return path_manager->GetRttStats();
+}
+
+QuicBandwidth QuicMultipathSentPacketManager::BandwidthEstimate() const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ return QuicBandwidth::Zero();
+ }
+ return path_manager->BandwidthEstimate();
+}
+
+const QuicSustainedBandwidthRecorder*
+QuicMultipathSentPacketManager::SustainedBandwidthRecorder() const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ return nullptr;
+ }
+ return path_manager->SustainedBandwidthRecorder();
+}
+
+QuicPacketCount QuicMultipathSentPacketManager::GetCongestionWindowInTcpMss()
+ const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetCongestionWindowInTcpMss();
+}
+
+QuicPacketCount QuicMultipathSentPacketManager::EstimateMaxPacketsInFlight(
+ QuicByteCount max_packet_length) const {
+ QuicPacketCount max_packets_in_flight = 0;
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager != nullptr) {
+ max_packets_in_flight =
+ max(max_packets_in_flight,
+ path_manager_info.manager->EstimateMaxPacketsInFlight(
+ max_packet_length));
+ }
+ }
+ DCHECK_LT(0u, max_packets_in_flight);
+ return max_packets_in_flight;
+}
+
+QuicByteCount QuicMultipathSentPacketManager::GetCongestionWindowInBytes()
+ const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetCongestionWindowInBytes();
+}
+
+QuicPacketCount QuicMultipathSentPacketManager::GetSlowStartThresholdInTcpMss()
+ const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetSlowStartThresholdInTcpMss();
+}
+
+void QuicMultipathSentPacketManager::CancelRetransmissionsForStream(
+ QuicStreamId stream_id) {
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager != nullptr) {
+ path_manager_info.manager->CancelRetransmissionsForStream(stream_id);
+ }
+ }
+}
+
+void QuicMultipathSentPacketManager::OnConnectionMigration(
+ QuicPathId path_id,
+ PeerAddressChangeType type) {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(path_id);
+ if (path_manager == nullptr) {
+ OnUnrecoverablePathError(path_id);
+ return;
+ }
+ path_manager->OnConnectionMigration(path_id, type);
+}
+
+bool QuicMultipathSentPacketManager::IsHandshakeConfirmed() const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ return path_manager != nullptr && path_manager->IsHandshakeConfirmed();
+}
+
+void QuicMultipathSentPacketManager::SetDebugDelegate(
+ DebugDelegate* debug_delegate) {
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager == nullptr) {
+ continue;
+ }
+ path_manager_info.manager->SetDebugDelegate(debug_delegate);
+ }
+}
+
+QuicPacketNumber QuicMultipathSentPacketManager::GetLargestObserved(
+ QuicPathId path_id) const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForPath(path_id);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetLargestObserved(path_id);
+}
+
+QuicPacketNumber QuicMultipathSentPacketManager::GetLargestSentPacket(
+ QuicPathId path_id) const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForPath(path_id);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetLargestSentPacket(path_id);
+}
+
+QuicPacketNumber QuicMultipathSentPacketManager::GetLeastPacketAwaitedByPeer(
+ QuicPathId path_id) const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForPath(path_id);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetLeastPacketAwaitedByPeer(path_id);
+}
+
+void QuicMultipathSentPacketManager::SetNetworkChangeVisitor(
+ NetworkChangeVisitor* visitor) {
+ for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) {
+ if (path_manager_info.manager == nullptr ||
+ path_manager_info.state != ACTIVE) {
+ continue;
+ }
+ path_manager_info.manager->SetNetworkChangeVisitor(visitor);
+ }
+}
+
+bool QuicMultipathSentPacketManager::InSlowStart() const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ return path_manager != nullptr && path_manager->InSlowStart();
+}
+
+size_t QuicMultipathSentPacketManager::GetConsecutiveRtoCount() const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetConsecutiveRtoCount();
+}
+size_t QuicMultipathSentPacketManager::GetConsecutiveTlpCount() const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForActivePath(kDefaultPathId);
+ if (path_manager == nullptr) {
+ return 0;
+ }
+ return path_manager->GetConsecutiveTlpCount();
+}
+
+QuicMultipathSentPacketManager::PathSentPacketManagerInfo::
+ PathSentPacketManagerInfo()
+ : manager(nullptr), state(CLOSING) {}
+
+QuicMultipathSentPacketManager::PathSentPacketManagerInfo::
+ PathSentPacketManagerInfo(QuicSentPacketManagerInterface* manager,
+ PathSentPacketManagerState state)
+ : manager(manager), state(state) {}
+
+QuicMultipathSentPacketManager::PathSentPacketManagerInfo::
+ PathSentPacketManagerInfo(const PathSentPacketManagerInfo& other) = default;
+
+QuicSentPacketManagerInterface*
+QuicMultipathSentPacketManager::MaybeGetSentPacketManagerForPath(
+ QuicPathId path_id) const {
+ if (path_id >= path_managers_info_.size() ||
+ path_managers_info_[path_id].manager == nullptr) {
+ QUIC_BUG << "Sent packet manager of path: ("
+ << base::IntToString(path_id)
+ << ") must exist but does not.";
+ return nullptr;
+ }
+
+ return path_managers_info_[path_id].manager;
+}
+
+QuicSentPacketManagerInterface*
+QuicMultipathSentPacketManager::MaybeGetSentPacketManagerForActivePath(
+ QuicPathId path_id) const {
+ QuicSentPacketManagerInterface* path_manager =
+ MaybeGetSentPacketManagerForPath(path_id);
+ if (path_manager == nullptr) {
+ return nullptr;
+ }
+ if (path_managers_info_[path_id].state != ACTIVE) {
+ QUIC_BUG << "Sent packet manager of path: ("
+ << base::IntToString(path_id)
+ << ") must be active but is not.";
+ return nullptr;
+ }
+
+ return path_manager;
+}
+
+QuicPathId QuicMultipathSentPacketManager::DetermineRetransmissionTimeoutPath()
+ const {
+ QuicTime retransmission_time = QuicTime::Zero();
+ QuicPathId rto_path = kInvalidPathId;
+ for (size_t i = 0; i < path_managers_info_.size(); ++i) {
+ if (path_managers_info_[i].manager == nullptr ||
+ path_managers_info_[i].state != ACTIVE) {
+ continue;
+ }
+ QuicTime path_retransmission_time =
+ path_managers_info_[i].manager->GetRetransmissionTime();
+ if (!path_retransmission_time.IsInitialized()) {
+ continue;
+ }
+ if (!retransmission_time.IsInitialized() ||
+ path_retransmission_time < retransmission_time) {
+ retransmission_time = path_retransmission_time;
+ rto_path = i;
+ }
+ }
+ return rto_path;
+}
+
+void QuicMultipathSentPacketManager::OnUnrecoverablePathError(
+ QuicPathId path_id) {
+ if (MaybeGetSentPacketManagerForPath(path_id) == nullptr) {
+ const string error_details =
+ "Sent packet manager of path: (" + base::IntToString(path_id) +
+ ") must exist but does not.";
+ delegate_->OnUnrecoverableError(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST,
+ error_details,
+ ConnectionCloseSource::FROM_SELF);
+ return;
+ }
+ const string error_details =
+ "Sent packet manager of path: (" + base::IntToString(path_id) +
+ ") must be active but is not.";
+ delegate_->OnUnrecoverableError(QUIC_MULTIPATH_PATH_NOT_ACTIVE, error_details,
+ ConnectionCloseSource::FROM_SELF);
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698