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