MySQL 8.0.37
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 <vector>
35
36#include <openssl/bio.h>
37
46
47#include "authentication.h"
52
53namespace server_mock {
54
55/** @brief Vector for keeping has_value|string representation of the values
56 * of the single row (ordered by column)
57 **/
58using RowValueType = std::vector<std::optional<std::string>>;
59
60/** @brief Keeps result data for single SQL statement that returns
61 * resultset.
62 **/
64 std::vector<classic_protocol::message::server::ColumnMeta> columns;
65 std::vector<RowValueType> rows;
66};
67
70
72 // how many milliseconds after the client connects this Notice
73 // should be sent to the client
74 std::chrono::milliseconds send_offset_ms;
75 unsigned type;
76 bool is_local; // true = local, false = global
77 std::string payload;
78};
79
81 public:
85
86 ProtocolBase(socket_type client_sock, endpoint_type client_ep,
87 TlsServerContext &tls_ctx);
88
89 ProtocolBase(const ProtocolBase &) = delete;
91
94 client_socket_ = std::move(rhs.client_socket_);
95 ssl_ = std::move(rhs.ssl_);
96 tls_ctx_ = std::move(rhs.tls_ctx_);
97
98 return *this;
99 }
100
101 virtual ~ProtocolBase() = default;
102
103 // throws std::system_error
104 virtual void encode_error(const ErrorResponse &resp) = 0;
105
106 // throws std::system_error
107 virtual void encode_ok(const uint64_t affected_rows = 0,
108 const uint64_t last_insert_id = 0,
109 const uint16_t server_status = 0,
110 const uint16_t warning_count = 0) = 0;
111
112 void encode_ok(const OkResponse &resp) {
113 encode_ok(resp.affected_rows(), resp.last_insert_id(),
114 resp.status_flags().to_ulong(), resp.warning_count());
115 }
116
117 // throws std::system_error
118 virtual void encode_resultset(const ResultsetResponse &response) = 0;
119
121 const net::mutable_buffer &buf);
122
124 const net::const_buffer &buf);
125
127
128 template <class CompletionToken>
129 void async_send_tls(CompletionToken &&token) {
130 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
131 token};
132
133 const auto write_res = write_ssl(net::buffer(send_buffer_));
134 if (!write_res) {
135 auto write_ec = write_res.error();
136
137 if (write_ec == TlsErrc::kWantRead || write_ec == TlsErrc::kWantWrite) {
138 client_socket_.async_wait(
141 [this, compl_handler = std::move(init.completion_handler)](
142 std::error_code ec) mutable {
143 if (ec) {
144 compl_handler(ec, {});
145 return;
146 }
147
148 async_send(std::move(compl_handler));
149 });
150 } else {
151 net::defer(client_socket_.get_executor(),
152 [compl_handler = std::move(init.completion_handler),
153 ec = write_res.error()]() { compl_handler(ec, {}); });
154 }
155 } else {
156 net::dynamic_buffer(send_buffer_).consume(write_res.value());
157
158 net::defer(client_socket_.get_executor(),
159 [compl_handler = std::move(init.completion_handler),
160 transferred = write_res.value()]() {
161 compl_handler({}, transferred);
162 });
163 }
164
165 return init.result.get();
166 }
167
168 template <class CompletionToken>
169 void async_send(CompletionToken &&token) {
170 if (is_tls()) {
171 async_send_tls(std::forward<CompletionToken>(token));
172 } else {
173 net::async_write(client_socket_, net::dynamic_buffer(send_buffer_),
174 std::forward<CompletionToken>(token));
175 }
176 }
177
178 // TlsErrc to net::stream_errc if needed.
179 static std::error_code map_tls_error_code(std::error_code ec) {
180 return (ec == TlsErrc::kZeroReturn) ? net::stream_errc::eof : ec;
181 }
182
183 template <class CompletionToken>
184 void async_receive_tls(CompletionToken &&token) {
185 net::async_completion<CompletionToken, void(std::error_code, size_t)> init{
186 token};
187
188 auto buf = net::dynamic_buffer(recv_buffer_);
189
190 auto orig_size = buf.size();
191 auto grow_size = 16 * 1024;
192
193 buf.grow(grow_size);
194 size_t transferred{};
195 auto read_res = read_ssl(buf.data(orig_size, grow_size));
196 if (read_res) {
197 transferred = read_res.value();
198 }
199
200 buf.shrink(grow_size - transferred);
201
202 if (!read_res) {
203 const auto read_ec = read_res.error();
204 if (read_ec == TlsErrc::kWantRead || read_ec == TlsErrc::kWantWrite) {
205 client_socket_.async_wait(
208 [this, compl_handler = std::move(init.completion_handler)](
209 std::error_code ec) mutable {
210 if (ec) {
211 compl_handler(ec, {});
212 return;
213 }
214
215 async_receive_tls(std::move(compl_handler));
216 });
217 } else {
218 // as we can't handle the error, forward the error to the
219 // completion handler
220
222 client_socket_.get_executor(),
223 [compl_handler = std::move(init.completion_handler),
224 ec = map_tls_error_code(read_ec)]() { compl_handler(ec, {}); });
225 }
226 } else {
227 // success, forward it to the completion handler
228 net::defer(client_socket_.get_executor(),
229 [compl_handler = std::move(init.completion_handler),
230 transferred]() { compl_handler({}, transferred); });
231 }
232
233 return init.result.get();
234 }
235
236 template <class CompletionToken>
237 void async_receive(CompletionToken &&token) {
238 if (is_tls()) {
239 return async_receive_tls(std::forward<CompletionToken>(token));
240 } else {
241 return net::async_read(client_socket_, net::dynamic_buffer(recv_buffer_),
242 std::forward<CompletionToken>(token));
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 client_socket_.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(client_socket_.get_executor().context(),
271 [ec, compl_handler = std::move(init.completion_handler)]() {
272 compl_handler(ec);
273 });
274 }
275 } else {
276 net::defer(client_socket_.get_executor().context(),
277 [compl_handler = std::move(init.completion_handler)]() {
278 compl_handler({});
279 });
280 }
281
282 return init.result.get();
283 }
284
285 const std::vector<uint8_t> &send_buffer() const { return send_buffer_; }
286
287 const net::ip::tcp::socket &client_socket() const { return client_socket_; }
288
289 void username(const std::string &username) { username_ = username; }
290
291 std::string username() const { return username_; }
292
293 void auth_method_name(const std::string &auth_method_name) {
294 auth_method_name_ = auth_method_name;
295 }
296
297 std::string auth_method_name() const { return auth_method_name_; }
298
299 void auth_method_data(const std::string &auth_method_data) {
300 auth_method_data_ = auth_method_data;
301 }
302
303 std::string auth_method_data() const { return auth_method_data_; }
304
305 static bool authenticate(const std::string &auth_method_name,
306 const std::string &auth_method_data,
307 const std::string &password,
308 const std::vector<uint8_t> &auth_response);
309
310 void init_tls();
311
312 bool is_tls() { return bool(ssl_); }
313
314 const SSL *ssl() const { return ssl_.get(); }
315
317
318 net::steady_timer &exec_timer() { return exec_timer_; }
319
320 void cancel();
321
323 return client_socket_.get_executor().context();
324 }
325
326 protected:
329 net::steady_timer exec_timer_{io_context()};
330
331 std::string username_{};
332 std::string auth_method_name_{};
333 std::string auth_method_data_{};
334
336
338 public:
339 void operator()(SSL *v) { SSL_free(v); }
340 };
341
342 std::unique_ptr<SSL, SSL_Deleter> ssl_;
343
344 std::vector<uint8_t> recv_buffer_;
345 std::vector<uint8_t> send_buffer_;
346};
347
349 public:
351 std::optional<ErrorResponse> error;
352
353 std::optional<std::string> username;
354 std::optional<std::string> password;
355 bool cert_required{false};
356 std::optional<std::string> cert_subject;
357 std::optional<std::string> cert_issuer;
358 };
359
361
364
367
368 virtual ~StatementReaderBase() = default;
369
370 /** @brief Returns the data about the next statement from the
371 * json file. If there is no more statements it returns
372 * empty statement.
373 **/
374 virtual void handle_statement(const std::string &statement,
375 ProtocolBase *protocol) = 0;
376
377 /** @brief Returns the default execution time in microseconds. If
378 * no default execution time is provided in json file, then
379 * 0 microseconds is returned.
380 **/
381 virtual std::chrono::microseconds get_default_exec_time() = 0;
382
383 virtual std::vector<AsyncNotice> get_async_notices() = 0;
384
386 std::error_code>
387 server_greeting(bool with_tls) = 0;
388
390
391 virtual std::chrono::microseconds server_greeting_exec_time() = 0;
392
393 virtual void set_session_ssl_info(const SSL *ssl) = 0;
394};
395
396} // namespace server_mock
397
398#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:46
Definition: executor.h:72
Definition: socket.h:1144
Definition: timer.h:57
Definition: buffer.h:135
io_context & context() const noexcept
Definition: io_context.h:1002
Definition: io_context.h:61
executor_type get_executor() noexcept
Definition: io_context.h:1080
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:337
void operator()(SSL *v)
Definition: statement_reader.h:339
Definition: statement_reader.h:80
std::string username() const
Definition: statement_reader.h:291
virtual ~ProtocolBase()=default
net::steady_timer & exec_timer()
Definition: statement_reader.h:318
TlsServerContext & tls_ctx_
Definition: statement_reader.h:335
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:74
const std::vector< uint8_t > & send_buffer() const
Definition: statement_reader.h:285
void async_send_tls(CompletionToken &&token)
Definition: statement_reader.h:129
socket_type client_socket_
Definition: statement_reader.h:327
const SSL * ssl() const
Definition: statement_reader.h:314
std::string auth_method_data() const
Definition: statement_reader.h:303
virtual void encode_ok(const uint64_t affected_rows=0, const uint64_t last_insert_id=0, const uint16_t server_status=0, const uint16_t warning_count=0)=0
void encode_ok(const OkResponse &resp)
Definition: statement_reader.h:112
void auth_method_name(const std::string &auth_method_name)
Definition: statement_reader.h:293
ProtocolBase(ProtocolBase &&)=default
ProtocolBase & operator=(ProtocolBase &&rhs)
Definition: statement_reader.h:93
void async_tls_accept(CompletionToken &&token)
Definition: statement_reader.h:247
virtual void encode_resultset(const ResultsetResponse &response)=0
endpoint_type client_ep_
Definition: statement_reader.h:328
std::vector< uint8_t > recv_buffer_
Definition: statement_reader.h:344
const net::ip::tcp::socket & client_socket() const
Definition: statement_reader.h:287
void async_receive_tls(CompletionToken &&token)
Definition: statement_reader.h:184
void auth_method_data(const std::string &auth_method_data)
Definition: statement_reader.h:299
bool is_tls()
Definition: statement_reader.h:312
void async_receive(CompletionToken &&token)
Definition: statement_reader.h:237
typename protocol_type::endpoint endpoint_type
Definition: statement_reader.h:84
void async_send(CompletionToken &&token)
Definition: statement_reader.h:169
std::string auth_method_name() const
Definition: statement_reader.h:297
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:179
void username(const std::string &username)
Definition: statement_reader.h:289
ProtocolBase & operator=(const ProtocolBase &)=delete
typename protocol_type::socket socket_type
Definition: statement_reader.h:83
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:345
net::io_context & io_context()
Definition: statement_reader.h:322
ProtocolBase(const ProtocolBase &)=delete
std::unique_ptr< SSL, SSL_Deleter > ssl_
Definition: statement_reader.h:342
Definition: statement_reader.h:348
StatementReaderBase & operator=(StatementReaderBase &&)=default
virtual std::vector< AsyncNotice > get_async_notices()=0
virtual stdx::expected< handshake_data, ErrorResponse > handshake()=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.
virtual stdx::expected< classic_protocol::message::server::Greeting, std::error_code > server_greeting(bool with_tls)=0
StatementReaderBase & operator=(const StatementReaderBase &)=default
virtual std::chrono::microseconds server_greeting_exec_time()=0
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:56
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:1399
borrowable::message::server::Greeting< false > Greeting
Definition: classic_protocol_message.h:1401
borrowable::message::server::Ok< false > Ok
Definition: classic_protocol_message.h:1398
dynamic_vector_buffer< T, Allocator > dynamic_buffer(std::vector< T, Allocator > &vec) noexcept
Definition: buffer.h:663
auto defer(CompletionToken &&token)
Definition: executor.h:804
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:420
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_dynamic_buffer< DynamicBuffer >::value, void > async_write(AsyncWriteStream &stream, DynamicBuffer &&b, CompletionCondition cond, CompletionToken &&token)
Definition: buffer.h:1074
Definition: mock_server_component.h:36
classic_protocol::message::server::Ok OkResponse
Definition: statement_reader.h:68
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:58
classic_protocol::message::server::Error ErrorResponse
Definition: statement_reader.h:69
Definition: statement_reader.h:71
std::chrono::milliseconds send_offset_ms
Definition: statement_reader.h:74
bool is_local
Definition: statement_reader.h:76
std::string payload
Definition: statement_reader.h:77
unsigned type
Definition: statement_reader.h:75
Keeps result data for single SQL statement that returns resultset.
Definition: statement_reader.h:63
std::vector< RowValueType > rows
Definition: statement_reader.h:65
std::vector< classic_protocol::message::server::ColumnMeta > columns
Definition: statement_reader.h:64
Definition: statement_reader.h:350
std::optional< std::string > username
Definition: statement_reader.h:353
std::optional< ErrorResponse > error
Definition: statement_reader.h:351
std::optional< std::string > cert_issuer
Definition: statement_reader.h:357
std::optional< std::string > password
Definition: statement_reader.h:354
std::optional< std::string > cert_subject
Definition: statement_reader.h:356
Definition: mysqlslap.cc:217