MySQL 8.0.37
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
31#include "channel.h"
34
36 public:
38 Channel *src_channel, ClassicProtocolState *src_protocol);
39
40 [[nodiscard]] static stdx::expected<void, std::error_code>
41 ensure_has_full_frame(Channel *src_channel,
42 ClassicProtocolState *src_protocol);
43
44 /**
45 * recv a full message sequence into the channel's recv_plain_buffer()
46 */
48 recv_frame_sequence(Channel *src_channel, ClassicProtocolState *src_protocol);
49
51 Channel *src_channel, ClassicProtocolState *src_protocol);
52
54 Channel *src_channel, ClassicProtocolState *src_protocol);
55
56 template <class T>
57 static constexpr uint8_t cmd_byte() {
59 }
60
61 /**
62 * receive a classic protocol message frame from a channel.
63 */
64 template <class Msg>
66 Channel *src_channel, ClassicProtocolState *src_protocol,
68 auto read_res =
69 ClassicFrame::recv_frame_sequence(src_channel, src_protocol);
70 if (!read_res) return stdx::make_unexpected(read_res.error());
71
72 auto num_of_frames = *read_res;
73 if (num_of_frames > 1) {
74 // more than one frame.
75 auto frame_sequence_buf = src_channel->recv_plain_view();
76
77 // assemble the payload from multiple frames.
78
79 auto &payload_buf = src_channel->payload_buffer();
80 payload_buf.clear();
81
82 while (!frame_sequence_buf.empty()) {
83 auto hdr_res =
84 classic_protocol::decode<classic_protocol::frame::Header>(
85 net::buffer(frame_sequence_buf), caps);
86 if (!hdr_res) return stdx::make_unexpected(hdr_res.error());
87
88 // skip the hdr.
89 frame_sequence_buf =
90 frame_sequence_buf.last(frame_sequence_buf.size() - hdr_res->first);
91
92 auto frame_payload =
93 frame_sequence_buf.first(hdr_res->second.payload_size());
94
95 payload_buf.insert(payload_buf.end(), frame_payload.begin(),
96 frame_payload.end());
97
98 frame_sequence_buf = frame_sequence_buf.last(
99 frame_sequence_buf.size() - hdr_res->second.payload_size());
100 }
101
102 auto decode_res =
103 classic_protocol::decode<Msg>(net::buffer(payload_buf), caps);
104 if (!decode_res) return stdx::make_unexpected(decode_res.error());
105
106 return decode_res->second;
107 } else {
108 auto &recv_buf = src_channel->recv_plain_view();
109
110 auto decode_res =
111 classic_protocol::decode<classic_protocol::frame::Frame<Msg>>(
112 net::buffer(recv_buf), caps);
113 if (!decode_res) return stdx::make_unexpected(decode_res.error());
114
115 return decode_res->second.payload();
116 }
117 }
118
119 template <class Msg>
121 Channel *src_channel, ClassicProtocolState *src_protocol) {
122 return recv_msg<Msg>(src_channel, src_protocol,
123 src_protocol->shared_capabilities());
124 }
125
126 template <class Msg>
128 Channel *dst_channel, ClassicProtocolState *dst_protocol, Msg msg,
130 auto encode_res = classic_protocol::encode(
132 std::forward<Msg>(msg)),
133 caps, net::dynamic_buffer(dst_channel->send_plain_buffer()));
134 if (!encode_res) return encode_res;
135
136 return dst_channel->flush_to_send_buf();
137 }
138
139 template <class Msg>
141 Channel *dst_channel, ClassicProtocolState *dst_protocol, Msg msg) {
142 return send_msg<Msg>(dst_channel, dst_protocol, std::forward<Msg>(msg),
143 dst_protocol->shared_capabilities());
144 }
145};
146
147/**
148 * receive a StmtExecute message from a channel.
149 *
150 * specialization of recv_msg<> as StmtExecute needs a the data from the
151 * StmtPrepareOk.
152 */
153template <>
155 std::error_code>
158 Channel *src_channel, ClassicProtocolState *src_protocol,
161
162 auto read_res = ClassicFrame::recv_frame_sequence(src_channel, src_protocol);
163 if (!read_res) return stdx::make_unexpected(read_res.error());
164
165 const auto &recv_buf = src_channel->recv_plain_view();
166
167 auto frame_decode_res = classic_protocol::decode<
169 net::buffer(recv_buf), caps);
170 if (!frame_decode_res) {
171 return stdx::make_unexpected(frame_decode_res.error());
172 }
173
174 src_protocol->seq_id(frame_decode_res->second.seq_id());
175
176 auto decode_res = classic_protocol::decode<msg_type>(
177 net::buffer(frame_decode_res->second.payload().value()), caps,
178 [src_protocol](auto stmt_id)
179 -> stdx::expected<std::vector<msg_type::ParamDef>, std::error_code> {
180 const auto it = src_protocol->prepared_statements().find(stmt_id);
181 if (it == src_protocol->prepared_statements().end()) {
182 return stdx::make_unexpected(make_error_code(
183 classic_protocol::codec_errc::statement_id_not_found));
184 }
185
186 std::vector<msg_type::ParamDef> params;
187 params.reserve(it->second.parameters.size());
188
189 for (const auto &param : it->second.parameters) {
190 params.emplace_back(param.type_and_flags);
191 }
192
193 return params;
194 });
195 if (!decode_res) return stdx::make_unexpected(decode_res.error());
196
197 return decode_res->second;
198}
199
200#endif
SSL aware socket buffers.
Definition: channel.h:64
stdx::expected< size_t, std::error_code > flush_to_send_buf()
flush data to the send buffer.
Definition: channel.cc:152
const recv_buffer_type & payload_buffer() const
payload buffer for
Definition: channel.h:257
recv_buffer_type & send_plain_buffer()
unencrypted data to be sent to the socket.
Definition: channel.cc:277
const recv_view_type & recv_plain_view() const
decrypted data after a recv().
Definition: channel.cc:283
Definition: classic_frame.h:35
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:44
static stdx::expected< Msg, std::error_code > recv_msg(Channel *src_channel, ClassicProtocolState *src_protocol)
Definition: classic_frame.h:120
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:127
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:127
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:172
static constexpr uint8_t cmd_byte()
Definition: classic_frame.h:57
static stdx::expected< size_t, std::error_code > send_msg(Channel *dst_channel, ClassicProtocolState *dst_protocol, Msg msg)
Definition: classic_frame.h:140
static stdx::expected< Msg, std::error_code > recv_msg(Channel *src_channel, ClassicProtocolState *src_protocol, classic_protocol::capabilities::value_type caps)
receive a classic protocol message frame from a channel.
Definition: classic_frame.h:65
static stdx::expected< void, std::error_code > ensure_has_full_frame(Channel *src_channel, ClassicProtocolState *src_protocol)
Definition: classic_frame.cc:152
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_connection_base.h:52
uint8_t & seq_id()
Definition: classic_connection_base.h:118
classic_protocol::capabilities::value_type shared_capabilities() const
Definition: classic_connection_base.h:94
Codec for a type.
Definition: classic_protocol_codec_base.h:72
execute a prepared statement.
Definition: classic_protocol_message.h:1090
Definition: classic_protocol_frame.h:85
Definition: expected.h:944
borrowable::message::client::StmtExecute< true > StmtExecute
Definition: classic_protocol_message.h:1474
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:663
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:420
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:125