MySQL 9.4.0
Source Code Documentation
trace_stream.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2021, 2025, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef ROUTER_SRC_OPENSSL_INCLUDE_TLS_TRACE_STREAM_H_
27#define ROUTER_SRC_OPENSSL_INCLUDE_TLS_TRACE_STREAM_H_
28
29#include <algorithm>
30#include <functional>
31#include <iomanip>
32#include <mutex>
33#include <string>
34#include <utility>
35#include <vector>
36
38#ifndef USE_CUSTOM_HOLDER
40#endif // USE_CUSTOM_HOLDER
42
43// In future instead on defining output-stream methods here and a mutex to
44// access it, extract Console/terminal class.
46
47template <typename NameType, typename LowerLevelStream>
48class TraceStream : Mutex_static_holder<Trace_stream_static_holder> {
49 // Mutex_static_holder<Trace_stream_static_holder> - makes mutex static
50 // variable common for different instantiations of this template
51
52 public:
53 using native_handle_type = std::nullptr_t;
54 using protocol_type = std::nullptr_t;
55 using endpoint_type = typename LowerLevelStream::endpoint_type;
56 using VectorOfBuffers = std::vector<net::mutable_buffer>;
57 using VectorOfConstBuffers = std::vector<net::const_buffer>;
58
59 public:
63 lower_layer_{std::move(other.lower_layer_)},
64 out_{other.out_} {
65 print("ctor move");
66 }
67
68 template <typename... Args>
69 TraceStream(Args &&...args) // NOLINT(runtime/explicit)
70 : lower_layer_{std::forward<Args>(args)...}, out_{NameType::get_out()} {
71 print("ctor");
72 }
73
74 auto get_executor() { return lower_layer_.get_executor(); }
75
76 LowerLevelStream &lower_layer() { return lower_layer_; }
77 const LowerLevelStream &lower_layer() const { return lower_layer_; }
78
79 template <class MutableBufferSequence>
81 const MutableBufferSequence &buffers) {
82 return lower_layer_.read_some(buffers);
83 }
84
85 template <class ConstBufferSequence>
87 const ConstBufferSequence &buffers) {
88 return lower_layer_.write_some(buffers);
89 }
90
91 template <typename Buffer, typename Handler>
92 void async_send(const Buffer &buffer, Handler &&handler) {
94 print("async_send buffer-size: ", net::buffer_size(buffer));
97 }
98
99 template <class HandshakeType, class CompletionToken>
100 auto async_handshake(HandshakeType type, CompletionToken &&token) {
101 print("async_handshake type: ", type);
103 lower_layer_.async_handshake(type, get_handshake_handler(ref, token));
104 }
105
106 template <typename Buffer, typename Handler>
107 void async_receive(const Buffer &buffer, Handler &&handler) {
109 print("async_receive buffer-size: ", net::buffer_size(buffer));
112 }
113
114 void set_parent(const char *parent) { parent_ = parent; }
115
116 auto cancel() {
117 print("cancel");
118 return lower_layer_.cancel();
119 }
120
122 print("shutdown");
123 lower_layer_.shutdown(s);
124 }
125
126 auto close() {
127 print("close");
128 return lower_layer_.close();
129 }
130
131 void handle_read(std::error_code ec, size_t size) {
132 print("handle_read error:", ec, ", size:", size);
133
135 }
136
137 void handle_write(std::error_code ec, size_t size) {
138 print("handle_write error:", ec, ", size:", size);
139
141 }
142
143 void handle_handshake(std::error_code ec, size_t size) {
144 print("handle_handshake error:", ec, ", size:", size);
145 }
146
147 template <typename SettableSocketOption>
149 const SettableSocketOption &option) {
150 return lower_layer_.set_option(option);
151 }
152
153 template <typename... Args>
154 void print(const Args &...args) {
155 std::unique_lock<std::mutex> l{mutex_};
156 *out_ << "this:" << parent_ << ", thread:" << std::this_thread::get_id()
157 << ", " << NameType::get_name() << ": ";
158 print_single(args...);
159 *out_ << std::endl;
160 out_->flush();
161 }
162
163 protected:
165 public:
166 WrappedTraceStream(TraceStream *parent = nullptr) : parent_{parent} {}
168 : parent_{other.parent_} {}
170
171 void handle_read(std::error_code ec, size_t size) {
172 if (parent_) parent_->handle_read(ec, size);
173 }
174
175 void handle_write(std::error_code ec, size_t size) {
176 if (parent_) parent_->handle_write(ec, size);
177 }
178
179 void handle_handshake(std::error_code ec, size_t size) {
181 }
182
183 private:
185 };
186
187 template <typename Vector>
188 void dump(Vector &data, size_t s) {
189 std::unique_lock<std::mutex> l{mutex_};
190 auto it = data.begin();
191 size_t offset = 0;
192
193 while (it != data.end() && s) {
194 auto data_on_page = std::min(s, it->size());
195 const char *data_ptr = (const char *)it->data();
196 auto to_print = data_on_page;
197
198 while (to_print) {
199 auto line = std::min(to_print, 16UL);
200 *out_ << "this:" << parent_ << " " << std::hex << std::setfill('0')
201 << std::setw(8) << offset << " | ";
202 for (size_t i = 0; i < line; ++i) {
203 *out_ << " 0x" << std::setw(2) << (int)((const uint8_t *)data_ptr)[i];
204 }
205
206 *out_ << std::string((16 - line) * 5, ' ');
207
208 *out_ << " - ";
209 for (size_t i = 0; i < line; ++i) {
210 *out_ << (iscntrl(data_ptr[i]) ? '?' : data_ptr[i]);
211 }
212
213 *out_ << std::dec << std::setw(1) << std::endl;
214
215 to_print -= line;
216 data_ptr += line;
217 s -= line;
218 offset += line;
219 }
220 }
221
222 out_->flush();
223 }
224
225 template <typename Vector, typename SrcBuffers>
226 void copy(Vector &dst, const SrcBuffers &src) {
227 dst.resize(0);
228 auto it = net::buffer_sequence_begin(src);
229 auto end = net::buffer_sequence_end(src);
230 while (it != end) {
231 dst.emplace_back(it->data(), it->size());
232 ++it;
233 }
234 }
235
236 void print_single() {}
237
238 template <typename Arg, typename... Args>
239 void print_single(const Arg &arg, const Args... args) {
240 *out_ << arg;
241 print_single(args...);
242 }
243
244 template <typename WriteToken, typename StandardToken>
246 get_write_handler(WriteToken &write_token, StandardToken &std_token) {
247 using Write_token_result = std::decay_t<WriteToken>;
248 using Write_token_handler =
250 Write_token_result &, Write_token_result>;
251
252 using Standard_token_result = std::decay_t<StandardToken>;
253 using Standard_token_handler = std::conditional_t<
255 Standard_token_result &, Standard_token_result>;
256
258 std::forward<Write_token_handler>(write_token),
259 std::forward<Standard_token_handler>(std_token));
260 }
261
262 template <typename ReadToken, typename StandardToken>
264 get_read_handler(ReadToken &read_token, StandardToken &std_token) {
265 using Read_token_result = std::decay_t<ReadToken>;
266 using Read_token_handler =
268 Read_token_result &, Read_token_result>;
269
270 using Standard_token_result = std::decay_t<StandardToken>;
271 using Standard_token_handler = std::conditional_t<
273 Standard_token_result &, Standard_token_result>;
275 std::forward<Read_token_handler>(read_token),
276 std::forward<Standard_token_handler>(std_token));
277 }
278
279 template <typename HandshakeToken, typename StandardToken>
281 get_handshake_handler(HandshakeToken &handshake_token,
282 StandardToken &std_token) {
283 using Handshake_token_result = std::decay_t<HandshakeToken>;
284 using Handshake_token_handler = std::conditional_t<
286 Handshake_token_result &, Handshake_token_result>;
287
288 using Standard_token_result = std::decay_t<StandardToken>;
289 using Standard_token_handler = std::conditional_t<
291 Standard_token_result &, Standard_token_result>;
293 StandardToken>(
294 std::forward<Handshake_token_handler>(handshake_token),
295 std::forward<Standard_token_handler>(std_token));
296 }
297
300 LowerLevelStream lower_layer_;
301 std::ostream *out_;
302 std::string parent_;
303};
304
305template <typename NameType, typename LowerLevelStream>
306class TlsTraceStream : public TraceStream<NameType, LowerLevelStream> {
307 public:
309 using This::TraceStream;
310 using LowerLayerType = typename LowerLevelStream::LowerLayerType;
311
312 LowerLayerType &lower_layer() { return this->lower_layer_.lower_layer(); }
314 return this->lower_layer_.lower_layer();
315 }
316};
317
318#endif // ROUTER_SRC_OPENSSL_INCLUDE_TLS_TRACE_STREAM_H_
Definition: trace_stream.h:306
const LowerLayerType & lower_layer() const
Definition: trace_stream.h:313
typename LowerLevelStream::LowerLayerType LowerLayerType
Definition: trace_stream.h:310
LowerLayerType & lower_layer()
Definition: trace_stream.h:312
Definition: trace_stream.h:164
void handle_write(std::error_code ec, size_t size)
Definition: trace_stream.h:175
WrappedTraceStream(TraceStream *parent=nullptr)
Definition: trace_stream.h:166
WrappedTraceStream(const WrappedTraceStream &other)
Definition: trace_stream.h:167
void handle_handshake(std::error_code ec, size_t size)
Definition: trace_stream.h:179
WrappedTraceStream(WrappedTraceStream &&other)
Definition: trace_stream.h:169
void handle_read(std::error_code ec, size_t size)
Definition: trace_stream.h:171
TraceStream * parent_
Definition: trace_stream.h:184
Definition: trace_stream.h:48
auto cancel()
Definition: trace_stream.h:116
typename LowerLevelStream::endpoint_type endpoint_type
Definition: trace_stream.h:55
VectorOfConstBuffers send_buffer_
Definition: trace_stream.h:299
auto async_handshake(HandshakeType type, CompletionToken &&token)
Definition: trace_stream.h:100
void shutdown(net::socket_base::shutdown_type s)
Definition: trace_stream.h:121
const LowerLevelStream & lower_layer() const
Definition: trace_stream.h:77
void handle_read(std::error_code ec, size_t size)
Definition: trace_stream.h:131
net::tls::LowerLayerWriteCompletionToken< WriteToken, StandardToken > get_write_handler(WriteToken &write_token, StandardToken &std_token)
Definition: trace_stream.h:246
void async_receive(const Buffer &buffer, Handler &&handler)
Definition: trace_stream.h:107
void handle_write(std::error_code ec, size_t size)
Definition: trace_stream.h:137
void copy(Vector &dst, const SrcBuffers &src)
Definition: trace_stream.h:226
std::vector< net::const_buffer > VectorOfConstBuffers
Definition: trace_stream.h:57
net::tls::LowerLayerHandshakeCompletionToken< HandshakeToken, StandardToken > get_handshake_handler(HandshakeToken &handshake_token, StandardToken &std_token)
Definition: trace_stream.h:281
std::nullptr_t protocol_type
Definition: trace_stream.h:54
net::tls::LowerLayerReadCompletionToken< ReadToken, StandardToken > get_read_handler(ReadToken &read_token, StandardToken &std_token)
Definition: trace_stream.h:264
void print_single()
Definition: trace_stream.h:236
stdx::expected< void, std::error_code > set_option(const SettableSocketOption &option)
Definition: trace_stream.h:148
TraceStream(TraceStream &&other)
Definition: trace_stream.h:60
TraceStream(Args &&...args)
Definition: trace_stream.h:69
std::ostream * out_
Definition: trace_stream.h:301
stdx::expected< size_t, std::error_code > write_some(const ConstBufferSequence &buffers)
Definition: trace_stream.h:86
std::vector< net::mutable_buffer > VectorOfBuffers
Definition: trace_stream.h:56
void set_parent(const char *parent)
Definition: trace_stream.h:114
void print(const Args &...args)
Definition: trace_stream.h:154
VectorOfBuffers recv_buffer_
Definition: trace_stream.h:298
auto get_executor()
Definition: trace_stream.h:74
std::nullptr_t native_handle_type
Definition: trace_stream.h:53
LowerLevelStream & lower_layer()
Definition: trace_stream.h:76
void handle_handshake(std::error_code ec, size_t size)
Definition: trace_stream.h:143
void async_send(const Buffer &buffer, Handler &&handler)
Definition: trace_stream.h:92
std::string parent_
Definition: trace_stream.h:302
LowerLevelStream lower_layer_
Definition: trace_stream.h:300
stdx::expected< size_t, std::error_code > read_some(const MutableBufferSequence &buffers)
Definition: trace_stream.h:80
void dump(Vector &data, size_t s)
Definition: trace_stream.h:188
void print_single(const Arg &arg, const Args... args)
Definition: trace_stream.h:239
auto close()
Definition: trace_stream.h:126
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4666
shutdown_type
Definition: socket.h:172
Definition: lower_layer_completion.h:115
Definition: lower_layer_completion.h:40
Definition: lower_layer_completion.h:77
static const std::string dec("DECRYPTION")
PT & ref(PT *tp)
Definition: tablespace_impl.cc:359
std::string hex(const Container &c)
Definition: hex.h:61
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
size_t size(const char *const c)
Definition: base64.h:46
HandshakeType
Definition: tls_stream.h:44
const const_buffer * buffer_sequence_end(const const_buffer &b) noexcept
Definition: buffer.h:185
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
const const_buffer * buffer_sequence_begin(const const_buffer &b) noexcept
Definition: buffer.h:180
size_t buffer_size(const ConstBufferSequence &buffers) noexcept
Definition: buffer.h:313
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:192
Definition: gcs_xcom_synode.h:64
pid_type get_id()
Definition: process.h:48
required string type
Definition: replication_group_member_actions.proto:34
uint read_token(const sql_digest_storage *digest_storage, uint index, uint *tok)
Read a single token from token array.
Definition: sql_digest.cc:56
Definition: mutex_static_holder.h:32
static std::mutex mutex_
Definition: mutex_static_holder.h:33
Definition: trace_stream.h:45