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