gfe-relnote: In QUIC, add VersionHasIetfInvariantHeader and  VersionSupportsMessageFrames. No functional change expected. Not protected.

PiperOrigin-RevId: 250714233
Change-Id: I9f540d239b84285f83fe5774866ebd345ce09532
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
index 0a0326c..68655c8 100644
--- a/quic/core/http/end_to_end_test.cc
+++ b/quic/core/http/end_to_end_test.cc
@@ -472,9 +472,11 @@
 
   // Client supports IETF QUIC, while it is not supported by server.
   bool ClientSupportsIetfQuicNotSupportedByServer() {
-    return client_supported_versions_[0].transport_version > QUIC_VERSION_43 &&
-           FilterSupportedVersions(GetParam().server_supported_versions)[0]
-                   .transport_version <= QUIC_VERSION_43;
+    return VersionHasIetfInvariantHeader(
+               client_supported_versions_[0].transport_version) &&
+           !VersionHasIetfInvariantHeader(
+               FilterSupportedVersions(GetParam().server_supported_versions)[0]
+                   .transport_version);
   }
 
   // Returns true when client starts with an unsupported version, and client
@@ -485,7 +487,7 @@
   }
 
   bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
-    return version.transport_version > QUIC_VERSION_43 &&
+    return VersionHasIetfInvariantHeader(version.transport_version) &&
            version.handshake_protocol == PROTOCOL_TLS1_3;
   }
 
@@ -1662,7 +1664,8 @@
 }
 
 TEST_P(EndToEndTest, 0ByteConnectionId) {
-  if (GetParam().negotiated_version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(
+          GetParam().negotiated_version.transport_version)) {
     // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
     ASSERT_TRUE(Initialize());
     return;
@@ -1684,7 +1687,8 @@
 }
 
 TEST_P(EndToEndTestWithTls, 8ByteConnectionId) {
-  if (GetParam().negotiated_version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(
+          GetParam().negotiated_version.transport_version)) {
     // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
     ASSERT_TRUE(Initialize());
     return;
@@ -1702,7 +1706,8 @@
 }
 
 TEST_P(EndToEndTestWithTls, 15ByteConnectionId) {
-  if (GetParam().negotiated_version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(
+          GetParam().negotiated_version.transport_version)) {
     // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
     ASSERT_TRUE(Initialize());
     return;
@@ -2253,7 +2258,7 @@
   QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
                     Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
   std::unique_ptr<QuicEncryptedPacket> packet;
-  if (client_connection->transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
     packet = framer.BuildIetfStatelessResetPacket(connection_id,
                                                   stateless_reset_token);
   } else {
@@ -2302,7 +2307,7 @@
   testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
   client_->client()->client_session()->connection()->set_debug_visitor(
       &visitor);
-  if (client_connection->transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
     packet = framer.BuildIetfStatelessResetPacket(incorrect_connection_id,
                                                   stateless_reset_token);
     EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
@@ -2320,7 +2325,7 @@
       client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
   server_thread_->Resume();
 
-  if (client_connection->transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
     // The request should fail. IETF stateless reset does not include connection
     // ID.
     EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
@@ -2377,7 +2382,7 @@
   std::unique_ptr<QuicEncryptedPacket> packet(
       QuicFramer::BuildVersionNegotiationPacket(
           incorrect_connection_id, EmptyQuicConnectionId(),
-          client_connection->transport_version() > QUIC_VERSION_43,
+          VersionHasIetfInvariantHeader(client_connection->transport_version()),
           server_supported_versions_));
   testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
   client_connection->set_debug_visitor(&visitor);
@@ -3285,8 +3290,10 @@
   client_.reset(CreateQuicClient(client_writer_));
   EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
 
-  if (client_->client()->client_session()->connection()->transport_version() >
-          QUIC_VERSION_43 ||
+  if (VersionHasIetfInvariantHeader(client_->client()
+                                        ->client_session()
+                                        ->connection()
+                                        ->transport_version()) ||
       GetQuicReloadableFlag(quic_terminate_gquic_connection_as_ietf)) {
     EXPECT_EQ(QUIC_HANDSHAKE_FAILED, client_->connection_error());
   } else {
@@ -3486,7 +3493,7 @@
   EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
   QuicSession* client_session = client_->client()->client_session();
   QuicConnection* client_connection = client_session->connection();
-  if (client_connection->transport_version() <= QUIC_VERSION_44) {
+  if (!VersionSupportsMessageFrames(client_connection->transport_version())) {
     return;
   }
 
@@ -3762,9 +3769,9 @@
   // This test ensures ZERO_RTT_PROTECTED connection close could close a client
   // which has switched to forward secure.
   connect_to_server_on_initialize_ =
-      negotiated_version_.transport_version <= QUIC_VERSION_43;
+      !VersionHasIetfInvariantHeader(negotiated_version_.transport_version);
   ASSERT_TRUE(Initialize());
-  if (negotiated_version_.transport_version <= QUIC_VERSION_43) {
+  if (!VersionHasIetfInvariantHeader(negotiated_version_.transport_version)) {
     // Only runs for IETF QUIC header.
     return;
   }
@@ -3823,9 +3830,9 @@
   // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
   // which has ZERO_RTT_PROTECTED encryption level.
   connect_to_server_on_initialize_ =
-      negotiated_version_.transport_version <= QUIC_VERSION_43;
+      !VersionHasIetfInvariantHeader(negotiated_version_.transport_version);
   ASSERT_TRUE(Initialize());
-  if (negotiated_version_.transport_version <= QUIC_VERSION_43) {
+  if (!VersionHasIetfInvariantHeader(negotiated_version_.transport_version)) {
     // Only runs for IETF QUIC header.
     return;
   }
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index b718278..847de2b 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -560,7 +560,7 @@
   ParsedQuicVersionVector versions = {GetParam()};
   bool version_flag = false;
   QuicConnectionIdIncluded scid_included = CONNECTION_ID_ABSENT;
-  if (GetParam().transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(GetParam().transport_version)) {
     version_flag = true;
     source_connection_id = destination_connection_id;
     scid_included = CONNECTION_ID_PRESENT;
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 226a4cc..35f0752 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -332,7 +332,8 @@
       next_mtu_probe_at_(kPacketsBetweenMtuProbesBase),
       largest_received_packet_size_(0),
       write_error_occurred_(false),
-      no_stop_waiting_frames_(transport_version() > QUIC_VERSION_43),
+      no_stop_waiting_frames_(
+          VersionHasIetfInvariantHeader(transport_version())),
       consecutive_num_packets_with_no_retransmittable_frames_(0),
       max_consecutive_num_packets_with_no_retransmittable_frames_(
           kMaxConsecutiveNonRetransmittablePackets),
@@ -685,7 +686,7 @@
 
   MaybeEnableSessionDecidesWhatToWrite();
   no_stop_waiting_frames_ =
-      received_version.transport_version > QUIC_VERSION_43;
+      VersionHasIetfInvariantHeader(received_version.transport_version);
 
   // TODO(satyamshekhar): Store the packet number of this packet and close the
   // connection if we ever received a packet with incorrect version and whose
@@ -771,7 +772,7 @@
 
   QUIC_DLOG(INFO) << ENDPOINT << "Negotiated version: "
                   << ParsedQuicVersionToString(version());
-  no_stop_waiting_frames_ = transport_version() > QUIC_VERSION_43;
+  no_stop_waiting_frames_ = VersionHasIetfInvariantHeader(transport_version());
   version_negotiation_state_ = NEGOTIATION_IN_PROGRESS;
 
   RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
@@ -2173,7 +2174,7 @@
   if (version_negotiation_state_ != NEGOTIATED_VERSION) {
     if (perspective_ == Perspective::IS_CLIENT) {
       DCHECK(!header.version_flag || header.form != GOOGLE_QUIC_PACKET);
-      if (framer_.transport_version() <= QUIC_VERSION_43) {
+      if (!VersionHasIetfInvariantHeader(framer_.transport_version())) {
         // If the client gets a packet without the version flag from the server
         // it should stop sending version since the version negotiation is done.
         // IETF QUIC stops sending version once encryption level switches to
@@ -2727,7 +2728,7 @@
       break;
     default:
       // We can't send an error as the socket is presumably borked.
-      if (transport_version() > QUIC_VERSION_43) {
+      if (VersionHasIetfInvariantHeader(transport_version())) {
         QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_ietf);
       } else {
         QUIC_CODE_COUNT(
@@ -2749,7 +2750,7 @@
     // loop here.
     // TODO(ianswett): This is actually an internal error, not an
     // encryption failure.
-    if (transport_version() > QUIC_VERSION_43) {
+    if (VersionHasIetfInvariantHeader(transport_version())) {
       QUIC_CODE_COUNT(
           quic_tear_down_local_connection_on_serialized_packet_ietf);
     } else {
@@ -2777,7 +2778,7 @@
                                           const std::string& error_details) {
   // The packet creator or generator encountered an unrecoverable error: tear
   // down local connection state immediately.
-  if (transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(transport_version())) {
     QUIC_CODE_COUNT(
         quic_tear_down_local_connection_on_unrecoverable_error_ietf);
   } else {
@@ -3999,7 +4000,7 @@
 
 MessageStatus QuicConnection::SendMessage(QuicMessageId message_id,
                                           QuicMemSliceSpan message) {
-  if (transport_version() <= QUIC_VERSION_44) {
+  if (!VersionSupportsMessageFrames(transport_version())) {
     QUIC_BUG << "MESSAGE frame is not supported for version "
              << transport_version();
     return MESSAGE_STATUS_UNSUPPORTED;
@@ -4059,7 +4060,7 @@
   }
   if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)) {
     if (encryption_level_ != ENCRYPTION_ZERO_RTT) {
-      if (transport_version() > QUIC_VERSION_43) {
+      if (VersionHasIetfInvariantHeader(transport_version())) {
         QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close_ietf);
       } else {
         QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close);
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 554f71a..fb3d21b 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -883,11 +883,12 @@
          {AckResponse::kDefer, AckResponse::kImmediate}) {
       for (bool no_stop_waiting : {true, false}) {
         // After version 43, never use STOP_WAITING.
-        params.push_back(TestParams(
-            all_supported_versions[i], ack_response,
-            all_supported_versions[i].transport_version <= QUIC_VERSION_43
-                ? no_stop_waiting
-                : true));
+        params.push_back(
+            TestParams(all_supported_versions[i], ack_response,
+                       !VersionHasIetfInvariantHeader(
+                           all_supported_versions[i].transport_version)
+                           ? no_stop_waiting
+                           : true));
       }
     }
   }
@@ -948,7 +949,7 @@
     }
     QuicFramerPeer::SetLastSerializedServerConnectionId(
         QuicConnectionPeer::GetFramer(&connection_), connection_id_);
-    if (version().transport_version > QUIC_VERSION_43) {
+    if (VersionHasIetfInvariantHeader(version().transport_version)) {
       EXPECT_TRUE(QuicConnectionPeer::GetNoStopWaitingFrames(&connection_));
     } else {
       QuicConnectionPeer::SetNoStopWaitingFrames(&connection_,
@@ -1126,7 +1127,7 @@
     header.destination_connection_id = connection_id_;
     header.packet_number_length = packet_number_length_;
     header.destination_connection_id_included = connection_id_included_;
-    if ((peer_framer_.transport_version() > QUIC_VERSION_43 ||
+    if ((VersionHasIetfInvariantHeader(peer_framer_.transport_version()) ||
          GetQuicRestartFlag(quic_do_not_override_connection_id)) &&
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.destination_connection_id_included = CONNECTION_ID_ABSENT;
@@ -1347,7 +1348,7 @@
   QuicPacketHeader ConstructPacketHeader(uint64_t number,
                                          EncryptionLevel level) {
     QuicPacketHeader header;
-    if (peer_framer_.transport_version() > QUIC_VERSION_43 &&
+    if (VersionHasIetfInvariantHeader(peer_framer_.transport_version()) &&
         level < ENCRYPTION_FORWARD_SECURE) {
       // Set long header type accordingly.
       header.version_flag = true;
@@ -1371,7 +1372,7 @@
       header.destination_connection_id = connection_id_;
       header.destination_connection_id_included = connection_id_included_;
     }
-    if (peer_framer_.transport_version() > QUIC_VERSION_43 &&
+    if (VersionHasIetfInvariantHeader(peer_framer_.transport_version()) &&
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.destination_connection_id_included = CONNECTION_ID_ABSENT;
       if (header.version_flag) {
@@ -1420,12 +1421,12 @@
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.source_connection_id = connection_id_;
       header.destination_connection_id_included = CONNECTION_ID_ABSENT;
-      if (peer_framer_.transport_version() <= QUIC_VERSION_43) {
+      if (!VersionHasIetfInvariantHeader(peer_framer_.transport_version())) {
         header.source_connection_id_included = CONNECTION_ID_PRESENT;
       }
     } else {
       header.destination_connection_id = connection_id_;
-      if (peer_framer_.transport_version() > QUIC_VERSION_43) {
+      if (VersionHasIetfInvariantHeader(peer_framer_.transport_version())) {
         header.destination_connection_id_included = CONNECTION_ID_ABSENT;
       }
     }
@@ -2589,13 +2590,13 @@
   QuicPacketNumber retransmission;
   // Packet 1 is short header for IETF QUIC because the encryption level
   // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
-  EXPECT_CALL(
-      *send_algorithm_,
-      OnPacketSent(_, _, _,
-                   GetParam().version.transport_version > QUIC_VERSION_43
-                       ? packet_size
-                       : packet_size - kQuicVersionSize,
-                   _))
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _,
+                           VersionHasIetfInvariantHeader(
+                               GetParam().version.transport_version)
+                               ? packet_size
+                               : packet_size - kQuicVersionSize,
+                           _))
       .WillOnce(SaveArg<2>(&retransmission));
 
   ProcessAckPacket(&frame);
@@ -2742,7 +2743,7 @@
 }
 
 TEST_P(QuicConnectionTest, LeastUnackedLower) {
-  if (GetParam().version.transport_version > QUIC_VERSION_43 ||
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version) ||
       connection_.SupportsMultiplePacketNumberSpaces()) {
     return;
   }
@@ -3564,13 +3565,13 @@
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
   // Packet 1 is short header for IETF QUIC because the encryption level
   // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
-  EXPECT_CALL(
-      *send_algorithm_,
-      OnPacketSent(_, _, _,
-                   GetParam().version.transport_version > QUIC_VERSION_43
-                       ? packet_size
-                       : packet_size - kQuicVersionSize,
-                   _));
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _,
+                           VersionHasIetfInvariantHeader(
+                               GetParam().version.transport_version)
+                               ? packet_size
+                               : packet_size - kQuicVersionSize,
+                           _));
   ProcessAckPacket(&frame);
 }
 
@@ -5493,7 +5494,7 @@
 
 TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
   set_perspective(Perspective::IS_SERVER);
-  if (GetParam().version.transport_version <= QUIC_VERSION_43) {
+  if (!VersionHasIetfInvariantHeader(GetParam().version.transport_version)) {
     // For IETF QUIC, encryption level will be switched to FORWARD_SECURE in
     // SendStreamDataWithString.
     QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
@@ -5519,7 +5520,7 @@
   EXPECT_EQ(payload.size(),
             connection_.SendStreamDataWithString(3, payload, 1350, NO_FIN)
                 .bytes_consumed);
-  if (connection_.transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(connection_.transport_version())) {
     // Short header packets sent from server omit connection ID already, and
     // stream offset size increases from 0 to 2.
     EXPECT_EQ(non_truncated_packet_size, writer_->last_packet_size() - 2);
@@ -6642,7 +6643,7 @@
 }
 
 TEST_P(QuicConnectionTest, PublicReset) {
-  if (GetParam().version.transport_version > QUIC_VERSION_43 ||
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version) ||
       connection_.SupportsMultiplePacketNumberSpaces()) {
     return;
   }
@@ -6659,7 +6660,7 @@
 }
 
 TEST_P(QuicConnectionTest, IetfStatelessReset) {
-  if (GetParam().version.transport_version <= QUIC_VERSION_43 ||
+  if (!VersionHasIetfInvariantHeader(GetParam().version.transport_version) ||
       connection_.SupportsMultiplePacketNumberSpaces()) {
     return;
   }
@@ -6725,7 +6726,7 @@
 }
 
 TEST_P(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
-  if (GetParam().version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version)) {
     return;
   }
   // Set the packet number of the ack packet to be least unacked (4).
@@ -6740,7 +6741,7 @@
   SetQuicReloadableFlag(quic_enable_version_99, false);
   connection_.SetSupportedVersions(CurrentSupportedVersions());
   set_perspective(Perspective::IS_SERVER);
-  if (GetParam().version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version)) {
     peer_framer_.set_version_for_tests(
         ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_99));
   } else {
@@ -6793,7 +6794,7 @@
   SetQuicReloadableFlag(quic_enable_version_99, false);
   connection_.SetSupportedVersions(CurrentSupportedVersions());
   set_perspective(Perspective::IS_SERVER);
-  if (GetParam().version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version)) {
     peer_framer_.set_version_for_tests(
         ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_99));
   } else {
@@ -6853,7 +6854,7 @@
   SetQuicReloadableFlag(quic_enable_version_99, false);
   connection_.SetSupportedVersions(CurrentSupportedVersions());
   set_perspective(Perspective::IS_SERVER);
-  if (GetParam().version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version)) {
     peer_framer_.set_version_for_tests(
         ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_99));
   } else {
@@ -6907,7 +6908,7 @@
   std::unique_ptr<QuicEncryptedPacket> encrypted(
       QuicFramer::BuildVersionNegotiationPacket(
           connection_id_, EmptyQuicConnectionId(),
-          connection_.transport_version() > QUIC_VERSION_43,
+          VersionHasIetfInvariantHeader(connection_.transport_version()),
           AllSupportedVersions()));
   std::unique_ptr<QuicReceivedPacket> received(
       ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
@@ -6945,7 +6946,7 @@
   connection_.ProcessUdpPacket(
       kSelfAddress, kPeerAddress,
       QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
-  if (GetParam().version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version)) {
     // IETF QUIC stops sending version when switch to FORWARD_SECURE.
     EXPECT_NE(ENCRYPTION_FORWARD_SECURE, connection_.encryption_level());
     ASSERT_TRUE(QuicPacketCreatorPeer::SendVersionInPacket(creator_));
@@ -6963,7 +6964,7 @@
   std::unique_ptr<QuicEncryptedPacket> encrypted(
       QuicFramer::BuildVersionNegotiationPacket(
           connection_id_, EmptyQuicConnectionId(),
-          connection_.transport_version() > QUIC_VERSION_43,
+          VersionHasIetfInvariantHeader(connection_.transport_version()),
           AllSupportedVersions()));
   std::unique_ptr<QuicReceivedPacket> received(
       ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
@@ -7015,8 +7016,9 @@
   // For IETF QUIC, version is not included as the encryption level switches to
   // FORWARD_SECURE in SendStreamDataWithString.
   size_t save_on_version =
-      GetParam().version.transport_version > QUIC_VERSION_43 ? 0
-                                                             : kQuicVersionSize;
+      VersionHasIetfInvariantHeader(GetParam().version.transport_version)
+          ? 0
+          : kQuicVersionSize;
   EXPECT_EQ(3 * first_packet_size + 2 * second_packet_size - save_on_version,
             stats.bytes_sent);
   EXPECT_EQ(5u, stats.packets_sent);
@@ -7034,12 +7036,12 @@
       peer_framer_.perspective() == Perspective::IS_SERVER) {
     header.source_connection_id = connection_id_;
     header.destination_connection_id_included = CONNECTION_ID_ABSENT;
-    if (peer_framer_.transport_version() <= QUIC_VERSION_43) {
+    if (!VersionHasIetfInvariantHeader(peer_framer_.transport_version())) {
       header.source_connection_id_included = CONNECTION_ID_PRESENT;
     }
   } else {
     header.destination_connection_id = connection_id_;
-    if (peer_framer_.transport_version() > QUIC_VERSION_43) {
+    if (VersionHasIetfInvariantHeader(peer_framer_.transport_version())) {
       header.destination_connection_id_included = CONNECTION_ID_ABSENT;
     }
   }
@@ -7143,7 +7145,7 @@
 TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
   QuicPacketHeader header;
   header.packet_number = QuicPacketNumber(1);
-  if (GetParam().version.transport_version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version)) {
     header.form = IETF_QUIC_LONG_HEADER_PACKET;
   }
 
@@ -8198,7 +8200,7 @@
 }
 
 TEST_P(QuicConnectionTest, SendMessage) {
-  if (connection_.transport_version() <= QUIC_VERSION_44 ||
+  if (!VersionSupportsMessageFrames(connection_.transport_version()) ||
       connection_.SupportsMultiplePacketNumberSpaces()) {
     return;
   }
@@ -8350,7 +8352,7 @@
   // This test mimics a problematic scenario where an IETF QUIC connection
   // receives a Google QUIC packet and continue processing it using Google QUIC
   // wire format.
-  if (version().transport_version <= QUIC_VERSION_43) {
+  if (!VersionHasIetfInvariantHeader(version().transport_version)) {
     return;
   }
   set_perspective(Perspective::IS_SERVER);
diff --git a/quic/core/quic_crypto_stream.cc b/quic/core/quic_crypto_stream.cc
index f394b3d..a38cb82 100644
--- a/quic/core/quic_crypto_stream.cc
+++ b/quic/core/quic_crypto_stream.cc
@@ -56,8 +56,8 @@
       PACKET_0BYTE_CONNECTION_ID,
       /*include_version=*/true,
       /*include_diversification_nonce=*/true,
-      version > QUIC_VERSION_43 ? PACKET_4BYTE_PACKET_NUMBER
-                                : PACKET_1BYTE_PACKET_NUMBER,
+      VersionHasIetfInvariantHeader(version) ? PACKET_4BYTE_PACKET_NUMBER
+                                             : PACKET_1BYTE_PACKET_NUMBER,
       VARIABLE_LENGTH_INTEGER_LENGTH_1, VARIABLE_LENGTH_INTEGER_LENGTH_2,
       /*offset=*/0);
 }
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index 0e6a71d..1611287 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -634,10 +634,10 @@
   if (connection->termination_packets() != nullptr &&
       !connection->termination_packets()->empty()) {
     action = QuicTimeWaitListManager::SEND_TERMINATION_PACKETS;
-  } else if (connection->transport_version() > QUIC_VERSION_43 ||
+  } else if (VersionHasIetfInvariantHeader(connection->transport_version()) ||
              GetQuicReloadableFlag(quic_terminate_gquic_connection_as_ietf)) {
     if (!connection->IsHandshakeConfirmed()) {
-      if (connection->transport_version() <= QUIC_VERSION_43) {
+      if (!VersionHasIetfInvariantHeader(connection->transport_version())) {
         QUIC_CODE_COUNT(gquic_add_to_time_wait_list_with_handshake_failed);
       } else {
         QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_handshake_failed);
@@ -647,7 +647,7 @@
       // QUIC_HANDSHAKE_FAILED and adds the connection to the time wait list.
       StatelesslyTerminateConnection(
           connection->connection_id(),
-          connection->transport_version() > QUIC_VERSION_43
+          VersionHasIetfInvariantHeader(connection->transport_version())
               ? IETF_QUIC_LONG_HEADER_PACKET
               : GOOGLE_QUIC_PACKET,
           /*version_flag=*/true, connection->version(), QUIC_HANDSHAKE_FAILED,
@@ -662,8 +662,9 @@
     QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_stateless_reset);
   }
   time_wait_list_manager_->AddConnectionIdToTimeWait(
-      it->first, connection->transport_version() > QUIC_VERSION_43, action,
-      connection->encryption_level(), connection->termination_packets());
+      it->first, VersionHasIetfInvariantHeader(connection->transport_version()),
+      action, connection->encryption_level(),
+      connection->termination_packets());
   session_map_.erase(it);
 }
 
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index df29bca..538c8d9 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -1073,7 +1073,8 @@
   QuicConnectionId connection_id = TestConnectionId(1);
   EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
       .Times(0);
-  if (CurrentSupportedVersions()[0].transport_version > QUIC_VERSION_43 &&
+  if (VersionHasIetfInvariantHeader(
+          CurrentSupportedVersions()[0].transport_version) &&
       !QuicUtils::VariableLengthConnectionIdAllowedForVersion(
           CurrentSupportedVersions()[0].transport_version)) {
     // This IETF packet has invalid connection ID length.
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 6048133..04b824a 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -520,7 +520,7 @@
 size_t QuicFramer::GetMessageFrameSize(QuicTransportVersion version,
                                        bool last_frame_in_packet,
                                        QuicByteCount length) {
-  QUIC_BUG_IF(version <= QUIC_VERSION_44)
+  QUIC_BUG_IF(!VersionSupportsMessageFrames(version))
       << "Try to serialize MESSAGE frame in " << version;
   return kQuicFrameTypeSize +
          (last_frame_in_packet ? 0 : QuicDataWriter::GetVarInt62Len(length)) +
@@ -1484,7 +1484,7 @@
   bool packet_has_ietf_packet_header = false;
   if (infer_packet_header_type_from_version_) {
     packet_has_ietf_packet_header =
-        version_.transport_version > QUIC_VERSION_43;
+        VersionHasIetfInvariantHeader(version_.transport_version);
   } else if (!reader.IsDoneReading()) {
     uint8_t type = reader.PeekByte();
     packet_has_ietf_packet_header = QuicUtils::IsIetfPacketHeader(type);
@@ -2054,7 +2054,7 @@
 bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
                                     QuicDataWriter* writer,
                                     size_t* length_field_offset) {
-  if (transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(transport_version())) {
     return AppendIetfPacketHeader(header, writer, length_field_offset);
   }
   QUIC_DVLOG(1) << ENDPOINT << "Appending header: " << header;
@@ -5220,7 +5220,7 @@
 bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
                                         const QuicStopWaitingFrame& frame,
                                         QuicDataWriter* writer) {
-  DCHECK_GE(QUIC_VERSION_43, version_.transport_version);
+  DCHECK(!VersionHasIetfInvariantHeader(version_.transport_version));
   DCHECK(frame.least_unacked.IsInitialized() &&
          header.packet_number >= frame.least_unacked);
   const uint64_t least_unacked_delta =
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index 7420c72..3daf302 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -123,7 +123,7 @@
 // maximum packet size if we stop sending version before it is serialized.
 void QuicPacketCreator::StopSendingVersion() {
   DCHECK(send_version_in_packet_);
-  DCHECK_LE(framer_->transport_version(), QUIC_VERSION_43);
+  DCHECK(!VersionHasIetfInvariantHeader(framer_->transport_version()));
   send_version_in_packet_ = false;
   if (packet_size_ > 0) {
     DCHECK_LT(kQuicVersionSize, packet_size_);
@@ -758,7 +758,7 @@
 
 QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
     const {
-  if (framer_->transport_version() > QUIC_VERSION_43 ||
+  if (VersionHasIetfInvariantHeader(framer_->transport_version()) ||
       GetQuicRestartFlag(quic_do_not_override_connection_id)) {
     // Packets sent by client always include destination connection ID, and
     // those sent by the server do not include destination connection ID.
@@ -997,7 +997,7 @@
 }
 
 bool QuicPacketCreator::IncludeVersionInHeader() const {
-  if (framer_->transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(framer_->transport_version())) {
     return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
   }
   return send_version_in_packet_;
@@ -1045,7 +1045,7 @@
 }
 
 QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
-  if (framer_->transport_version() <= QUIC_VERSION_44) {
+  if (!VersionSupportsMessageFrames(framer_->transport_version())) {
     return 0;
   }
   const size_t packet_header_size = GetPacketHeaderSize(
@@ -1061,7 +1061,7 @@
 }
 
 QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
-  if (framer_->transport_version() <= QUIC_VERSION_44) {
+  if (!VersionSupportsMessageFrames(framer_->transport_version())) {
     return 0;
   }
   // QUIC Crypto server packets may include a diversification nonce.
@@ -1091,7 +1091,7 @@
 }
 
 bool QuicPacketCreator::HasIetfLongHeader() const {
-  return framer_->transport_version() > QUIC_VERSION_43 &&
+  return VersionHasIetfInvariantHeader(framer_->transport_version()) &&
          packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
 }
 
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
index bf69563..ba72d25 100644
--- a/quic/core/quic_packet_creator_test.cc
+++ b/quic/core/quic_packet_creator_test.cc
@@ -104,7 +104,7 @@
   }
 
   void StopSendingVersion() {
-    if (version_ > QUIC_VERSION_43) {
+    if (VersionHasIetfInvariantHeader(version_)) {
       set_encryption_level(ENCRYPTION_FORWARD_SECURE);
       return;
     }
@@ -331,7 +331,7 @@
 }
 
 TEST_P(QuicPacketCreatorTest, ReserializeFramesWithSequenceNumberLength) {
-  if (client_framer_.transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(client_framer_.transport_version())) {
     creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
   }
   // If the original packet number length, the current packet number
@@ -808,7 +808,8 @@
   QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
   ParsedQuicVersionVector versions;
   versions.push_back(test::QuicVersionMax());
-  const bool ietf_quic = GetParam().version.transport_version > QUIC_VERSION_43;
+  const bool ietf_quic =
+      VersionHasIetfInvariantHeader(GetParam().version.transport_version);
   std::unique_ptr<QuicEncryptedPacket> encrypted(
       creator_.SerializeVersionNegotiationPacket(ietf_quic, versions));
 
@@ -1106,7 +1107,7 @@
 }
 
 TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) {
-  if (GetParam().version.transport_version > QUIC_VERSION_43 &&
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version) &&
       GetParam().version.transport_version != QUIC_VERSION_99) {
     EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
               QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
@@ -1144,7 +1145,7 @@
 
 TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) {
   QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
-  if (GetParam().version.transport_version > QUIC_VERSION_43 &&
+  if (VersionHasIetfInvariantHeader(GetParam().version.transport_version) &&
       GetParam().version.transport_version != QUIC_VERSION_99) {
     EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
               QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
@@ -1674,7 +1675,7 @@
 }
 
 TEST_P(QuicPacketCreatorTest, AddMessageFrame) {
-  if (client_framer_.transport_version() <= QUIC_VERSION_44) {
+  if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
     return;
   }
   creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
@@ -1726,7 +1727,7 @@
 }
 
 TEST_P(QuicPacketCreatorTest, MessageFrameConsumption) {
-  if (client_framer_.transport_version() <= QUIC_VERSION_44) {
+  if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
     return;
   }
   std::string message_data(kDefaultMaxPacketSize, 'a');
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc
index 7212e22..1756874 100644
--- a/quic/core/quic_packet_generator_test.cc
+++ b/quic/core/quic_packet_generator_test.cc
@@ -901,7 +901,7 @@
 }
 
 TEST_F(QuicPacketGeneratorTest, ConsumeDataLargeSendAckTrue) {
-  if (framer_.transport_version() > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(framer_.transport_version())) {
     return;
   }
   delegate_.SetCanNotWrite();
@@ -1144,7 +1144,7 @@
 
   for (size_t i = 1; i < 10; i++) {
     generator_.SetServerConnectionIdLength(i);
-    if (framer_.transport_version() > QUIC_VERSION_43) {
+    if (VersionHasIetfInvariantHeader(framer_.transport_version())) {
       EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
                 creator_->GetDestinationConnectionIdLength());
     } else {
@@ -1423,7 +1423,7 @@
 }
 
 TEST_F(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) {
-  if (framer_.transport_version() > QUIC_VERSION_43) {
+  if (VersionSupportsMessageFrames(framer_.transport_version())) {
     return;
   }
   // Test added to ensure the generator does not crash when an invalid frame is
@@ -1627,7 +1627,7 @@
 }
 
 TEST_F(QuicPacketGeneratorTest, AddMessageFrame) {
-  if (framer_.transport_version() <= QUIC_VERSION_44) {
+  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
     return;
   }
   quic::QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
diff --git a/quic/core/quic_packets.cc b/quic/core/quic_packets.cc
index 738cc6e..4cf727b 100644
--- a/quic/core/quic_packets.cc
+++ b/quic/core/quic_packets.cc
@@ -121,7 +121,7 @@
     QuicVariableLengthIntegerLength retry_token_length_length,
     QuicByteCount retry_token_length,
     QuicVariableLengthIntegerLength length_length) {
-  if (version > QUIC_VERSION_43) {
+  if (VersionHasIetfInvariantHeader(version)) {
     if (include_version) {
       // Long header.
       return kPacketHeaderTypeSize + kConnectionIdLengthSize +
diff --git a/quic/core/quic_time_wait_list_manager_test.cc b/quic/core/quic_time_wait_list_manager_test.cc
index 4624a23..209f26f 100644
--- a/quic/core/quic_time_wait_list_manager_test.cc
+++ b/quic/core/quic_time_wait_list_manager_test.cc
@@ -163,8 +163,8 @@
       QuicTimeWaitListManager::TimeWaitAction action,
       std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
     time_wait_list_manager_.AddConnectionIdToTimeWait(
-        connection_id, version.transport_version > QUIC_VERSION_43, action,
-        ENCRYPTION_INITIAL, packets);
+        connection_id, VersionHasIetfInvariantHeader(version.transport_version),
+        action, ENCRYPTION_INITIAL, packets);
   }
 
   bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index 0a368df..b33e084 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -336,6 +336,18 @@
                                          std::numeric_limits<size_t>::max());
 }
 
+// Returns true if |transport_version| uses IETF invariant headers.
+QUIC_EXPORT_PRIVATE inline bool VersionHasIetfInvariantHeader(
+    QuicTransportVersion transport_version) {
+  return transport_version > QUIC_VERSION_43;
+}
+
+// Returns true if |transport_version| supports MESSAGE frames.
+QUIC_EXPORT_PRIVATE inline bool VersionSupportsMessageFrames(
+    QuicTransportVersion transport_version) {
+  return transport_version > QUIC_VERSION_44;
+}
+
 // Returns true if QuicSpdyStream encodes body using HTTP/3 specification and
 // sends data frame header along with body.
 QUIC_EXPORT_PRIVATE inline bool VersionHasDataFrameHeader(
diff --git a/quic/quartc/quartc_session.h b/quic/quartc/quartc_session.h
index cd8d2cb..3dd2916 100644
--- a/quic/quartc/quartc_session.h
+++ b/quic/quartc/quartc_session.h
@@ -69,7 +69,7 @@
 
   // Return true if transport support message frame.
   bool CanSendMessage() const {
-    return connection()->transport_version() > QUIC_VERSION_44;
+    return VersionSupportsMessageFrames(connection()->transport_version());
   }
 
   void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;