MySQL 8.4.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 <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"
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:
100
101 ProtocolBase(socket_type client_sock, endpoint_type client_ep,
102 TlsServerContext &tls_ctx);
103
104 ProtocolBase(const ProtocolBase &) = delete;
106
109 client_socket_ = std::move(rhs.client_socket_);
110 ssl_ = std::move(rhs.ssl_);
111 tls_ctx_ = std::move(rhs.tls_ctx_);
112
113 return *this;
114 }
115
116 virtual ~ProtocolBase() = default;
117
118 // throws std::system_error
119 virtual void encode_error(const ErrorResponse &resp) = 0;
120
121 // throws std::system_error
122 virtual void encode_ok(const OkResponse &resp) = 0;
123
124 // throws std::system_error
125 virtual void encode_resultset(const ResultsetResponse &response) = 0;
126
128 const net::mutable_buffer &buf);
129
131 const net::const_buffer &buf);
132
134
135 template <class CompletionToken>
136 void async_send_tls(CompletionToken &&token) {
137 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
138 token};
139
140 const auto write_res = write_ssl(net::buffer(send_buffer_));
141 if (!write_res) {
142 auto write_ec = write_res.error();
143
144 if (write_ec == TlsErrc::kWantRead || write_ec == TlsErrc::kWantWrite) {
145 client_socket_.async_wait(
148 [this, compl_handler = std::move(init.completion_handler)](
149 std::error_code ec) mutable {
150 if (ec) {
151 compl_handler(ec, {});
152 return;
153 }
154
155 async_send(std::move(compl_handler));
156 });
157 } else {
158 net::defer(client_socket_.get_executor(),
159 [compl_handler = std::move(init.completion_handler),
160 ec = write_res.error()]() { compl_handler(ec, {}); });
161 }
162 } else {
163 net::dynamic_buffer(send_buffer_).consume(write_res.value());
164
165 net::defer(client_socket_.get_executor(),
166 [compl_handler = std::move(init.completion_handler),
167 transferred = write_res.value()]() {
168 compl_handler({}, transferred);
169 });
170 }
171
172 return init.result.get();
173 }
174
175 template <class CompletionToken>
176 void async_send(CompletionToken &&token) {
177 if (is_tls()) {
178 async_send_tls(std::forward<CompletionToken>(token));
179 } else {
180 net::async_write(client_socket_, net::dynamic_buffer(send_buffer_),
181 std::forward<CompletionToken>(token));
182 }
183 }
184
185 // TlsErrc to net::stream_errc if needed.
186 static std::error_code map_tls_error_code(std::error_code ec) {
187 return (ec == TlsErrc::kZeroReturn) ? net::stream_errc::eof : ec;
188 }
189
190 template <class CompletionToken>
191 void async_receive_tls(CompletionToken &&token) {
192 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
193 token};
194
195 auto buf = net::dynamic_buffer(recv_buffer_);
196
197 auto orig_size = buf.size();
198 auto grow_size = 16 * 1024;
199
200 buf.grow(grow_size);
201 size_t transferred{};
202 auto read_res = read_ssl(buf.data(orig_size, grow_size));
203 if (read_res) {
204 transferred = read_res.value();
205 }
206
207 buf.shrink(grow_size - transferred);
208
209 if (!read_res) {
210 const auto read_ec = read_res.error();
211 if (read_ec == TlsErrc::kWantRead || read_ec == TlsErrc::kWantWrite) {
212 client_socket_.async_wait(
215 [this, compl_handler = std::move(init.completion_handler)](
216 std::error_code ec) mutable {
217 if (ec) {
218 compl_handler(ec, {});
219 return;
220 }
221
222 async_receive_tls(std::move(compl_handler));
223 });
224 } else {
225 // as we can't handle the error, forward the error to the
226 // completion handler
227
229 client_socket_.get_executor(),
230 [compl_handler = std::move(init.completion_handler),
231 ec = map_tls_error_code(read_ec)]() { compl_handler(ec, {}); });
232 }
233 } else {
234 // success, forward it to the completion handler
235 net::defer(client_socket_.get_executor(),
236 [compl_handler = std::move(init.completion_handler),
237 transferred]() { compl_handler({}, transferred); });
238 }
239
240 return init.result.get();
241 }
242
243 template <class CompletionToken>
244 void async_receive(CompletionToken &&token) {
245 if (is_tls()) {
246 return async_receive_tls(std::forward<CompletionToken>(token));
247 } else {
248 return net::async_read(client_socket_, net::dynamic_buffer(recv_buffer_),
249 std::forward<CompletionToken>(token));
250 }
251 }
252
253 template <class CompletionToken>
254 void async_tls_accept(CompletionToken &&token) {
255 net::async_completion<CompletionToken, void(std::error_code)> init{token};
256
257 // data may already be pending
258 auto res = tls_accept();
259 if (!res) {
260 auto ec = res.error();
261 if (ec == TlsErrc::kWantRead || ec == TlsErrc::kWantWrite) {
264
265 client_socket_.async_wait(
266 wt, [&, compl_handler = std::move(init.completion_handler)](
267 std::error_code ec) mutable {
268 if (ec) {
269 compl_handler(ec);
270 return;
271 }
272
273 // call async accept again.
274 async_tls_accept(std::move(compl_handler));
275 });
276 } else {
277 net::defer(client_socket_.get_executor().context(),
278 [ec, compl_handler = std::move(init.completion_handler)]() {
279 compl_handler(ec);
280 });
281 }
282 } else {
283 net::defer(client_socket_.get_executor().context(),
284 [compl_handler = std::move(init.completion_handler)]() {
285 compl_handler({});
286 });
287 }
288
289 return init.result.get();
290 }
291
292 const std::vector<uint8_t> &send_buffer() const { return send_buffer_; }
293
294 const net::ip::tcp::socket &client_socket() const { return client_socket_; }
295
296 void username(const std::string &username) { username_ = username; }
297
298 std::string username() const { return username_; }
299
300 void auth_method_name(const std::string &auth_method_name) {
301 auth_method_name_ = auth_method_name;
302 }
303
304 std::string auth_method_name() const { return auth_method_name_; }
305
306 void auth_method_data(const std::string &auth_method_data) {
307 auth_method_data_ = auth_method_data;
308 }
309
310 std::string auth_method_data() const { return auth_method_data_; }
311
312 static bool authenticate(const std::string &auth_method_name,
313 const std::string &auth_method_data,
314 const std::string &password,
315 const std::vector<uint8_t> &auth_response);
316
317 void init_tls();
318
319 bool is_tls() { return bool(ssl_); }
320
321 const SSL *ssl() const { return ssl_.get(); }
322
324
325 net::steady_timer &exec_timer() { return exec_timer_; }
326
327 void cancel();
328
330 return client_socket_.get_executor().context();
331 }
332
333 protected:
336 net::steady_timer exec_timer_{io_context()};
337
338 std::string username_{};
339 std::string auth_method_name_{};
340 std::string auth_method_data_{};
341
343
345 public:
346 void operator()(SSL *v) { SSL_free(v); }
347 };
348
349 std::unique_ptr<SSL, SSL_Deleter> ssl_;
350
351 std::vector<uint8_t> recv_buffer_;
352 std::vector<uint8_t> send_buffer_;
353};
354
356 public:
359
360 std::optional<std::string> username;
361 std::optional<std::string> password;
362 bool cert_required{false};
363 std::optional<std::string> cert_subject;
364 std::optional<std::string> cert_issuer;
365
366 std::chrono::microseconds exec_time;
367 };
368
370
373
376
377 virtual ~StatementReaderBase() = default;
378
379 /** @brief Returns the data about the next statement from the
380 * json file. If there is no more statements it returns
381 * empty statement.
382 **/
383 virtual void handle_statement(const std::string &statement,
384 ProtocolBase *protocol) = 0;
385
386 /** @brief Returns the default execution time in microseconds. If
387 * no default execution time is provided in json file, then
388 * 0 microseconds is returned.
389 **/
390 virtual std::chrono::microseconds get_default_exec_time() = 0;
391
392 virtual std::vector<AsyncNotice> get_async_notices() = 0;
393
395 bool is_greeting) = 0;
396
397 virtual void set_session_ssl_info(const SSL *ssl) = 0;
398};
399
400} // namespace server_mock
401
402#endif
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:571
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:344
void operator()(SSL *v)
Definition: statement_reader.h:346
Definition: statement_reader.h:95
std::string username() const
Definition: statement_reader.h:298
virtual ~ProtocolBase()=default
net::steady_timer & exec_timer()
Definition: statement_reader.h:325
TlsServerContext & tls_ctx_
Definition: statement_reader.h:342
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:292
void async_send_tls(CompletionToken &&token)
Definition: statement_reader.h:136
socket_type client_socket_
Definition: statement_reader.h:334
const SSL * ssl() const
Definition: statement_reader.h:321
std::string auth_method_data() const
Definition: statement_reader.h:310
void auth_method_name(const std::string &auth_method_name)
Definition: statement_reader.h:300
ProtocolBase(ProtocolBase &&)=default
ProtocolBase & operator=(ProtocolBase &&rhs)
Definition: statement_reader.h:108
void async_tls_accept(CompletionToken &&token)
Definition: statement_reader.h:254
virtual void encode_resultset(const ResultsetResponse &response)=0
endpoint_type client_ep_
Definition: statement_reader.h:335
std::vector< uint8_t > recv_buffer_
Definition: statement_reader.h:351
const net::ip::tcp::socket & client_socket() const
Definition: statement_reader.h:294
void async_receive_tls(CompletionToken &&token)
Definition: statement_reader.h:191
void auth_method_data(const std::string &auth_method_data)
Definition: statement_reader.h:306
bool is_tls()
Definition: statement_reader.h:319
void async_receive(CompletionToken &&token)
Definition: statement_reader.h:244
typename protocol_type::endpoint endpoint_type
Definition: statement_reader.h:99
void async_send(CompletionToken &&token)
Definition: statement_reader.h:176
std::string auth_method_name() const
Definition: statement_reader.h:304
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:186
void username(const std::string &username)
Definition: statement_reader.h:296
ProtocolBase & operator=(const ProtocolBase &)=delete
virtual void encode_ok(const OkResponse &resp)=0
typename protocol_type::socket socket_type
Definition: statement_reader.h:98
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:352
net::io_context & io_context()
Definition: statement_reader.h:329
ProtocolBase(const ProtocolBase &)=delete
std::unique_ptr< SSL, SSL_Deleter > ssl_
Definition: statement_reader.h:349
Definition: statement_reader.h:355
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: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: 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:357
std::optional< std::string > username
Definition: statement_reader.h:360
std::chrono::microseconds exec_time
Definition: statement_reader.h:366
classic_protocol::message::server::Greeting greeting
Definition: statement_reader.h:358
std::optional< std::string > cert_issuer
Definition: statement_reader.h:364
std::optional< std::string > password
Definition: statement_reader.h:361
std::optional< std::string > cert_subject
Definition: statement_reader.h:363
Definition: mysqlslap.cc:219