Index: net/quic/quic_connection.cc |
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc |
index 1bfc6ff5211c823369c8120d1d0449a75196f889..a8763794fe9c755f62ad43559ca73a52017edad3 100644 |
--- a/net/quic/quic_connection.cc |
+++ b/net/quic/quic_connection.cc |
@@ -207,7 +207,7 @@ class MtuDiscoveryAckListener : public QuicAckNotifier::DelegateInterface { |
QuicTime::Delta /*delta_largest_observed*/) override { |
// Since the probe was successful, increase the maximum packet size to that. |
if (probe_size_ > connection_->max_packet_length()) { |
- connection_->set_max_packet_length(probe_size_); |
+ connection_->SetMaxPacketLength(probe_size_); |
} |
} |
@@ -327,9 +327,11 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id, |
framer_.set_received_entropy_calculator(&received_packet_manager_); |
stats_.connection_creation_time = clock_->ApproximateNow(); |
sent_packet_manager_.set_network_change_visitor(this); |
- if (perspective_ == Perspective::IS_SERVER) { |
- set_max_packet_length(kDefaultServerMaxPacketSize); |
- } |
+ // Allow the packet writer to potentially reduce the packet size to a value |
+ // even smaller than kDefaultMaxPacketSize. |
+ SetMaxPacketLength(perspective_ == Perspective::IS_SERVER |
+ ? kDefaultServerMaxPacketSize |
+ : kDefaultMaxPacketSize); |
} |
QuicConnection::~QuicConnection() { |
@@ -381,10 +383,10 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) { |
} |
if (config.HasClientSentConnectionOption(kMTUH, perspective_)) { |
- mtu_discovery_target_ = kMtuDiscoveryTargetPacketSizeHigh; |
+ SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh); |
} |
if (config.HasClientSentConnectionOption(kMTUL, perspective_)) { |
- mtu_discovery_target_ = kMtuDiscoveryTargetPacketSizeLow; |
+ SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow); |
} |
} |
@@ -1417,6 +1419,14 @@ void QuicConnection::CheckForAddressMigration( |
self_ip_changed_ = (self_address.address() != self_address_.address()); |
self_port_changed_ = (self_address.port() != self_address_.port()); |
} |
+ |
+ // TODO(vasilvv): reset maximum packet size on connection migration. Whenever |
+ // the connection is migrated, it usually ends up being on a different path, |
+ // with possibly smaller MTU. This means the max packet size has to be reset |
+ // and MTU discovery mechanism re-initialized. The main reason the code does |
+ // not do it now is that the retransmission code currently cannot deal with |
+ // the case when it needs to resend a packet created with larger MTU (see |
+ // b/22172803). |
} |
void QuicConnection::OnCanWrite() { |
@@ -1491,7 +1501,7 @@ bool QuicConnection::ProcessValidatedPacket() { |
if (perspective_ == Perspective::IS_SERVER && |
encryption_level_ == ENCRYPTION_NONE && |
last_size_ > packet_generator_.GetMaxPacketLength()) { |
- set_max_packet_length(last_size_); |
+ SetMaxPacketLength(last_size_); |
} |
return true; |
} |
@@ -2143,8 +2153,9 @@ QuicByteCount QuicConnection::max_packet_length() const { |
return packet_generator_.GetMaxPacketLength(); |
} |
-void QuicConnection::set_max_packet_length(QuicByteCount length) { |
- return packet_generator_.SetMaxPacketLength(length, /*force=*/false); |
+void QuicConnection::SetMaxPacketLength(QuicByteCount length) { |
+ return packet_generator_.SetMaxPacketLength(LimitMaxPacketSize(length), |
+ /*force=*/false); |
} |
bool QuicConnection::HasQueuedData() const { |
@@ -2374,7 +2385,41 @@ bool QuicConnection::IsConnectionClose(const QueuedPacket& packet) { |
return false; |
} |
+void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) { |
+ mtu_discovery_target_ = LimitMaxPacketSize(target); |
+} |
+ |
+QuicByteCount QuicConnection::LimitMaxPacketSize( |
+ QuicByteCount suggested_max_packet_size) { |
+ if (FLAGS_quic_allow_oversized_packets_for_test) { |
+ return suggested_max_packet_size; |
+ } |
+ |
+ if (!FLAGS_quic_limit_mtu_by_writer) { |
+ return suggested_max_packet_size; |
+ } |
+ |
+ if (peer_address_.address().empty()) { |
+ LOG(DFATAL) << "Attempted to use a connection without a valid peer address"; |
+ return suggested_max_packet_size; |
+ } |
+ |
+ const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address()); |
+ |
+ QuicByteCount max_packet_size = suggested_max_packet_size; |
+ if (max_packet_size > writer_limit) { |
+ max_packet_size = writer_limit; |
+ } |
+ if (max_packet_size > kMaxPacketSize) { |
+ max_packet_size = kMaxPacketSize; |
+ } |
+ return max_packet_size; |
+} |
+ |
void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) { |
+ // Currently, this limit is ensured by the caller. |
+ DCHECK_EQ(target_mtu, LimitMaxPacketSize(target_mtu)); |
+ |
// Create a listener for the new probe. The ownership of the listener is |
// transferred to the AckNotifierManager. The notifier will get destroyed |
// before the connection (because it's stored in one of the connection's |