Make server drop IETF QUIC Version Negotiation packets

It is invalid for a client to send a Version Negotiation packet. Servers should drop them instead of trying to parse them as a packet for unsupported version 0.

gfe-relnote: drop version negotiation, protected by gfe2_restart_flag_quic_server_drop_version_negotiation
PiperOrigin-RevId: 247126958
Change-Id: Ia7272de96fa750ec5b4743b6596fc70c8ce5d128
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 67e3447..c4eefb1 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -281,7 +281,7 @@
         break;
       default:
         QUIC_BUG << "Unreachable statement";
-        *long_header_type = VERSION_NEGOTIATION;
+        *long_header_type = INVALID_PACKET_TYPE;
         return false;
     }
     return true;
@@ -1430,7 +1430,7 @@
   QuicDataWriter writer(len, buffer.get());
 
   // TODO(fayang): Randomly select a value for the type.
-  uint8_t type = static_cast<uint8_t>(FLAGS_LONG_HEADER | VERSION_NEGOTIATION);
+  uint8_t type = static_cast<uint8_t>(FLAGS_LONG_HEADER);
   if (!writer.WriteUInt8(type)) {
     return nullptr;
   }
@@ -1497,8 +1497,19 @@
   }
 
   if (IsVersionNegotiation(header, packet_has_ietf_packet_header)) {
-    QUIC_DVLOG(1) << ENDPOINT << "Received version negotiation packet";
-    return ProcessVersionNegotiationPacket(&reader, header);
+    if (!GetQuicRestartFlag(quic_server_drop_version_negotiation)) {
+      QUIC_DVLOG(1) << ENDPOINT << "Received version negotiation packet";
+      return ProcessVersionNegotiationPacket(&reader, header);
+    }
+    QUIC_RESTART_FLAG_COUNT_N(quic_server_drop_version_negotiation, 1, 2);
+    if (perspective_ == Perspective::IS_CLIENT) {
+      QUIC_DVLOG(1) << "Client received version negotiation packet";
+      return ProcessVersionNegotiationPacket(&reader, header);
+    } else {
+      QUIC_DLOG(ERROR) << "Server received version negotiation packet";
+      set_detailed_error("Server received version negotiation packet.");
+      return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+    }
   }
 
   if (header.version_flag && header.version != version_) {
@@ -1745,6 +1756,10 @@
 
   if (header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
       header->long_packet_type != VERSION_NEGOTIATION) {
+    DCHECK(header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
+           header->long_packet_type == INITIAL ||
+           header->long_packet_type == HANDSHAKE ||
+           header->long_packet_type == ZERO_RTT_PROTECTED);
     // Process packet number.
     QuicPacketNumber base_packet_number;
     if (supports_multiple_packet_number_spaces_) {
@@ -5249,9 +5264,13 @@
     const QuicPacketHeader& header,
     bool packet_has_ietf_packet_header) const {
   if (perspective_ == Perspective::IS_SERVER) {
-    return false;
+    if (!GetQuicRestartFlag(quic_server_drop_version_negotiation)) {
+      return false;
+    }
+    QUIC_RESTART_FLAG_COUNT_N(quic_server_drop_version_negotiation, 2, 2);
   }
-  if (!packet_has_ietf_packet_header) {
+  if (!packet_has_ietf_packet_header &&
+      perspective_ == Perspective::IS_CLIENT) {
     return header.version_flag;
   }
   if (header.form == IETF_QUIC_SHORT_HEADER_PACKET) {