gfe-relnote: In QUIC version T099, implement HANDSHAKE_DONE frame to drive the handshake to confirmation on the client side. Not used in prod yet.

PiperOrigin-RevId: 290948924
Change-Id: Idcbc5c0d573b5db992b65d4971ea12a3d7e87633
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 16ec7b6..74931ad 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -374,6 +374,11 @@
                 << ", " << message;
 }
 
+void QuicSession::OnHandshakeDoneReceived() {
+  QUIC_DVLOG(1) << ENDPOINT << "OnHandshakeDoneReceived";
+  GetMutableCryptoStream()->OnHandshakeDoneReceived();
+}
+
 // static
 void QuicSession::RecordConnectionCloseAtServer(QuicErrorCode error,
                                                 ConnectionCloseSource source) {
@@ -1372,6 +1377,12 @@
       }
       QUIC_BUG_IF(!config_.negotiated())
           << ENDPOINT << "Handshake confirmed without parameter negotiation.";
+      if (connection()->version().HasHandshakeDone() &&
+          perspective_ == Perspective::IS_SERVER) {
+        // Server sends HANDSHAKE_DONE to signal confirmation of the handshake
+        // to the client.
+        control_frame_manager_.WriteOrBufferHandshakeDone();
+      }
       break;
     default:
       QUIC_BUG << "Unknown encryption level: "
@@ -1398,9 +1409,7 @@
       NeuterUnencryptedData();
       break;
     case ENCRYPTION_HANDSHAKE:
-      DCHECK(false);
-      // TODO(fayang): implement this when handshake keys discarding settles
-      // down.
+      NeuterHandshakeData();
       break;
     case ENCRYPTION_ZERO_RTT:
       break;