MySQL 9.0.0
Source Code Documentation
classic_frame.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2022, 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 ROUTING_CLASSIC_FRAME_INCLUDED
27#define ROUTING_CLASSIC_FRAME_INCLUDED
28
29#include <system_error>
30
34#include "mysqlrouter/channel.h"
35
37 public:
39 Channel &src_channel, ClassicProtocolState &src_protocol);
40
41 template <class Proto>
44 return ensure_has_msg_prefix(conn.channel(), conn.protocol());
45 }
46
47 [[nodiscard]] static stdx::expected<void, std::error_code>
48 ensure_has_full_frame(Channel &src_channel,
49 ClassicProtocolState &src_protocol);
50
51 template <class Proto>
52 [[nodiscard]] static stdx::expected<void, std::error_code>
54 return ensure_has_full_frame(conn.channel(), conn.protocol());
55 }
56
57 /**
58 * recv a full message sequence into the channel's recv_plain_buffer()
59 */
61 recv_frame_sequence(Channel &src_channel, ClassicProtocolState &src_protocol);
62
64 Channel &src_channel, ClassicProtocolState &src_protocol);
65
67 Channel &src_channel, ClassicProtocolState &src_protocol);
68
69 template <class Proto>
72 return ensure_frame_header(conn.channel(), conn.protocol());
73 }
74
75 template <class T>
76 static constexpr uint8_t cmd_byte() {
78 }
79
80 /**
81 * receive a classic protocol message frame from a channel.
82 */
83 template <class Msg, class Proto>
85 Channel &src_channel, Proto &src_protocol,
87 auto read_res =
88 ClassicFrame::recv_frame_sequence(src_channel, src_protocol);
89 if (!read_res) return stdx::unexpected(read_res.error());
90
91 auto num_of_frames = *read_res;
92 if (num_of_frames > 1) {
93 // more than one frame.
94 auto frame_sequence_buf = src_channel.recv_plain_view();
95
96 // assemble the payload from multiple frames.
97
98 auto &payload_buf = src_channel.payload_buffer();
99 payload_buf.clear();
100
101 while (!frame_sequence_buf.empty()) {
102 auto hdr_res =
103 classic_protocol::decode<classic_protocol::frame::Header>(
104 net::buffer(frame_sequence_buf), caps);
105 if (!hdr_res) return stdx::unexpected(hdr_res.error());
106
107 // skip the hdr.
108 frame_sequence_buf =
109 frame_sequence_buf.last(frame_sequence_buf.size() - hdr_res->first);
110
111 auto frame_payload =
112 frame_sequence_buf.first(hdr_res->second.payload_size());
113
114 payload_buf.insert(payload_buf.end(), frame_payload.begin(),
115 frame_payload.end());
116
117 frame_sequence_buf = frame_sequence_buf.last(
118 frame_sequence_buf.size() - hdr_res->second.payload_size());
119 }
120
121 auto decode_res =
122 classic_protocol::decode<Msg>(net::buffer(payload_buf), caps);
123 if (!decode_res) return stdx::unexpected(decode_res.error());
124
125 return decode_res->second;
126 } else {
127 auto &recv_buf = src_channel.recv_plain_view();
128
129 auto decode_res =
130 classic_protocol::decode<classic_protocol::frame::Frame<Msg>>(
131 net::buffer(recv_buf), caps);
132 if (!decode_res) return stdx::unexpected(decode_res.error());
133
134 return decode_res->second.payload();
135 }
136 }
137
138 template <class Msg, class Proto>
140 Channel &src_channel, Proto &src_protocol) {
141 return recv_msg<Msg>(src_channel, src_protocol,
142 src_protocol.shared_capabilities());
143 }
144
145 template <class Msg, class Proto>
148 return recv_msg<Msg>(conn.channel(), conn.protocol());
149 }
150
151 /**
152 * receive a StmtExecute message from a channel.
153 *
154 * specialization of recv_msg<> as StmtExecute needs a the data from the
155 * StmtPrepareOk.
156 */
157 template <class Msg, class Proto>
158 requires(
159 (std::is_same_v<
161 std::is_same_v<Proto, ClientSideClassicProtocolState>)) //
163 Channel &src_channel, Proto &src_protocol,
165 auto read_res =
166 ClassicFrame::recv_frame_sequence(src_channel, src_protocol);
167 if (!read_res) return stdx::unexpected(read_res.error());
168
169 const auto &recv_buf = src_channel.recv_plain_view();
170
171 auto frame_decode_res =
174 caps);
175 if (!frame_decode_res) {
176 return stdx::unexpected(frame_decode_res.error());
177 }
178
179 src_protocol.seq_id(frame_decode_res->second.seq_id());
180
181 auto decode_res = classic_protocol::decode<Msg>(
182 net::buffer(frame_decode_res->second.payload().value()), caps,
183 [src_protocol](
184 auto stmt_id) -> stdx::expected<std::vector<typename Msg::ParamDef>,
185 std::error_code> {
186 const auto it = src_protocol.prepared_statements().find(stmt_id);
187 if (it == src_protocol.prepared_statements().end()) {
188 return stdx::unexpected(make_error_code(
189 classic_protocol::codec_errc::statement_id_not_found));
190 }
191
192 std::vector<typename Msg::ParamDef> params;
193 params.reserve(it->second.parameters.size());
194
195 for (const auto &param : it->second.parameters) {
196 params.emplace_back(param.type_and_flags, std::string_view{},
197 param.param_already_sent);
198 }
199
200 return params;
201 });
202 if (!decode_res) return stdx::unexpected(decode_res.error());
203
204 return decode_res->second;
205 }
206
207 template <class Msg>
209 Channel &dst_channel, ClassicProtocolState &dst_protocol, Msg msg,
211 auto encode_res = classic_protocol::encode(
213 std::forward<Msg>(msg)),
214 caps, net::dynamic_buffer(dst_channel.send_plain_buffer()));
215 if (!encode_res) return encode_res;
216
217 return dst_channel.flush_to_send_buf();
218 }
219
220 template <class Msg>
222 Channel &dst_channel, ClassicProtocolState &dst_protocol, Msg msg) {
223 return send_msg<Msg>(dst_channel, dst_protocol, std::forward<Msg>(msg),
224 dst_protocol.shared_capabilities());
225 }
226
227 template <class Msg, class Proto>
229 TlsSwitchableConnection<Proto> &conn, Msg msg,
231 return send_msg<Msg>(conn.channel(), conn.protocol(),
232 std::forward<Msg>(msg), caps);
233 }
234
235 template <class Msg, class Proto>
237 TlsSwitchableConnection<Proto> &conn, Msg msg) {
238 return send_msg<Msg>(conn.channel(), conn.protocol(),
239 std::forward<Msg>(msg));
240 }
241
242 /**
243 * set attributes from the Ok message in the TraceEvent.
244 */
245 static void trace_set_attributes(
246 TraceEvent *ev, ClassicProtocolState &src_protocol,
248
249 /**
250 * set attributes from the Eof message in the TraceEvent.
251 */
252 static void trace_set_attributes(
253 TraceEvent *ev, ClassicProtocolState &src_protocol,
255
256 /**
257 * set attributes from the Eof message in the TraceEvent.
258 */
259 static void trace_set_attributes(
260 TraceEvent *ev, ClassicProtocolState &src_protocol,
262};
263
264#endif
SSL aware socket buffers.
Definition: channel.h:65
stdx::expected< size_t, std::error_code > flush_to_send_buf()
flush data to the send buffer.
Definition: channel.cc:151
const recv_buffer_type & payload_buffer() const
payload buffer for
Definition: channel.h:273
recv_buffer_type & send_plain_buffer()
unencrypted data to be sent to the socket.
Definition: channel.cc:275
const recv_view_type & recv_plain_view() const
decrypted data after a recv().
Definition: channel.cc:281
Definition: classic_frame.h:36
static stdx::expected< void, std::error_code > ensure_frame_header(TlsSwitchableConnection< Proto > &conn)
Definition: classic_frame.h:70
static stdx::expected< Msg, std::error_code > recv_msg(TlsSwitchableConnection< Proto > &conn)
Definition: classic_frame.h:146
static stdx::expected< void, std::error_code > ensure_has_full_frame(TlsSwitchableConnection< Proto > &conn)
Definition: classic_frame.h:53
static stdx::expected< size_t, std::error_code > recv_frame_sequence(Channel &src_channel, ClassicProtocolState &src_protocol)
recv a full message sequence into the channel's recv_plain_buffer()
Definition: classic_frame.cc:178
static stdx::expected< void, std::error_code > ensure_has_full_frame(Channel &src_channel, ClassicProtocolState &src_protocol)
Definition: classic_frame.cc:158
static stdx::expected< Msg, std::error_code > recv_msg(Channel &src_channel, Proto &src_protocol, classic_protocol::capabilities::value_type caps)
receive a StmtExecute message from a channel.
Definition: classic_frame.h:162
static stdx::expected< size_t, std::error_code > send_msg(TlsSwitchableConnection< Proto > &conn, Msg msg)
Definition: classic_frame.h:236
static stdx::expected< void, std::error_code > ensure_has_msg_prefix(Channel &src_channel, ClassicProtocolState &src_protocol)
ensure message has a frame-header and msg-type.
Definition: classic_frame.cc:46
static stdx::expected< Msg, std::error_code > recv_msg(Channel &src_channel, Proto &src_protocol, classic_protocol::capabilities::value_type caps)
receive a classic protocol message frame from a channel.
Definition: classic_frame.h:84
static constexpr uint8_t cmd_byte()
Definition: classic_frame.h:76
static stdx::expected< void, std::error_code > ensure_has_msg_prefix(TlsSwitchableConnection< Proto > &conn)
Definition: classic_frame.h:42
static stdx::expected< size_t, std::error_code > send_msg(TlsSwitchableConnection< Proto > &conn, Msg msg, classic_protocol::capabilities::value_type caps)
Definition: classic_frame.h:228
static stdx::expected< size_t, std::error_code > send_msg(Channel &dst_channel, ClassicProtocolState &dst_protocol, Msg msg)
Definition: classic_frame.h:221
static stdx::expected< void, std::error_code > ensure_frame_header(Channel &src_channel, ClassicProtocolState &src_protocol)
ensure current_frame() has a current frame-info.
Definition: classic_frame.cc:133
static stdx::expected< Msg, std::error_code > recv_msg(Channel &src_channel, Proto &src_protocol)
Definition: classic_frame.h:139
static stdx::expected< size_t, std::error_code > send_msg(Channel &dst_channel, ClassicProtocolState &dst_protocol, Msg msg, classic_protocol::capabilities::value_type caps)
Definition: classic_frame.h:208
static stdx::expected< void, std::error_code > ensure_server_greeting(Channel &src_channel, ClassicProtocolState &src_protocol)
protocol state of a classic protocol connection.
Definition: classic_protocol_state.h:39
uint8_t & seq_id()
Definition: classic_protocol_state.h:197
classic_protocol::capabilities::value_type shared_capabilities() const
Definition: classic_protocol_state.h:173
a Connection that can be switched to TLS.
Definition: connection_base.h:264
Channel & channel()
Definition: connection_base.h:359
protocol_state_type & protocol()
Definition: connection_base.h:398
Codec for a type.
Definition: classic_protocol_codec_base.h:72
execute a prepared statement.
Definition: classic_protocol_message.h:1090
Definition: classic_protocol_wire.h:38
Definition: classic_protocol_frame.h:85
Definition: expected.h:284
borrowable::message::server::Eof< true > Eof
Definition: classic_protocol_message.h:1460
borrowable::message::server::Error< true > Error
Definition: classic_protocol_message.h:1459
borrowable::message::server::Ok< true > Ok
Definition: classic_protocol_message.h:1458
std::bitset< 32 > value_type
Definition: classic_protocol_constants.h:73
stdx::expected< size_t, std::error_code > encode(const T &v, capabilities::value_type caps, DynamicBuffer &&dyn_buffer)
encode a message into a dynamic buffer.
Definition: classic_protocol_codec_base.h:84
stdx::expected< std::pair< size_t, T >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
decode a message from a buffer.
Definition: classic_protocol_codec_base.h:119
dynamic_vector_buffer< T, Allocator > dynamic_buffer(std::vector< T, Allocator > &vec) noexcept
Definition: buffer.h:661
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
unexpected(E) -> unexpected< E >
Definition: trace_span.h:35