MySQL 9.2.0
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 <cassert>
30#include <chrono>
31#include <memory>
32#include <optional>
33#include <string>
34#include <utility>
35#include <variant>
36#include <vector>
37
38#include <openssl/bio.h>
39
54
55namespace server_mock {
56
57/** @brief Vector for keeping has_value|string representation of the values
58 * of the single row (ordered by column)
59 **/
60using RowValueType = std::vector<std::optional<std::string>>;
61
69
70std::string encode_session_trackers(
71 const std::vector<session_tracker_field> &trackers);
72
73/** @brief Keeps result data for single SQL statement that returns
74 * resultset.
75 **/
77 std::vector<classic_protocol::message::server::ColumnMeta> columns;
78 std::vector<RowValueType> rows;
79
81};
82
85
87 // how many milliseconds after the client connects this Notice
88 // should be sent to the client
89 std::chrono::milliseconds send_offset_ms;
90 unsigned type;
91 bool is_local; // true = local, false = global
92 std::string payload;
93};
94
96 public:
99 TlsServerContext &tls_ctx)
100 : sock_(std::move(sock)), ep_(std::move(ep)), tls_ctx_(tls_ctx) {
101 // if it doesn't work, no problem.
102
103 assert(sock_.is_tcp() == ep.is_tcp());
104
105 if (sock_.is_tcp()) {
106 sock_.set_option(net::ip::tcp::no_delay{true});
107 }
109 }
110
112 const net::const_buffer &buf);
113
115 const net::mutable_buffer &buf);
116
118
120
122
123 template <class CompletionToken>
124 void async_send_tls(CompletionToken &&token) {
125 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
126 token};
127
128 const auto write_res = write_ssl(net::buffer(send_buffer_));
129 if (!write_res) {
130 auto write_ec = write_res.error();
131
132 if (write_ec == TlsErrc::kWantRead || write_ec == TlsErrc::kWantWrite) {
136 [this, compl_handler = std::move(init.completion_handler)](
137 std::error_code ec) mutable {
138 if (ec) {
139 compl_handler(ec, {});
140 return;
141 }
142
143 async_send(std::move(compl_handler));
144 });
145 } else {
147 [compl_handler = std::move(init.completion_handler),
148 ec = write_res.error()]() { compl_handler(ec, {}); });
149 }
150 } else {
151 net::dynamic_buffer(send_buffer_).consume(write_res.value());
152
153 net::defer(get_executor(),
154 [compl_handler = std::move(init.completion_handler),
155 transferred = write_res.value()]() {
156 compl_handler({}, transferred);
157 });
158 }
159
160 return init.result.get();
161 }
162
163 template <class CompletionToken>
164 void async_send(CompletionToken &&token) {
165 if (is_tls()) {
166 async_send_tls(std::forward<CompletionToken>(token));
167 } else {
168 sock_.async_send(net::dynamic_buffer(send_buffer_),
169 std::forward<CompletionToken>(token));
170 }
171 }
172
173 template <class CompletionToken>
174 void async_receive_tls(CompletionToken &&token) {
175 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
176 token};
177
178 auto buf = net::dynamic_buffer(recv_buffer_);
179
180 auto orig_size = buf.size();
181 auto grow_size = 16 * 1024;
182
183 buf.grow(grow_size);
184 size_t transferred{};
185 auto read_res = read_ssl(buf.data(orig_size, grow_size));
186 if (read_res) {
187 transferred = read_res.value();
188 }
189
190 buf.shrink(grow_size - transferred);
191
192 if (!read_res) {
193 const auto read_ec = read_res.error();
194 if (read_ec == TlsErrc::kWantRead || read_ec == TlsErrc::kWantWrite) {
195 sock_.async_wait(
198 [this, compl_handler = std::move(init.completion_handler)](
199 std::error_code ec) mutable {
200 if (ec) {
201 compl_handler(ec, {});
202 return;
203 }
204
205 async_receive_tls(std::move(compl_handler));
206 });
207 } else {
208 // as we can't handle the error, forward the error to the
209 // completion handler
210
212 get_executor(),
213 [compl_handler = std::move(init.completion_handler),
214 ec = map_tls_error_code(read_ec)]() { compl_handler(ec, {}); });
215 }
216 } else {
217 // success, forward it to the completion handler
218 net::defer(get_executor(),
219 [compl_handler = std::move(init.completion_handler),
220 transferred]() { compl_handler({}, transferred); });
221 }
222
223 return init.result.get();
224 }
225
226 template <class CompletionToken>
227 void async_receive(CompletionToken &&token) {
228 is_terminated_([&](const bool killed) {
229 if (killed) {
230 net::async_completion<CompletionToken, void(std::error_code, size_t)>
231 init{token};
232
233 net::defer(get_executor(), [compl_handler =
234 std::move(init.completion_handler)]() {
235 compl_handler(make_error_code(std::errc::operation_canceled), 0);
236 });
237 } else if (is_tls()) {
238 return async_receive_tls(std::forward<CompletionToken>(token));
239 } else {
240 return sock_.async_recv(net::dynamic_buffer(recv_buffer_),
241 std::forward<CompletionToken>(token));
242 }
243 });
244 }
245
246 template <class CompletionToken>
247 void async_tls_accept(CompletionToken &&token) {
248 net::async_completion<CompletionToken, void(std::error_code)> init{token};
249
250 // data may already be pending
251 auto res = tls_accept();
252 if (!res) {
253 auto ec = res.error();
254 if (ec == TlsErrc::kWantRead || ec == TlsErrc::kWantWrite) {
257
258 sock_.async_wait(
259 wt, [&, compl_handler = std::move(init.completion_handler)](
260 std::error_code ec) mutable {
261 if (ec) {
262 compl_handler(ec);
263 return;
264 }
265
266 // call async accept again.
267 async_tls_accept(std::move(compl_handler));
268 });
269 } else {
270 net::defer(get_executor(),
271 [ec, compl_handler = std::move(init.completion_handler)]() {
272 compl_handler(ec);
273 });
274 }
275 } else {
276 net::defer(get_executor(),
277 [compl_handler = std::move(init.completion_handler)]() {
278 compl_handler({});
279 });
280 }
281
282 return init.result.get();
283 }
284
285 bool is_tls() { return static_cast<bool>(ssl_); }
286
287 const SSL *ssl() const { return ssl_.get(); }
288
289 const std::vector<uint8_t> &send_buffer() const { return send_buffer_; }
290 std::vector<uint8_t> &send_buffer() { return send_buffer_; }
291
292 const std::vector<uint8_t> &recv_buffer() const { return recv_buffer_; }
293 std::vector<uint8_t> &recv_buffer() { return recv_buffer_; }
294
296
298 return sock_.native_handle();
299 }
300
301 void init_tls();
302
304
305 void terminate();
306
307 private:
308 // TlsErrc to net::stream_errc if needed.
309 static std::error_code map_tls_error_code(std::error_code ec) {
310 return (ec == TlsErrc::kZeroReturn) ? net::stream_errc::eof : ec;
311 }
312
313 Monitor<bool> is_terminated_{false};
314
317
318 std::vector<uint8_t> send_buffer_;
319 std::vector<uint8_t> recv_buffer_;
320
322 public:
323 void operator()(SSL *ssl) { SSL_free(ssl); }
324 };
325
326 std::unique_ptr<SSL, SSL_Deleter> ssl_;
327
329};
330
332 public:
335 TlsServerContext &tls_ctx)
336 : conn_(std::move(sock), std::move(ep), tls_ctx) {}
337
338 ProtocolBase(const ProtocolBase &) = delete;
340
343
344 virtual ~ProtocolBase() = default;
345
346 // throws std::system_error
347 virtual void encode_error(const ErrorResponse &resp) = 0;
348
349 // throws std::system_error
350 virtual void encode_ok(const OkResponse &resp) = 0;
351
352 // throws std::system_error
353 virtual void encode_resultset(const ResultsetResponse &response) = 0;
354
355 template <class CompletionToken>
356 void async_send_tls(CompletionToken &&token) {
357 return conn_.async_send_tls(std::forward<CompletionToken>(token));
358 }
359
360 template <class CompletionToken>
361 void async_send(CompletionToken &&token) {
362 return conn_.async_send(std::forward<CompletionToken>(token));
363 }
364
365 template <class CompletionToken>
366 void async_receive(CompletionToken &&token) {
367 return conn_.async_receive(std::forward<CompletionToken>(token));
368 }
369
370 const std::vector<uint8_t> &send_buffer() const {
371 return conn_.send_buffer();
372 }
373
374 std::vector<uint8_t> &send_buffer() { return conn_.send_buffer(); }
375
376 const std::vector<uint8_t> &recv_buffer() const {
377 return conn_.recv_buffer();
378 }
379
380 std::vector<uint8_t> &recv_buffer() { return conn_.recv_buffer(); }
381
382 void username(const std::string &username) { username_ = username; }
383
384 std::string username() const { return username_; }
385
386 void server_auth_method_name(const std::string &auth_method_name) {
387 server_auth_method_name_ = auth_method_name;
388 }
389
390 std::string server_auth_method_name() const {
391 return server_auth_method_name_;
392 }
393
394 void server_auth_method_data(const std::string &auth_method_data) {
395 server_auth_method_data_ = auth_method_data;
396 }
397
398 std::string server_auth_method_data() const {
399 return server_auth_method_data_;
400 }
401
402 void auth_method_name(const std::string &auth_method_name) {
403 auth_method_name_ = auth_method_name;
404 }
405
406 std::string auth_method_name() const { return auth_method_name_; }
407
408 void auth_method_data(const std::string &auth_method_data) {
409 auth_method_data_ = auth_method_data;
410 }
411
412 std::string auth_method_data() const { return auth_method_data_; }
413
414 static bool authenticate(const std::string &auth_method_name,
415 const std::string &auth_method_data,
416 const std::string &password,
417 const std::vector<uint8_t> &auth_response);
418
419 net::steady_timer &exec_timer() { return exec_timer_; }
420
421 void cancel();
422
423 /**
424 * terminate the current connection.
425 *
426 * sets is_terminated(true) and cancels the current operation.
427 *
428 * may be called from another thread.
429 */
430 void terminate() { conn_.terminate(); }
431
432 net::io_context &io_context() { return conn_.io_context(); }
433
434 Connection &connection() { return conn_; }
435
436 protected:
438 net::steady_timer exec_timer_{io_context()};
439
440 std::string username_{};
441
442 std::string server_auth_method_name_{};
443 std::string server_auth_method_data_{};
444
445 std::string auth_method_name_{};
446 std::string auth_method_data_{};
447};
448
450 public:
453
454 std::optional<std::string> username;
455 std::optional<std::string> password;
456 std::optional<std::string> auth_method_name;
457 bool cert_required{false};
458 std::optional<std::string> cert_subject;
459 std::optional<std::string> cert_issuer;
460
461 std::chrono::microseconds exec_time;
462 };
463
465
468
471
472 virtual ~StatementReaderBase() = default;
473
474 /** @brief Returns the data about the next statement from the
475 * json file. If there is no more statements it returns
476 * empty statement.
477 **/
478 virtual void handle_statement(const std::string &statement,
479 ProtocolBase *protocol) = 0;
480
481 /** @brief Returns the default execution time in microseconds. If
482 * no default execution time is provided in json file, then
483 * 0 microseconds is returned.
484 **/
485 virtual std::chrono::microseconds get_default_exec_time() = 0;
486
487 virtual std::vector<AsyncNotice> get_async_notices() = 0;
488
490 bool is_greeting) = 0;
491
492 virtual void set_session_ssl_info(const SSL *ssl) = 0;
493};
494
495} // namespace server_mock
496
497#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: destination_endpoint.h:38
bool is_tcp() const
Definition: destination_endpoint.h:47
Definition: destination_socket.h:40
net::io_context::executor_type get_executor()
Definition: destination_socket.h:107
stdx::expected< void, std::error_code > native_non_blocking(bool val)
Definition: destination_socket.h:68
bool is_tcp() const
Definition: destination_socket.h:48
void async_wait(net::socket_base::wait_type wt, CompletionToken &&token)
Definition: destination_socket.h:134
stdx::expected< void, std::error_code > set_option(const SettableSocketOption &option)
Definition: destination_socket.h:88
Definition: executor.h:72
Definition: timer.h:57
Definition: buffer.h:135
Definition: io_context.h:991
io_context & context() const noexcept
Definition: io_context.h:1003
Definition: io_context.h:61
io_context()
Definition: io_context.h:68
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:321
void operator()(SSL *ssl)
Definition: statement_reader.h:323
Definition: statement_reader.h:95
const std::vector< uint8_t > & recv_buffer() const
Definition: statement_reader.h:292
stdx::expected< void, std::error_code > cancel()
Definition: statement_reader.h:295
void async_receive_tls(CompletionToken &&token)
Definition: statement_reader.h:174
std::vector< uint8_t > recv_buffer_
Definition: statement_reader.h:319
std::unique_ptr< SSL, SSL_Deleter > ssl_
Definition: statement_reader.h:326
stdx::expected< size_t, std::error_code > avail_ssl()
Definition: protocol_base.cc:62
TlsServerContext & tls_ctx_
Definition: statement_reader.h:328
void async_tls_accept(CompletionToken &&token)
Definition: statement_reader.h:247
void async_receive(CompletionToken &&token)
Definition: statement_reader.h:227
net::impl::socket::native_handle_type native_handle() const
Definition: statement_reader.h:297
mysql_harness::DestinationSocket sock_
Definition: statement_reader.h:315
stdx::expected< size_t, std::error_code > read_ssl(const net::mutable_buffer &buf)
Definition: protocol_base.cc:48
const std::vector< uint8_t > & send_buffer() const
Definition: statement_reader.h:289
Connection(mysql_harness::DestinationSocket sock, mysql_harness::DestinationEndpoint ep, TlsServerContext &tls_ctx)
Definition: statement_reader.h:97
void async_send(CompletionToken &&token)
Definition: statement_reader.h:164
net::io_context & io_context()
Definition: statement_reader.h:121
mysql_harness::DestinationEndpoint ep_
Definition: statement_reader.h:316
void async_send_tls(CompletionToken &&token)
Definition: statement_reader.h:124
stdx::expected< size_t, std::error_code > write_ssl(const net::const_buffer &buf)
Definition: protocol_base.cc:37
std::vector< uint8_t > & send_buffer()
Definition: statement_reader.h:290
static std::error_code map_tls_error_code(std::error_code ec)
Definition: statement_reader.h:309
const SSL * ssl() const
Definition: statement_reader.h:287
std::vector< uint8_t > & recv_buffer()
Definition: statement_reader.h:293
std::vector< uint8_t > send_buffer_
Definition: statement_reader.h:318
bool is_tls()
Definition: statement_reader.h:285
net::io_context::executor_type get_executor()
Definition: statement_reader.h:119
Definition: statement_reader.h:331
std::string username() const
Definition: statement_reader.h:384
virtual ~ProtocolBase()=default
ProtocolBase(ProtocolBase &&)=delete
std::string server_auth_method_name() const
Definition: statement_reader.h:390
net::steady_timer & exec_timer()
Definition: statement_reader.h:419
void terminate()
terminate the current connection.
Definition: statement_reader.h:430
Connection conn_
Definition: statement_reader.h:437
const std::vector< uint8_t > & send_buffer() const
Definition: statement_reader.h:370
void async_send_tls(CompletionToken &&token)
Definition: statement_reader.h:356
const std::vector< uint8_t > & recv_buffer() const
Definition: statement_reader.h:376
std::string server_auth_method_data() const
Definition: statement_reader.h:398
ProtocolBase & operator=(ProtocolBase &&rhs)=delete
std::string auth_method_data() const
Definition: statement_reader.h:412
Connection & connection()
Definition: statement_reader.h:434
void auth_method_name(const std::string &auth_method_name)
Definition: statement_reader.h:402
void server_auth_method_data(const std::string &auth_method_data)
Definition: statement_reader.h:394
virtual void encode_resultset(const ResultsetResponse &response)=0
void server_auth_method_name(const std::string &auth_method_name)
Definition: statement_reader.h:386
std::vector< uint8_t > & recv_buffer()
Definition: statement_reader.h:380
void auth_method_data(const std::string &auth_method_data)
Definition: statement_reader.h:408
void async_receive(CompletionToken &&token)
Definition: statement_reader.h:366
void async_send(CompletionToken &&token)
Definition: statement_reader.h:361
std::string auth_method_name() const
Definition: statement_reader.h:406
virtual void encode_error(const ErrorResponse &resp)=0
void username(const std::string &username)
Definition: statement_reader.h:382
ProtocolBase & operator=(const ProtocolBase &)=delete
virtual void encode_ok(const OkResponse &resp)=0
ProtocolBase(mysql_harness::DestinationSocket sock, mysql_harness::DestinationEndpoint ep, TlsServerContext &tls_ctx)
Definition: statement_reader.h:333
std::vector< uint8_t > & send_buffer()
Definition: statement_reader.h:374
net::io_context & io_context()
Definition: statement_reader.h:432
ProtocolBase(const ProtocolBase &)=delete
Definition: statement_reader.h:449
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
static MYSQL * sock
Definition: mysqlcheck.cc:57
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
int native_handle_type
Definition: socket_constants.h:51
dynamic_vector_buffer< T, Allocator > dynamic_buffer(std::vector< T, Allocator > &vec) noexcept
Definition: buffer.h:661
auto defer(CompletionToken &&token)
Definition: executor.h:779
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
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:68
classic_protocol::message::server::Ok OkResponse
Definition: statement_reader.h:83
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:60
classic_protocol::message::server::Error ErrorResponse
Definition: statement_reader.h:84
std::string encode_session_trackers(const std::vector< session_tracker_field > &trackers)
Definition: duktape_statement_reader.cc:91
Definition: gcs_xcom_synode.h:64
Definition: statement_reader.h:86
std::chrono::milliseconds send_offset_ms
Definition: statement_reader.h:89
bool is_local
Definition: statement_reader.h:91
std::string payload
Definition: statement_reader.h:92
unsigned type
Definition: statement_reader.h:90
Keeps result data for single SQL statement that returns resultset.
Definition: statement_reader.h:76
std::vector< RowValueType > rows
Definition: statement_reader.h:78
classic_protocol::message::server::Eof end_of_rows
Definition: statement_reader.h:80
std::vector< classic_protocol::message::server::ColumnMeta > columns
Definition: statement_reader.h:77
Definition: statement_reader.h:451
std::optional< std::string > username
Definition: statement_reader.h:454
std::chrono::microseconds exec_time
Definition: statement_reader.h:461
classic_protocol::message::server::Greeting greeting
Definition: statement_reader.h:452
std::optional< std::string > cert_issuer
Definition: statement_reader.h:459
std::optional< std::string > password
Definition: statement_reader.h:455
std::optional< std::string > cert_subject
Definition: statement_reader.h:458
std::optional< std::string > auth_method_name
Definition: statement_reader.h:456
Definition: mysqlslap.cc:221