Act on IETF QUIC max_packet_size After we receive the IETF QUIC max_packet_size transport parameter, we should not send packets larger than that value. This CL enforces this. gfe-relnote: act on IETF QUIC max_packet_size, protected by disabled TLS versions PiperOrigin-RevId: 290114223 Change-Id: I8ac886b49ae7a6099a393dbd7af1e0f765181241
diff --git a/quic/core/crypto/transport_parameters.cc b/quic/core/crypto/transport_parameters.cc index 7e1cf44..a7df751 100644 --- a/quic/core/crypto/transport_parameters.cc +++ b/quic/core/crypto/transport_parameters.cc
@@ -58,7 +58,6 @@ // the parameters. These come from the "Transport Parameter Definitions" // section of draft-ietf-quic-transport. const uint64_t kMinMaxPacketSizeTransportParam = 1200; -const uint64_t kDefaultMaxPacketSizeTransportParam = 65527; const uint64_t kMaxAckDelayExponentTransportParam = 20; const uint64_t kDefaultAckDelayExponentTransportParam = 3; const uint64_t kMaxMaxAckDelayTransportParam = 16383;
diff --git a/quic/core/quic_config.cc b/quic/core/quic_config.cc index 86b4a97..d0087c4 100644 --- a/quic/core/quic_config.cc +++ b/quic/core/quic_config.cc
@@ -1046,11 +1046,6 @@ if (params.max_packet_size.IsValid()) { max_packet_size_.SetReceivedValue(params.max_packet_size.value()); - if (ReceivedMaxPacketSize() < kMaxOutgoingPacketSize) { - // TODO(dschinazi) act on this. - QUIC_DLOG(ERROR) << "Ignoring peer's requested max packet size of " - << ReceivedMaxPacketSize(); - } } if (params.max_datagram_frame_size.IsValid()) {
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index 4df2699..a29825b 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -311,6 +311,7 @@ connected_(true), can_truncate_connection_ids_(perspective == Perspective::IS_SERVER), mtu_probe_count_(0), + peer_max_packet_size_(kDefaultMaxPacketSizeTransportParam), largest_received_packet_size_(0), write_error_occurred_(false), no_stop_waiting_frames_( @@ -469,6 +470,11 @@ framer_.set_process_timestamps(true); uber_received_packet_manager_.set_save_timestamps(true); } + if (config.HasReceivedMaxPacketSize()) { + peer_max_packet_size_ = config.ReceivedMaxPacketSize(); + packet_creator_.SetMaxPacketLength( + GetLimitedMaxPacketSize(peer_max_packet_size_)); + } supports_release_time_ = writer_ != nullptr && writer_->SupportsReleaseTime() && @@ -3345,6 +3351,9 @@ if (max_packet_size > writer_limit) { max_packet_size = writer_limit; } + if (max_packet_size > peer_max_packet_size_) { + max_packet_size = peer_max_packet_size_; + } if (max_packet_size > kMaxOutgoingPacketSize) { max_packet_size = kMaxOutgoingPacketSize; }
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h index 9c5810a..0374cc7 100644 --- a/quic/core/quic_connection.h +++ b/quic/core/quic_connection.h
@@ -1401,6 +1401,10 @@ // different. QuicByteCount long_term_mtu_; + // The maximum UDP payload size that our peer has advertised support for. + // Defaults to kDefaultMaxPacketSizeTransportParam until received from peer. + QuicByteCount peer_max_packet_size_; + // The size of the largest packet received from peer. QuicByteCount largest_received_packet_size_;
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index 8d25157..0817d57 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -2383,6 +2383,19 @@ EXPECT_EQ(1350u, connection_.max_packet_length()); } +TEST_P(QuicConnectionTest, PeerLowersMaxPacketSize) { + EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective()); + + // SetFromConfig is always called after construction from InitializeSession. + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + constexpr uint32_t kTestMaxPacketSize = 1233u; + QuicConfig config; + QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize); + connection_.SetFromConfig(config); + + EXPECT_EQ(kTestMaxPacketSize, connection_.max_packet_length()); +} + TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) { TestConnection connection(TestConnectionId(), kPeerAddress, helper_.get(), alarm_factory_.get(), writer_.get(),
diff --git a/quic/core/quic_constants.h b/quic/core/quic_constants.h index aad6d3a..c4a83b3 100644 --- a/quic/core/quic_constants.h +++ b/quic/core/quic_constants.h
@@ -50,6 +50,9 @@ // The maximal IETF DATAGRAM frame size we'll accept. Choosing 2^16 ensures // that it is greater than the biggest frame we could ever fit in a QUIC packet. const QuicByteCount kMaxAcceptedDatagramFrameSize = 65536; +// Default value of the max_packet_size transport parameter if it is not +// transmitted. +const QuicByteCount kDefaultMaxPacketSizeTransportParam = 65527; // Default maximum packet size used in the Linux TCP implementation. // Used in QUIC for congestion window computations in bytes. const QuicByteCount kDefaultTCPMSS = 1460;
diff --git a/quic/test_tools/quic_config_peer.cc b/quic/test_tools/quic_config_peer.cc index 481a148..41527c2 100644 --- a/quic/test_tools/quic_config_peer.cc +++ b/quic/test_tools/quic_config_peer.cc
@@ -91,5 +91,11 @@ config->stateless_reset_token_.SetReceivedValue(token); } +// static +void QuicConfigPeer::SetReceivedMaxPacketSize(QuicConfig* config, + uint32_t max_packet_size) { + config->max_packet_size_.SetReceivedValue(max_packet_size); +} + } // namespace test } // namespace quic
diff --git a/quic/test_tools/quic_config_peer.h b/quic/test_tools/quic_config_peer.h index f9d3b1e..61e2ef2 100644 --- a/quic/test_tools/quic_config_peer.h +++ b/quic/test_tools/quic_config_peer.h
@@ -55,6 +55,9 @@ static void SetReceivedStatelessResetToken(QuicConfig* config, QuicUint128 token); + + static void SetReceivedMaxPacketSize(QuicConfig* config, + uint32_t max_packet_size); }; } // namespace test