Introduce QUIC connection dapper tracing in GFE2.

See go/gfe-quic-trace for the design.

Protected by FLAGS_quic_reloadable_flag_quic_enable_connection_trace.

PiperOrigin-RevId: 386138667
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 173f648..09f387e 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -36,6 +36,7 @@
 #include "quic/core/quic_alarm.h"
 #include "quic/core/quic_alarm_factory.h"
 #include "quic/core/quic_blocked_writer_interface.h"
+#include "quic/core/quic_connection_context.h"
 #include "quic/core/quic_connection_id.h"
 #include "quic/core/quic_connection_id_manager.h"
 #include "quic/core/quic_connection_stats.h"
@@ -1253,6 +1254,13 @@
     return donot_write_mid_packet_processing_;
   }
 
+  QuicConnectionContext* context() { return &context_; }
+  const QuicConnectionContext* context() const { return &context_; }
+
+  void set_tracer(std::unique_ptr<QuicConnectionTracer> tracer) {
+    context_.tracer.swap(tracer);
+  }
+
  protected:
   // Calls cancel() on all the alarms owned by this connection.
   void CancelAllAlarms();
@@ -1849,6 +1857,8 @@
   bool ShouldSetRetransmissionAlarmOnPacketSent(bool in_flight,
                                                 EncryptionLevel level) const;
 
+  QuicConnectionContext context_;
+
   QuicFramer framer_;
 
   // Contents received in the current packet, especially used to identify
diff --git a/quic/core/quic_connection_context.cc b/quic/core/quic_connection_context.cc
index 65a8dd6..e77fc43 100644
--- a/quic/core/quic_connection_context.cc
+++ b/quic/core/quic_connection_context.cc
@@ -20,9 +20,16 @@
     QuicConnectionContext* new_context)
     : old_context_(QuicConnectionContext::Current()) {
   SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, new_context);
+  if (new_context && new_context->tracer) {
+    new_context->tracer->Activate();
+  }
 }
 
 QuicConnectionContextSwitcher::~QuicConnectionContextSwitcher() {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->Deactivate();
+  }
   SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, old_context_);
 }
 
diff --git a/quic/core/quic_connection_context.h b/quic/core/quic_connection_context.h
index 05b09cf..7cedee6 100644
--- a/quic/core/quic_connection_context.h
+++ b/quic/core/quic_connection_context.h
@@ -33,6 +33,23 @@
     std::string s = absl::StrFormat(format, args...);
     PrintString(s);
   }
+
+ private:
+  friend class QuicConnectionContextSwitcher;
+
+  // Called by QuicConnectionContextSwitcher, when |this| becomes the current
+  // thread's QUIC connection tracer.
+  //
+  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
+  // constructor/destructor, they always come in pairs.
+  virtual void Activate() {}
+
+  // Called by QuicConnectionContextSwitcher, when |this| stops from being the
+  // current thread's QUIC connection tracer.
+  //
+  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
+  // constructor/destructor, they always come in pairs.
+  virtual void Deactivate() {}
 };
 
 // QuicConnectionContext is a per-QuicConnection context that includes
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index dd96a57..5c56c15 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -13,6 +13,7 @@
 #include "absl/strings/string_view.h"
 #include "quic/core/frames/quic_ack_frequency_frame.h"
 #include "quic/core/quic_connection.h"
+#include "quic/core/quic_connection_context.h"
 #include "quic/core/quic_error_codes.h"
 #include "quic/core/quic_flow_controller.h"
 #include "quic/core/quic_types.h"
@@ -751,6 +752,7 @@
 void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
                                    const QuicSocketAddress& peer_address,
                                    const QuicReceivedPacket& packet) {
+  QuicConnectionContextSwitcher cs(connection_->context());
   connection_->ProcessUdpPacket(self_address, peer_address, packet);
 }