Enforce limits on sending ECN. QuicConnection only permits ECN via a state variable accessible only by QuicConnectionPeer. The send limits will be relaxed as new code meets the requirements. There is no code that allows sending anything other than NOT_ECT, so this is not flag-protected. PiperOrigin-RevId: 523154100
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc index 27cf706..f0fa10b 100644 --- a/quiche/quic/core/quic_connection_test.cc +++ b/quiche/quic/core/quic_connection_test.cc
@@ -17465,6 +17465,57 @@ EXPECT_EQ(kSelfAddress, connection_.self_address()); } +TEST_P(QuicConnectionTest, EcnCodepointsRejected) { + TestPerPacketOptions per_packet_options; + connection_.set_per_packet_options(&per_packet_options); + for (QuicEcnCodepoint ecn : {ECN_NOT_ECT, ECN_ECT0, ECN_ECT1, ECN_CE}) { + per_packet_options.ecn_codepoint = ecn; + if (ecn == ECN_ECT0) { + EXPECT_CALL(*send_algorithm_, SupportsECT0()).WillOnce(Return(false)); + } else if (ecn == ECN_ECT1) { + EXPECT_CALL(*send_algorithm_, SupportsECT1()).WillOnce(Return(false)); + } + EXPECT_CALL(connection_, OnSerializedPacket(_)); + SendPing(); + EXPECT_EQ(per_packet_options.ecn_codepoint, ECN_NOT_ECT); + EXPECT_EQ(writer_->last_ecn_sent(), ECN_NOT_ECT); + } +} + +TEST_P(QuicConnectionTest, EcnCodepointsAccepted) { + TestPerPacketOptions per_packet_options; + connection_.set_per_packet_options(&per_packet_options); + for (QuicEcnCodepoint ecn : {ECN_NOT_ECT, ECN_ECT0, ECN_ECT1, ECN_CE}) { + per_packet_options.ecn_codepoint = ecn; + if (ecn == ECN_ECT0) { + EXPECT_CALL(*send_algorithm_, SupportsECT0()).WillOnce(Return(true)); + } else if (ecn == ECN_ECT1) { + EXPECT_CALL(*send_algorithm_, SupportsECT1()).WillOnce(Return(true)); + } + EXPECT_CALL(connection_, OnSerializedPacket(_)); + SendPing(); + QuicEcnCodepoint expected_codepoint = ecn; + if (ecn == ECN_CE) { + expected_codepoint = ECN_NOT_ECT; + } + EXPECT_EQ(per_packet_options.ecn_codepoint, expected_codepoint); + EXPECT_EQ(writer_->last_ecn_sent(), expected_codepoint); + } +} + +TEST_P(QuicConnectionTest, EcnValidationDisabled) { + TestPerPacketOptions per_packet_options; + connection_.set_per_packet_options(&per_packet_options); + QuicConnectionPeer::DisableEcnCodepointValidation(&connection_); + for (QuicEcnCodepoint ecn : {ECN_NOT_ECT, ECN_ECT0, ECN_ECT1, ECN_CE}) { + per_packet_options.ecn_codepoint = ecn; + EXPECT_CALL(connection_, OnSerializedPacket(_)); + SendPing(); + EXPECT_EQ(per_packet_options.ecn_codepoint, ecn); + EXPECT_EQ(writer_->last_ecn_sent(), ecn); + } +} + } // namespace } // namespace test } // namespace quic