1 /*
2  * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #ifndef OSSL_QLOG_H
11 # define OSSL_QLOG_H
12 
13 # include <openssl/ssl.h>
14 # include <stdbool.h>
15 # include "internal/quic_types.h"
16 # include "internal/time.h"
17 
18 typedef struct qlog_st QLOG;
19 
20 # ifndef OPENSSL_NO_QLOG
21 
22 enum {
23     QLOG_EVENT_TYPE_NONE,
24 
25 #  define QLOG_EVENT(cat, name) QLOG_EVENT_TYPE_##cat##_##name,
26 #  include "internal/qlog_events.h"
27 #  undef QLOG_EVENT
28 
29     QLOG_EVENT_TYPE_NUM
30 };
31 
32 typedef struct qlog_trace_info_st {
33     QUIC_CONN_ID    odcid;
34     const char      *title, *description, *group_id;
35     int             is_server;
36     OSSL_TIME       (*now_cb)(void *arg);
37     void            *now_cb_arg;
38     uint64_t        override_process_id;
39     const char      *override_impl_name;
40 } QLOG_TRACE_INFO;
41 
42 QLOG *ossl_qlog_new(const QLOG_TRACE_INFO *info);
43 QLOG *ossl_qlog_new_from_env(const QLOG_TRACE_INFO *info);
44 
45 void ossl_qlog_free(QLOG *qlog);
46 
47 /* Configuration */
48 int ossl_qlog_set_event_type_enabled(QLOG *qlog, uint32_t event_type,
49                                      int enable);
50 int ossl_qlog_set_filter(QLOG *qlog, const char *filter);
51 
52 int ossl_qlog_set_sink_bio(QLOG *qlog, BIO *bio);
53 #  ifndef OPENSSL_NO_STDIO
54 int ossl_qlog_set_sink_file(QLOG *qlog, FILE *file, int close_flag);
55 #  endif
56 int ossl_qlog_set_sink_filename(QLOG *qlog, const char *filename);
57 
58 /* Operations */
59 int ossl_qlog_flush(QLOG *qlog);
60 
61 /* Queries */
62 int ossl_qlog_enabled(QLOG *qlog, uint32_t event_type);
63 
64 /* Grouping Functions */
65 int ossl_qlog_event_try_begin(QLOG *qlog, uint32_t event_type,
66                               const char *event_cat, const char *event_name,
67                               const char *event_combined_name);
68 void ossl_qlog_event_end(QLOG *qlog);
69 
70 void ossl_qlog_group_begin(QLOG *qlog, const char *name);
71 void ossl_qlog_group_end(QLOG *qlog);
72 
73 void ossl_qlog_array_begin(QLOG *qlog, const char *name);
74 void ossl_qlog_array_end(QLOG *qlog);
75 
76 void ossl_qlog_override_time(QLOG *qlog, OSSL_TIME event_time);
77 
78 /* Grouping Macros */
79 #  define QLOG_EVENT_BEGIN(qlog, cat, name)                                 \
80     {                                                                       \
81         QLOG *qlog_instance = (qlog);                                       \
82         uint32_t qlog_event_type = QLOG_EVENT_TYPE_##cat##_##name;          \
83                                                                             \
84         if (ossl_qlog_event_try_begin(qlog_instance, qlog_event_type,       \
85                                       #cat, #name, #cat ":" #name)) {
86 
87 #  define QLOG_EVENT_END()                                                  \
88             ossl_qlog_event_end(qlog_instance);                             \
89         }                                                                   \
90     }
91 
92 #  define QLOG_BEGIN(name)                                                  \
93     {                                                                       \
94         ossl_qlog_group_begin(qlog_instance, (name));
95 
96 #  define QLOG_END()                                                        \
97         ossl_qlog_group_end(qlog_instance);                                 \
98     }
99 
100 #  define QLOG_BEGIN_ARRAY(name)                                            \
101     {                                                                       \
102         ossl_qlog_array_begin(qlog_instance, (name));
103 
104 #  define QLOG_END_ARRAY()                                                  \
105         ossl_qlog_array_end(qlog_instance);                                 \
106     }
107 
108 /* Field Functions */
109 void ossl_qlog_str(QLOG *qlog, const char *name, const char *value);
110 void ossl_qlog_str_len(QLOG *qlog, const char *name,
111                        const char *value, size_t value_len);
112 void ossl_qlog_u64(QLOG *qlog, const char *name, uint64_t value);
113 void ossl_qlog_i64(QLOG *qlog, const char *name, int64_t value);
114 void ossl_qlog_bool(QLOG *qlog, const char *name, bool value);
115 void ossl_qlog_bin(QLOG *qlog, const char *name,
116                    const void *value, size_t value_len);
117 
118 /* Field Macros */
119 #  define QLOG_STR(name, value)   ossl_qlog_str(qlog_instance, (name), (value))
120 #  define QLOG_STR_LEN(name, value, value_len)                                \
121     ossl_qlog_str_len(qlog_instance, (name), (value), (value_len))
122 #  define QLOG_I64(name, value)   ossl_qlog_i64(qlog_instance, (name), (value))
123 #  define QLOG_U64(name, value)   ossl_qlog_u64(qlog_instance, (name), (value))
124 #  define QLOG_F64(name, value)   ossl_qlog_f64(qlog_instance, (name), (value))
125 #  define QLOG_BOOL(name, value)  ossl_qlog_bool(qlog_instance, (name), (value))
126 #  define QLOG_BIN(name, value, value_len) \
127     ossl_qlog_bin(qlog_instance, (name), (value), (value_len))
128 #  define QLOG_CID(name, value) QLOG_BIN((name), (value)->id, (value)->id_len)
129 
130 # endif
131 
132 #endif
133