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