MySQL 8.3.0
Source Code Documentation
statement_reader.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018, 2023, 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 also distributed 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 included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*/
24
25#ifndef MYSQLD_MOCK_STATEMENT_READER_INCLUDED
26#define MYSQLD_MOCK_STATEMENT_READER_INCLUDED
27
28#include <chrono>
29#include <memory>
30#include <optional>
31#include <string>
32#include <utility>
33#include <variant>
34#include <vector>
35
36#include <openssl/bio.h>
37
46
47#include "authentication.h"
53
54namespace server_mock {
55
56/** @brief Vector for keeping has_value|string representation of the values
57 * of the single row (ordered by column)
58 **/
59using RowValueType = std::vector<std::optional<std::string>>;
60
68
69std::string encode_session_trackers(
70 const std::vector<session_tracker_field> &trackers);
71
72/** @brief Keeps result data for single SQL statement that returns
73 * resultset.
74 **/
76 std::vector<classic_protocol::message::server::ColumnMeta> columns;
77 std::vector<RowValueType> rows;
78
80};
81
84
86 // how many milliseconds after the client connects this Notice
87 // should be sent to the client
88 std::chrono::milliseconds send_offset_ms;
89 unsigned type;
90 bool is_local; // true = local, false = global
91 std::string payload;
92};
93
95 public:
99
100 ProtocolBase(socket_type client_sock, endpoint_type client_ep,
101 TlsServerContext &tls_ctx);
102
103 ProtocolBase(const ProtocolBase &) = delete;
105
108 client_socket_ = std::move(rhs.client_socket_);
109 ssl_ = std::move(rhs.ssl_);
110 tls_ctx_ = std::move(rhs.tls_ctx_);
111
112 return *this;
113 }
114
115 virtual ~ProtocolBase() = default;
116
117 // throws std::system_error
118 virtual void encode_error(const ErrorResponse &resp) = 0;
119
120 // throws std::system_error
121 virtual void encode_ok(const OkResponse &resp) = 0;
122
123 // throws std::system_error
124 virtual void encode_resultset(const ResultsetResponse &response) = 0;
125
127 const net::mutable_buffer &buf);
128
130 const net::const_buffer &buf);
131
133
134 template <class CompletionToken>
135 void async_send_tls(CompletionToken &&token) {
136 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
137 token};
138
139 const auto write_res = write_ssl(net::buffer(send_buffer_));
140 if (!write_res) {
141 auto write_ec = write_res.error();
142
143 if (write_ec == TlsErrc::kWantRead || write_ec == TlsErrc::kWantWrite) {
144 client_socket_.async_wait(
147 [this, compl_handler = std::move(init.completion_handler)](
148 std::error_code ec) mutable {
149 if (ec) {
150 compl_handler(ec, {});
151 return;
152 }
153
154 async_send(std::move(compl_handler));
155 });
156 } else {
157 net::defer(client_socket_.get_executor(),
158 [compl_handler = std::move(init.completion_handler),
159 ec = write_res.error()]() { compl_handler(ec, {}); });
160 }
161 } else {
162 net::dynamic_buffer(send_buffer_).consume(write_res.value());
163
164 net::defer(client_socket_.get_executor(),
165 [compl_handler = std::move(init.completion_handler),
166 transferred = write_res.value()]() {
167 compl_handler({}, transferred);
168 });
169 }
170
171 return init.result.get();
172 }
173
174 template <class CompletionToken>
175 void async_send(CompletionToken &&token) {
176 if (is_tls()) {
177 async_send_tls(std::forward<CompletionToken>(token));
178 } else {
179 net::async_write(client_socket_, net::dynamic_buffer(send_buffer_),
180 std::forward<CompletionToken>(token));
181 }
182 }
183
184 // TlsErrc to net::stream_errc if needed.
185 static std::error_code map_tls_error_code(std::error_code ec) {
186 return (ec == TlsErrc::kZeroReturn) ? net::stream_errc::eof : ec;
187 }
188
189 template <class CompletionToken>
190 void async_receive_tls(CompletionToken &&token) {
191 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
192 token};
193
194 auto buf = net::dynamic_buffer(recv_buffer_);
195
196 auto orig_size = buf.size();
197 auto grow_size = 16 * 1024;
198
199 buf.grow(grow_size);
200 size_t transferred{};
201 auto read_res = read_ssl(buf.data(orig_size, grow_size));
202 if (read_res) {
203 transferred = read_res.value();
204 }
205
206 buf.shrink(grow_size - transferred);
207
208 if (!read_res) {
209 const auto read_ec = read_res.error();
210 if (read_ec == TlsErrc::kWantRead || read_ec == TlsErrc::kWantWrite) {
211 client_socket_.async_wait(
214 [this, compl_handler = std::move(init.completion_handler)](
215 std::error_code ec) mutable {
216 if (ec) {
217 compl_handler(ec, {});
218 return;
219 }
220
221 async_receive_tls(std::move(compl_handler));
222 });
223 } else {
224 // as we can't handle the error, forward the error to the
225 // completion handler
226
228 client_socket_.get_executor(),
229 [compl_handler = std::move(init.completion_handler),
230 ec = map_tls_error_code(read_ec)]() { compl_handler(ec, {}); });
231 }
232 } else {
233 // success, forward it to the completion handler
234 net::defer(client_socket_.get_executor(),
235 [compl_handler = std::move(init.completion_handler),
236 transferred]() { compl_handler({}, transferred); });
237 }
238
239 return init.result.get();
240 }
241
242 template <class CompletionToken>
243 void async_receive(CompletionToken &&token) {
244 if (is_tls()) {
245 return async_receive_tls(std::forward<CompletionToken>(token));
246 } else {
247 return net::async_read(client_socket_, net::dynamic_buffer(recv_buffer_),
248 std::forward<CompletionToken>(token));
249 }
250 }
251
252 template <class CompletionToken>
253 void async_tls_accept(CompletionToken &&token) {
254 net::async_completion<CompletionToken, void(std::error_code)> init{token};
255
256 // data may already be pending
257 auto res = tls_accept();
258 if (!res) {
259 auto ec = res.error();
260 if (ec == TlsErrc::kWantRead || ec == TlsErrc::kWantWrite) {
263
264 client_socket_.async_wait(
265 wt, [&, compl_handler = std::move(init.completion_handler)](
266 std::error_code ec) mutable {
267 if (ec) {
268 compl_handler(ec);
269 return;
270 }
271
272 // call async accept again.
273 async_tls_accept(std::move(compl_handler));
274 });
275 } else {
276 net::defer(client_socket_.get_executor().context(),
277 [ec, compl_handler = std::move(init.completion_handler)]() {
278 compl_handler(ec);
279 });
280 }
281 } else {
282 net::defer(client_socket_.get_executor().context(),
283 [compl_handler = std::move(init.completion_handler)]() {
284 compl_handler({});
285 });
286 }
287
288 return init.result.get();
289 }
290
291 const std::vector<uint8_t> &send_buffer() const { return send_buffer_; }
292
293 const net::ip::tcp::socket &client_socket() const { return client_socket_; }
294
295 void username(const std::string &username) { username_ = username; }
296
297 std::string username() const { return username_; }
298
299 void auth_method_name(const std::string &auth_method_name) {
300 auth_method_name_ = auth_method_name;
301 }
302
303 std::string auth_method_name() const { return auth_method_name_; }
304
305 void auth_method_data(const std::string &auth_method_data) {
306 auth_method_data_ = auth_method_data;
307 }
308
309 std::string auth_method_data() const { return auth_method_data_; }
310
311 static bool authenticate(const std::string &auth_method_name,
312 const std::string &auth_method_data,
313 const std::string &password,
314 const std::vector<uint8_t> &auth_response);
315
316 void init_tls();
317
318 bool is_tls() { return bool(ssl_); }
319
320 const SSL *ssl() const { return ssl_.get(); }
321
323
324 net::steady_timer &exec_timer() { return exec_timer_; }
325
326 void cancel();
327
329 return client_socket_.get_executor().context();
330 }
331
332 protected:
335 net::steady_timer exec_timer_{io_context()};
336
337 std::string username_{};
338 std::string auth_method_name_{};
339 std::string auth_method_data_{};
340
342
344 public:
345 void operator()(SSL *v) { SSL_free(v); }
346 };
347
348 std::unique_ptr<SSL, SSL_Deleter> ssl_;
349
350 std::vector<uint8_t> recv_buffer_;
351 std::vector<uint8_t> send_buffer_;
352};
353
355 public:
358
359 std::optional<std::string> username;
360 std::optional<std::string> password;
361 bool cert_required{false};
362 std::optional<std::string> cert_subject;
363 std::optional<std::string> cert_issuer;
364
365 std::chrono::microseconds exec_time;
366 };
367
369
372
375
376 virtual ~StatementReaderBase() = default;
377
378 /** @brief Returns the data about the next statement from the
379 * json file. If there is no more statements it returns
380 * empty statement.
381 **/
382 virtual void handle_statement(const std::string &statement,
383 ProtocolBase *protocol) = 0;
384
385 /** @brief Returns the default execution time in microseconds. If
386 * no default execution time is provided in json file, then
387 * 0 microseconds is returned.
388 **/
389 virtual std::chrono::microseconds get_default_exec_time() = 0;
390
391 virtual std::vector<AsyncNotice> get_async_notices() = 0;
392
394 bool is_greeting) = 0;
395
396 virtual void set_session_ssl_info(const SSL *ssl) = 0;
397};
398
399} // namespace server_mock
400
401#endif
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:570
TLS Context for the server side.
Definition: tls_server_context.h:50
gtid changed.
Definition: classic_protocol_session_track.h:146
Definition: executor.h:71
Definition: socket.h:1089
Definition: timer.h:56
Definition: buffer.h:134
io_context & context() const noexcept
Definition: io_context.h:1001
Definition: io_context.h:60
executor_type get_executor() noexcept
Definition: io_context.h:1079
TCP protocol.
Definition: internet.h:1154
basic_endpoint< tcp > endpoint
Definition: internet.h:1156
basic_stream_socket< tcp > socket
Definition: internet.h:1158
Definition: buffer.h:112
static constexpr wait_type wait_read
Definition: socket.h:167
static constexpr wait_type wait_write
Definition: socket.h:168
Definition: statement_reader.h:343
void operator()(SSL *v)
Definition: statement_reader.h:345
Definition: statement_reader.h:94
std::string username() const
Definition: statement_reader.h:297
virtual ~ProtocolBase()=default
net::steady_timer & exec_timer()
Definition: statement_reader.h:324
TlsServerContext & tls_ctx_
Definition: statement_reader.h:341
ProtocolBase(socket_type client_sock, endpoint_type client_ep, TlsServerContext &tls_ctx)
Definition: protocol_base.cc:35
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:291
void async_send_tls(CompletionToken &&token)
Definition: statement_reader.h:135
socket_type client_socket_
Definition: statement_reader.h:333
const SSL * ssl() const
Definition: statement_reader.h:320
std::string auth_method_data() const
Definition: statement_reader.h:309
void auth_method_name(const std::string &auth_method_name)
Definition: statement_reader.h:299
ProtocolBase(ProtocolBase &&)=default
ProtocolBase & operator=(ProtocolBase &&rhs)
Definition: statement_reader.h:107
void async_tls_accept(CompletionToken &&token)
Definition: statement_reader.h:253
virtual void encode_resultset(const ResultsetResponse &response)=0
endpoint_type client_ep_
Definition: statement_reader.h:334
std::vector< uint8_t > recv_buffer_
Definition: statement_reader.h:350
const net::ip::tcp::socket & client_socket() const
Definition: statement_reader.h:293
void async_receive_tls(CompletionToken &&token)
Definition: statement_reader.h:190
void auth_method_data(const std::string &auth_method_data)
Definition: statement_reader.h:305
bool is_tls()
Definition: statement_reader.h:318
void async_receive(CompletionToken &&token)
Definition: statement_reader.h:243
typename protocol_type::endpoint endpoint_type
Definition: statement_reader.h:98
void async_send(CompletionToken &&token)
Definition: statement_reader.h:175
std::string auth_method_name() const
Definition: statement_reader.h:303
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:58
static std::error_code map_tls_error_code(std::error_code ec)
Definition: statement_reader.h:185
void username(const std::string &username)
Definition: statement_reader.h:295
ProtocolBase & operator=(const ProtocolBase &)=delete
virtual void encode_ok(const OkResponse &resp)=0
typename protocol_type::socket socket_type
Definition: statement_reader.h:97
stdx::expected< size_t, std::error_code > write_ssl(const net::const_buffer &buf)
Definition: protocol_base.cc:47
std::vector< uint8_t > send_buffer_
Definition: statement_reader.h:351
net::io_context & io_context()
Definition: statement_reader.h:328
ProtocolBase(const ProtocolBase &)=delete
std::unique_ptr< SSL, SSL_Deleter > ssl_
Definition: statement_reader.h:348
Definition: statement_reader.h:354
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:57
Definition: buf0block_hint.cc:29
constexpr value_type ssl
Definition: classic_protocol_constants.h:48
borrowable::message::server::Error< false > Error
Definition: classic_protocol_message.h:1410
borrowable::message::server::Greeting< false > Greeting
Definition: classic_protocol_message.h:1412
borrowable::message::server::Eof< false > Eof
Definition: classic_protocol_message.h:1411
borrowable::message::server::Ok< false > Ok
Definition: classic_protocol_message.h:1409
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:660
auto defer(CompletionToken &&token)
Definition: executor.h:786
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:417
std::enable_if_t< is_dynamic_buffer< DynamicBuffer >::value, void > async_read(AsyncReadStream &stream, DynamicBuffer &&b, CompletionCondition completion_condition, CompletionToken &&token)
Definition: buffer.h:926
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:1073
Definition: mock_server_component.h:35
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:67
classic_protocol::message::server::Ok OkResponse
Definition: statement_reader.h:82
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:59
classic_protocol::message::server::Error ErrorResponse
Definition: statement_reader.h:83
std::string encode_session_trackers(const std::vector< session_tracker_field > &trackers)
Definition: duktape_statement_reader.cc:90
Definition: statement_reader.h:85
std::chrono::milliseconds send_offset_ms
Definition: statement_reader.h:88
bool is_local
Definition: statement_reader.h:90
std::string payload
Definition: statement_reader.h:91
unsigned type
Definition: statement_reader.h:89
Keeps result data for single SQL statement that returns resultset.
Definition: statement_reader.h:75
std::vector< RowValueType > rows
Definition: statement_reader.h:77
classic_protocol::message::server::Eof end_of_rows
Definition: statement_reader.h:79
std::vector< classic_protocol::message::server::ColumnMeta > columns
Definition: statement_reader.h:76
Definition: statement_reader.h:356
std::optional< std::string > username
Definition: statement_reader.h:359
std::chrono::microseconds exec_time
Definition: statement_reader.h:365
classic_protocol::message::server::Greeting greeting
Definition: statement_reader.h:357
std::optional< std::string > cert_issuer
Definition: statement_reader.h:363
std::optional< std::string > password
Definition: statement_reader.h:360
std::optional< std::string > cert_subject
Definition: statement_reader.h:362
Definition: mysqlslap.cc:218