xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_connection_context.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2021 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
6 #define QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
7 
8 #include "absl/strings/str_format.h"
9 #include "absl/strings/string_view.h"
10 #include "quiche/quic/platform/api/quic_export.h"
11 #include "quiche/common/platform/api/quiche_logging.h"
12 
13 namespace quic {
14 
15 // QuicConnectionTracer is responsible for emit trace messages for a single
16 // QuicConnection.
17 // QuicConnectionTracer is part of the QuicConnectionContext.
18 class QUICHE_EXPORT QuicConnectionTracer {
19  public:
20   virtual ~QuicConnectionTracer() = default;
21 
22   // Emit a trace message from a string literal. The trace may simply remember
23   // the address of the literal in this function and read it at a later time.
24   virtual void PrintLiteral(const char* literal) = 0;
25 
26   // Emit a trace message from a string_view. Unlike PrintLiteral, this function
27   // will not read |s| after it returns.
28   virtual void PrintString(absl::string_view s) = 0;
29 
30   // Emit a trace message from printf-style arguments.
31   template <typename... Args>
Printf(const absl::FormatSpec<Args...> & format,const Args &...args)32   void Printf(const absl::FormatSpec<Args...>& format, const Args&... args) {
33     std::string s = absl::StrFormat(format, args...);
34     PrintString(s);
35   }
36 
37  private:
38   friend class QuicConnectionContextSwitcher;
39 
40   // Called by QuicConnectionContextSwitcher, when |this| becomes the current
41   // thread's QUIC connection tracer.
42   //
43   // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
44   // constructor/destructor, they always come in pairs.
Activate()45   virtual void Activate() {}
46 
47   // Called by QuicConnectionContextSwitcher, when |this| stops from being the
48   // current thread's QUIC connection tracer.
49   //
50   // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
51   // constructor/destructor, they always come in pairs.
Deactivate()52   virtual void Deactivate() {}
53 };
54 
55 // QuicBugListener is a helper class for implementing QUIC_BUG. The QUIC_BUG
56 // implementation can send the bug information into quic::CurrentBugListener().
57 class QUICHE_EXPORT QuicBugListener {
58  public:
59   virtual ~QuicBugListener() = default;
60   virtual void OnQuicBug(const char* bug_id, const char* file, int line,
61                          absl::string_view bug_message) = 0;
62 };
63 
64 // QuicConnectionProcessPacketContext is a member of QuicConnectionContext that
65 // contains information of the packet currently being processed by the owning
66 // QuicConnection.
67 struct QUICHE_EXPORT QuicConnectionProcessPacketContext final {
68   // If !empty(), the decrypted payload of the packet currently being processed.
69   absl::string_view decrypted_payload;
70 
71   // The offset within |decrypted_payload|, if it's non-empty, that marks the
72   // start of the frame currently being processed.
73   // Should not be used when |decrypted_payload| is empty.
74   size_t current_frame_offset = 0;
75 
76   // NOTE: This can be very expansive. If used in logs, make sure it is rate
77   // limited via QUIC_BUG etc.
78   std::string DebugString() const;
79 };
80 
81 // QuicConnectionContext is a per-QuicConnection context that includes
82 // facilities useable by any part of a QuicConnection. A QuicConnectionContext
83 // is owned by a QuicConnection.
84 //
85 // The 'top-level' QuicConnection functions are responsible for maintaining the
86 // thread-local QuicConnectionContext pointer, such that any function called by
87 // them(directly or indirectly) can access the context.
88 //
89 // Like QuicConnection, all facilities in QuicConnectionContext are assumed to
90 // be called from a single thread at a time, they are NOT thread-safe.
91 struct QUICHE_EXPORT QuicConnectionContext final {
92   // Get the context on the current executing thread. nullptr if the current
93   // function is not called from a 'top-level' QuicConnection function.
94   static QuicConnectionContext* Current();
95 
96   std::unique_ptr<QuicConnectionTracer> tracer;
97   std::unique_ptr<QuicBugListener> bug_listener;
98 
99   // Information about the packet currently being processed.
100   QuicConnectionProcessPacketContext process_packet_context;
101 };
102 
103 // QuicConnectionContextSwitcher is a RAII object used for maintaining the
104 // thread-local QuicConnectionContext pointer.
105 class QUICHE_EXPORT QuicConnectionContextSwitcher final {
106  public:
107   // The constructor switches from QuicConnectionContext::Current() to
108   // |new_context|.
109   explicit QuicConnectionContextSwitcher(QuicConnectionContext* new_context);
110 
111   // The destructor switches from QuicConnectionContext::Current() back to the
112   // old context.
113   ~QuicConnectionContextSwitcher();
114 
115  private:
116   QuicConnectionContext* old_context_;
117 };
118 
119 // Emit a trace message from a string literal to the current tracer(if any).
QUIC_TRACELITERAL(const char * literal)120 inline void QUIC_TRACELITERAL(const char* literal) {
121   QuicConnectionContext* current = QuicConnectionContext::Current();
122   if (current && current->tracer) {
123     current->tracer->PrintLiteral(literal);
124   }
125 }
126 
127 // Emit a trace message from a string_view to the current tracer(if any).
QUIC_TRACESTRING(absl::string_view s)128 inline void QUIC_TRACESTRING(absl::string_view s) {
129   QuicConnectionContext* current = QuicConnectionContext::Current();
130   if (current && current->tracer) {
131     current->tracer->PrintString(s);
132   }
133 }
134 
135 // Emit a trace message from printf-style arguments to the current tracer(if
136 // any).
137 template <typename... Args>
QUIC_TRACEPRINTF(const absl::FormatSpec<Args...> & format,const Args &...args)138 void QUIC_TRACEPRINTF(const absl::FormatSpec<Args...>& format,
139                       const Args&... args) {
140   QuicConnectionContext* current = QuicConnectionContext::Current();
141   if (current && current->tracer) {
142     current->tracer->Printf(format, args...);
143   }
144 }
145 
CurrentBugListener()146 inline QuicBugListener* CurrentBugListener() {
147   QuicConnectionContext* current = QuicConnectionContext::Current();
148   return (current != nullptr) ? current->bug_listener.get() : nullptr;
149 }
150 
151 }  // namespace quic
152 
153 #endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
154