MySQL 8.4.2
Source Code Documentation
statement_reader.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018, 2024, 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 MYSQLD_MOCK_STATEMENT_READER_INCLUDED
27#define MYSQLD_MOCK_STATEMENT_READER_INCLUDED
28
29#include <chrono>
30#include <memory>
31#include <optional>
32#include <string>
33#include <utility>
34#include <variant>
35#include <vector>
36
37#include <openssl/bio.h>
38
47
48#include "authentication.h"
55
56namespace server_mock {
57
58/** @brief Vector for keeping has_value|string representation of the values
59 * of the single row (ordered by column)
60 **/
61using RowValueType = std::vector<std::optional<std::string>>;
62
70
71std::string encode_session_trackers(
72 const std::vector<session_tracker_field> &trackers);
73
74/** @brief Keeps result data for single SQL statement that returns
75 * resultset.
76 **/
78 std::vector<classic_protocol::message::server::ColumnMeta> columns;
79 std::vector<RowValueType> rows;
80
82};
83
86
88 // how many milliseconds after the client connects this Notice
89 // should be sent to the client
90 std::chrono::milliseconds send_offset_ms;
91 unsigned type;
92 bool is_local; // true = local, false = global
93 std::string payload;
94};
95
97 public:
101
102 ProtocolBase(socket_type client_sock, endpoint_type client_ep,
103 TlsServerContext &tls_ctx);
104
105 ProtocolBase(const ProtocolBase &) = delete;
107
110
111 virtual ~ProtocolBase() = default;
112
113 // throws std::system_error
114 virtual void encode_error(const ErrorResponse &resp) = 0;
115
116 // throws std::system_error
117 virtual void encode_ok(const OkResponse &resp) = 0;
118
119 // throws std::system_error
120 virtual void encode_resultset(const ResultsetResponse &response) = 0;
121
123 const net::mutable_buffer &buf);
124
126 const net::const_buffer &buf);
127
129
130 template <class CompletionToken>
131 void async_send_tls(CompletionToken &&token) {
132 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
133 token};
134
135 const auto write_res = write_ssl(net::buffer(send_buffer_));
136 if (!write_res) {
137 auto write_ec = write_res.error();
138
139 if (write_ec == TlsErrc::kWantRead || write_ec == TlsErrc::kWantWrite) {
140 client_socket_.async_wait(
143 [this, compl_handler = std::move(init.completion_handler)](
144 std::error_code ec) mutable {
145 if (ec) {
146 compl_handler(ec, {});
147 return;
148 }
149
150 async_send(std::move(compl_handler));
151 });
152 } else {
153 net::defer(client_socket_.get_executor(),
154 [compl_handler = std::move(init.completion_handler),
155 ec = write_res.error()]() { compl_handler(ec, {}); });
156 }
157 } else {
158 net::dynamic_buffer(send_buffer_).consume(write_res.value());
159
160 net::defer(client_socket_.get_executor(),
161 [compl_handler = std::move(init.completion_handler),
162 transferred = write_res.value()]() {
163 compl_handler({}, transferred);
164 });
165 }
166
167 return init.result.get();
168 }
169
170 template <class CompletionToken>
171 void async_send(CompletionToken &&token) {
172 if (is_tls()) {
173 async_send_tls(std::forward<CompletionToken>(token));
174 } else {
175 net::async_write(client_socket_, net::dynamic_buffer(send_buffer_),
176 std::forward<CompletionToken>(token));
177 }
178 }
179
180 // TlsErrc to net::stream_errc if needed.
181 static std::error_code map_tls_error_code(std::error_code ec) {
182 return (ec == TlsErrc::kZeroReturn) ? net::stream_errc::eof : ec;
183 }
184
185 template <class CompletionToken>
186 void async_receive_tls(CompletionToken &&token) {
187 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
188 token};
189
190 auto buf = net::dynamic_buffer(recv_buffer_);
191
192 auto orig_size = buf.size();
193 auto grow_size = 16 * 1024;
194
195 buf.grow(grow_size);
196 size_t transferred{};
197 auto read_res = read_ssl(buf.data(orig_size, grow_size));
198 if (read_res) {
199 transferred = read_res.value();
200 }
201
202 buf.shrink(grow_size - transferred);
203
204 if (!read_res) {
205 const auto read_ec = read_res.error();
206 if (read_ec == TlsErrc::kWantRead || read_ec == TlsErrc::kWantWrite) {
207 client_socket_.async_wait(
210 [this, compl_handler = std::move(init.completion_handler)](
211 std::error_code ec) mutable {
212 if (ec) {
213 compl_handler(ec, {});
214 return;
215 }
216
217 async_receive_tls(std::move(compl_handler));
218 });
219 } else {
220 // as we can't handle the error, forward the error to the
221 // completion handler
222
224 client_socket_.get_executor(),
225 [compl_handler = std::move(init.completion_handler),
226 ec = map_tls_error_code(read_ec)]() { compl_handler(ec, {}); });
227 }
228 } else {
229 // success, forward it to the completion handler
230 net::defer(client_socket_.get_executor(),
231 [compl_handler = std::move(init.completion_handler),
232 transferred]() { compl_handler({}, transferred); });
233 }
234
235 return init.result.get();
236 }
237
238 template <class CompletionToken>
239 void async_receive(CompletionToken &&token) {
240 is_terminated_([&](const bool killed) {
241 if (killed) {
242 net::async_completion<CompletionToken, void(std::error_code, size_t)>
243 init{token};
244
245 net::defer(client_socket_.get_executor(),
246 [compl_handler = std::move(init.completion_handler)]() {
247 compl_handler(
248 make_error_code(std::errc::operation_canceled), 0);
249 });
250 } else if (is_tls()) {
251 return async_receive_tls(std::forward<CompletionToken>(token));
252 } else {
253 return net::async_read(client_socket_,
254 net::dynamic_buffer(recv_buffer_),
255 std::forward<CompletionToken>(token));
256 }
257 });
258 }
259
260 template <class CompletionToken>
261 void async_tls_accept(CompletionToken &&token) {
262 net::async_completion<CompletionToken, void(std::error_code)> init{token};
263
264 // data may already be pending
265 auto res = tls_accept();
266 if (!res) {
267 auto ec = res.error();
268 if (ec == TlsErrc::kWantRead || ec == TlsErrc::kWantWrite) {
271
272 client_socket_.async_wait(
273 wt, [&, compl_handler = std::move(init.completion_handler)](
274 std::error_code ec) mutable {
275 if (ec) {
276 compl_handler(ec);
277 return;
278 }
279
280 // call async accept again.
281 async_tls_accept(std::move(compl_handler));
282 });
283 } else {
284 net::defer(client_socket_.get_executor().context(),
285 [ec, compl_handler = std::move(init.completion_handler)]() {
286 compl_handler(ec);
287 });
288 }
289 } else {
290 net::defer(client_socket_.get_executor().context(),
291 [compl_handler = std::move(init.completion_handler)]() {
292 compl_handler({});
293 });
294 }
295
296 return init.result.get();
297 }
298
299 const std::vector<uint8_t> &send_buffer() const { return send_buffer_; }
300
301 const net::ip::tcp::socket &client_socket() const { return client_socket_; }
302
303 void username(const std::string &username) { username_ = username; }
304
305 std::string username() const { return username_; }
306
307 void auth_method_name(const std::string &auth_method_name) {
308 auth_method_name_ = auth_method_name;
309 }
310
311 std::string auth_method_name() const { return auth_method_name_; }
312
313 void auth_method_data(const std::string &auth_method_data) {
314 auth_method_data_ = auth_method_data;
315 }
316
317 std::string auth_method_data() const { return auth_method_data_; }
318
319 static bool authenticate(const std::string &auth_method_name,
320 const std::string &auth_method_data,
321 const std::string &password,
322 const std::vector<uint8_t> &auth_response);
323
324 void init_tls();
325
326 bool is_tls() { return bool(ssl_); }
327
328 const SSL *ssl() const { return ssl_.get(); }
329
331
332 net::steady_timer &exec_timer() { return exec_timer_; }
333
334 void cancel();
335
336 /**
337 * terminate the current connection.
338 *
339 * sets is_terminated(true) and cancels the current operation.
340 *
341 * may be called from another thread.
342 */
343 void terminate();
344
346 return client_socket_.get_executor().context();
347 }
348
349 private:
350 Monitor<bool> is_terminated_{false};
351
352 protected:
355 net::steady_timer exec_timer_{io_context()};
356
357 std::string username_{};
358 std::string auth_method_name_{};
359 std::string auth_method_data_{};
360
362
364 public:
365 void operator()(SSL *v) { SSL_free(v); }
366 };
367
368 std::unique_ptr<SSL, SSL_Deleter> ssl_;
369
370 std::vector<uint8_t> recv_buffer_;
371 std::vector<uint8_t> send_buffer_;
372};
373
375 public:
378
379 std::optional<std::string> username;
380 std::optional<std::string> password;
381 bool cert_required{false};
382 std::optional<std::string> cert_subject;
383 std::optional<std::string> cert_issuer;
384
385 std::chrono::microseconds exec_time;
386 };
387
389
392
395
396 virtual ~StatementReaderBase() = default;
397
398 /** @brief Returns the data about the next statement from the
399 * json file. If there is no more statements it returns
400 * empty statement.
401 **/
402 virtual void handle_statement(const std::string &statement,
403 ProtocolBase *protocol) = 0;
404
405 /** @brief Returns the default execution time in microseconds. If
406 * no default execution time is provided in json file, then
407 * 0 microseconds is returned.
408 **/
409 virtual std::chrono::microseconds get_default_exec_time() = 0;
410
411 virtual std::vector<AsyncNotice> get_async_notices() = 0;
412
414 bool is_greeting) = 0;
415
416 virtual void set_session_ssl_info(const SSL *ssl) = 0;
417};
418
419} // namespace server_mock
420
421#endif
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:571
Monitor pattern.
Definition: monitor.h:39
TLS Context for the server side.
Definition: tls_server_context.h:51
gtid changed.
Definition: classic_protocol_session_track.h:146
Definition: executor.h:72
Definition: socket.h:1090
Definition: timer.h:57
Definition: buffer.h:135
io_context & context() const noexcept
Definition: io_context.h:1003
Definition: io_context.h:61
executor_type get_executor() noexcept
Definition: io_context.h:1081
TCP protocol.
Definition: internet.h:1155
basic_endpoint< tcp > endpoint
Definition: internet.h:1157
basic_stream_socket< tcp > socket
Definition: internet.h:1159
Definition: buffer.h:113
static constexpr wait_type wait_read
Definition: socket.h:168
static constexpr wait_type wait_write
Definition: socket.h:169
Definition: statement_reader.h:363
void operator()(SSL *v)
Definition: statement_reader.h:365
Definition: statement_reader.h:96
std::string username() const
Definition: statement_reader.h:305
virtual ~ProtocolBase()=default
ProtocolBase(ProtocolBase &&)=delete
net::steady_timer & exec_timer()
Definition: statement_reader.h:332
TlsServerContext & tls_ctx_
Definition: statement_reader.h:361
ProtocolBase(socket_type client_sock, endpoint_type client_ep, TlsServerContext &tls_ctx)
Definition: protocol_base.cc:36
stdx::expected< size_t, std::error_code > avail_ssl()
Definition: protocol_base.cc:73
const std::vector< uint8_t > & send_buffer() const
Definition: statement_reader.h:299
void async_send_tls(CompletionToken &&token)
Definition: statement_reader.h:131
socket_type client_socket_
Definition: statement_reader.h:353
const SSL * ssl() const
Definition: statement_reader.h:328
ProtocolBase & operator=(ProtocolBase &&rhs)=delete
std::string auth_method_data() const
Definition: statement_reader.h:317
void auth_method_name(const std::string &auth_method_name)
Definition: statement_reader.h:307
void async_tls_accept(CompletionToken &&token)
Definition: statement_reader.h:261
virtual void encode_resultset(const ResultsetResponse &response)=0
endpoint_type client_ep_
Definition: statement_reader.h:354
std::vector< uint8_t > recv_buffer_
Definition: statement_reader.h:370
const net::ip::tcp::socket & client_socket() const
Definition: statement_reader.h:301
void async_receive_tls(CompletionToken &&token)
Definition: statement_reader.h:186
void auth_method_data(const std::string &auth_method_data)
Definition: statement_reader.h:313
bool is_tls()
Definition: statement_reader.h:326
void async_receive(CompletionToken &&token)
Definition: statement_reader.h:239
typename protocol_type::endpoint endpoint_type
Definition: statement_reader.h:100
void async_send(CompletionToken &&token)
Definition: statement_reader.h:171
std::string auth_method_name() const
Definition: statement_reader.h:311
virtual void encode_error(const ErrorResponse &resp)=0
stdx::expected< size_t, std::error_code > read_ssl(const net::mutable_buffer &buf)
Definition: protocol_base.cc:59
static std::error_code map_tls_error_code(std::error_code ec)
Definition: statement_reader.h:181
void username(const std::string &username)
Definition: statement_reader.h:303
ProtocolBase & operator=(const ProtocolBase &)=delete
virtual void encode_ok(const OkResponse &resp)=0
typename protocol_type::socket socket_type
Definition: statement_reader.h:99
stdx::expected< size_t, std::error_code > write_ssl(const net::const_buffer &buf)
Definition: protocol_base.cc:48
std::vector< uint8_t > send_buffer_
Definition: statement_reader.h:371
net::io_context & io_context()
Definition: statement_reader.h:345
ProtocolBase(const ProtocolBase &)=delete
std::unique_ptr< SSL, SSL_Deleter > ssl_
Definition: statement_reader.h:368
Definition: statement_reader.h:374
StatementReaderBase & operator=(StatementReaderBase &&)=default
virtual std::vector< AsyncNotice > get_async_notices()=0
virtual stdx::expected< handshake_data, ErrorResponse > handshake(bool is_greeting)=0
StatementReaderBase(StatementReaderBase &&)=default
virtual ~StatementReaderBase()=default
virtual void set_session_ssl_info(const SSL *ssl)=0
virtual void handle_statement(const std::string &statement, ProtocolBase *protocol)=0
Returns the data about the next statement from the json file.
StatementReaderBase & operator=(const StatementReaderBase &)=default
StatementReaderBase(const StatementReaderBase &)=default
virtual std::chrono::microseconds get_default_exec_time()=0
Returns the default execution time in microseconds.
static char * password
Definition: mysql_secure_installation.cc:58
Definition: buf0block_hint.cc:30
constexpr value_type ssl
Definition: classic_protocol_constants.h:49
borrowable::message::server::Error< false > Error
Definition: classic_protocol_message.h:1411
borrowable::message::server::Greeting< false > Greeting
Definition: classic_protocol_message.h:1413
borrowable::message::server::Eof< false > Eof
Definition: classic_protocol_message.h:1412
borrowable::message::server::Ok< false > Ok
Definition: classic_protocol_message.h:1410
borrowable::session_track::TransactionCharacteristics< false > TransactionCharacteristics
Definition: classic_protocol_session_track.h:297
borrowable::session_track::TransactionState TransactionState
Definition: classic_protocol_session_track.h:298
borrowable::session_track::SystemVariable< false > SystemVariable
Definition: classic_protocol_session_track.h:299
borrowable::session_track::State State
Definition: classic_protocol_session_track.h:301
borrowable::session_track::Schema< false > Schema
Definition: classic_protocol_session_track.h:300
dynamic_vector_buffer< T, Allocator > dynamic_buffer(std::vector< T, Allocator > &vec) noexcept
Definition: buffer.h:661
auto defer(CompletionToken &&token)
Definition: executor.h:787
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
std::enable_if_t< is_dynamic_buffer< DynamicBuffer >::value, void > async_read(AsyncReadStream &stream, DynamicBuffer &&b, CompletionCondition completion_condition, CompletionToken &&token)
Definition: buffer.h:928
std::enable_if_t< is_const_buffer_sequence_v< ConstBufferSequence >, void > async_write(AsyncWriteStream &stream, const ConstBufferSequence &buffers, CompletionCondition cond, CompletionToken &&token)
Definition: buffer.h:1075
Definition: mock_server_component.h:36
std::variant< classic_protocol::session_track::TransactionCharacteristics, classic_protocol::session_track::TransactionState, classic_protocol::session_track::SystemVariable, classic_protocol::session_track::Schema, classic_protocol::session_track::State, classic_protocol::session_track::Gtid > session_tracker_field
Definition: statement_reader.h:69
classic_protocol::message::server::Ok OkResponse
Definition: statement_reader.h:84
std::vector< std::optional< std::string > > RowValueType
Vector for keeping has_value|string representation of the values of the single row (ordered by column...
Definition: statement_reader.h:61
classic_protocol::message::server::Error ErrorResponse
Definition: statement_reader.h:85
std::string encode_session_trackers(const std::vector< session_tracker_field > &trackers)
Definition: duktape_statement_reader.cc:91
Definition: statement_reader.h:87
std::chrono::milliseconds send_offset_ms
Definition: statement_reader.h:90
bool is_local
Definition: statement_reader.h:92
std::string payload
Definition: statement_reader.h:93
unsigned type
Definition: statement_reader.h:91
Keeps result data for single SQL statement that returns resultset.
Definition: statement_reader.h:77
std::vector< RowValueType > rows
Definition: statement_reader.h:79
classic_protocol::message::server::Eof end_of_rows
Definition: statement_reader.h:81
std::vector< classic_protocol::message::server::ColumnMeta > columns
Definition: statement_reader.h:78
Definition: statement_reader.h:376
std::optional< std::string > username
Definition: statement_reader.h:379
std::chrono::microseconds exec_time
Definition: statement_reader.h:385
classic_protocol::message::server::Greeting greeting
Definition: statement_reader.h:377
std::optional< std::string > cert_issuer
Definition: statement_reader.h:383
std::optional< std::string > password
Definition: statement_reader.h:380
std::optional< std::string > cert_subject
Definition: statement_reader.h:382
Definition: mysqlslap.cc:219