Add metrics to debug b/537474108.

Changes include:
- Add `/gfe/gfe2/quic/more_to_read_after_epoll_in` counter: Increments
  when an EPOLLIN event finishes but the QUIC socket is not drained.
- Add `/gfe/gfe2/quic/has_buffered_chlos_after_epoll_in` counter: Increments
  when an EPOLLIN event finishes but there are some CHLOs buffered.
- Add `/gfe/gfe2/quic/buffered_session_queue_time` distribution: Tracks
  the duration (in ms) from the earliest buffered packet's receipt time
  to the actual session creation. This is recorded in the new
  `QuicDispatcher::OnNewSessionCreated` virtual method.
- Add `/gfe/gfe2/quic/buffered_sessions` distribution: Exports the
  number of buffered sessions (both total and without full CHLO)
  after a QUIC packet is processed.

PiperOrigin-RevId: 976362820
diff --git a/quiche/quic/core/quic_buffered_packet_store.h b/quiche/quic/core/quic_buffered_packet_store.h
index 6999681..5570b7f 100644
--- a/quiche/quic/core/quic_buffered_packet_store.h
+++ b/quiche/quic/core/quic_buffered_packet_store.h
@@ -33,6 +33,7 @@
 #include "quiche/quic/core/quic_types.h"
 #include "quiche/quic/core/quic_versions.h"
 #include "quiche/quic/core/tls_chlo_extractor.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
 #include "quiche/quic/platform/api/quic_socket_address.h"
 #include "quiche/common/platform/api/quiche_export.h"
 #include "quiche/common/platform/api/quiche_logging.h"
@@ -268,6 +269,21 @@
   const BufferedPacketList* GetPacketList(
       const QuicConnectionId& connection_id) const;
 
+  // Returns the number of buffered sessions in the store.
+  size_t num_buffered_sessions() const { return num_buffered_sessions_; }
+
+  // Returns the number of buffered sessions without a full CHLO.
+  size_t num_buffered_sessions_without_chlo() const {
+    if (num_buffered_sessions_ < num_buffered_sessions_with_chlo_) {
+      QUIC_BUG(quic_store_invalid_session_counts)
+          << "num_buffered_sessions: " << num_buffered_sessions_
+          << ", num_buffered_sessions_with_chlo: "
+          << num_buffered_sessions_with_chlo_;
+      return 0;
+    }
+    return num_buffered_sessions_ - num_buffered_sessions_with_chlo_;
+  }
+
  private:
   friend class test::QuicBufferedPacketStorePeer;
 
diff --git a/quiche/quic/core/quic_dispatcher.cc b/quiche/quic/core/quic_dispatcher.cc
index 5a04ab6..e98e00e 100644
--- a/quiche/quic/core/quic_dispatcher.cc
+++ b/quiche/quic/core/quic_dispatcher.cc
@@ -1183,6 +1183,8 @@
         packet_list.connection_id_generator,
         packet_list.dispatcher_sent_packets);
     if (session_ptr != nullptr) {
+      OnNewSessionCreated(*session_ptr, packet_list.creation_time,
+                          /*entire_chlo_buffered=*/true);
       DeliverPacketsToSession(packets, session_ptr.get());
     }
   }
@@ -1261,6 +1263,8 @@
     QUICHE_DCHECK_EQ(packet_list.connection_id_generator, nullptr);
     return;
   }
+  OnNewSessionCreated(*session_ptr, packet_list.creation_time,
+                      /*entire_chlo_buffered=*/false);
   // Process the current packet first, then deliver queued-up packets.
   // Note that multi-packet CHLOs, if received in packet number order, will
   // not be delivered in the same order. This needs to be fixed.
diff --git a/quiche/quic/core/quic_dispatcher.h b/quiche/quic/core/quic_dispatcher.h
index 11ac78d..f8ac340 100644
--- a/quiche/quic/core/quic_dispatcher.h
+++ b/quiche/quic/core/quic_dispatcher.h
@@ -39,6 +39,7 @@
 #include "quiche/quic/core/quic_packets.h"
 #include "quiche/quic/core/quic_process_packet_interface.h"
 #include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time.h"
 #include "quiche/quic/core/quic_time_wait_list_manager.h"
 #include "quiche/quic/core/quic_types.h"
 #include "quiche/quic/core/quic_version_manager.h"
@@ -142,6 +143,16 @@
 
   size_t NumSessions() const;
 
+  // Number of buffered sessions in the store.
+  size_t num_buffered_sessions() const {
+    return buffered_packets_.num_buffered_sessions();
+  }
+
+  // Number of buffered sessions without a full ClientHello in the store.
+  size_t num_buffered_sessions_without_chlo() const {
+    return buffered_packets_.num_buffered_sessions_without_chlo();
+  }
+
   // Deletes all sessions on the closed session list and clears the list.
   virtual void DeleteSessions();
 
@@ -238,6 +249,14 @@
   // will be owned by the dispatcher as time_wait_list_manager_
   virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
 
+  // Called after a new session is created and before any packet is delivered to
+  // it. `first_packet_buffered_time` is the time when the first received packet
+  // of the connection was buffered, or QuicTime::Zero if no packets were
+  // buffered.
+  virtual void OnNewSessionCreated(const QuicSession& /*session*/,
+                                   QuicTime /*first_packet_buffered_time*/,
+                                   bool /*entire_chlo_buffered*/) const {}
+
   // Called when |packet_info| is the last received packet of the client hello.
   // |parsed_chlo| is the parsed version of the client hello. Creates a new
   // connection and delivers any buffered packets for that connection id.
@@ -260,6 +279,8 @@
 
   QuicConnectionHelperInterface* helper() { return helper_.get(); }
 
+  const QuicConnectionHelperInterface* helper() const { return helper_.get(); }
+
   QuicCryptoServerStreamBase::Helper* session_helper() {
     return session_helper_.get();
   }