MySQL 8.3.0
Source Code Documentation
classic_frame.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2022, 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 ROUTING_CLASSIC_FRAME_INCLUDED
26#define ROUTING_CLASSIC_FRAME_INCLUDED
27
28#include <system_error>
29
30#include "channel.h"
33
35 public:
37 Channel *src_channel, ClassicProtocolState *src_protocol);
38
39 [[nodiscard]] static stdx::expected<void, std::error_code>
40 ensure_has_full_frame(Channel *src_channel,
41 ClassicProtocolState *src_protocol);
42
43 /**
44 * recv a full message sequence into the channel's recv_plain_buffer()
45 */
47 recv_frame_sequence(Channel *src_channel, ClassicProtocolState *src_protocol);
48
50 Channel *src_channel, ClassicProtocolState *src_protocol);
51
53 Channel *src_channel, ClassicProtocolState *src_protocol);
54
55 template <class T>
56 static constexpr uint8_t cmd_byte() {
58 }
59
60 /**
61 * receive a classic protocol message frame from a channel.
62 */
63 template <class Msg>
65 Channel *src_channel, ClassicProtocolState *src_protocol,
67 auto read_res =
68 ClassicFrame::recv_frame_sequence(src_channel, src_protocol);
69 if (!read_res) return stdx::make_unexpected(read_res.error());
70
71 auto num_of_frames = *read_res;
72 if (num_of_frames > 1) {
73 // more than one frame.
74 auto frame_sequence_buf = src_channel->recv_plain_view();
75
76 // assemble the payload from multiple frames.
77
78 auto &payload_buf = src_channel->payload_buffer();
79 payload_buf.clear();
80
81 while (!frame_sequence_buf.empty()) {
82 auto hdr_res =
83 classic_protocol::decode<classic_protocol::frame::Header>(
84 net::buffer(frame_sequence_buf), caps);
85 if (!hdr_res) return stdx::make_unexpected(hdr_res.error());
86
87 // skip the hdr.
88 frame_sequence_buf =
89 frame_sequence_buf.last(frame_sequence_buf.size() - hdr_res->first);
90
91 auto frame_payload =
92 frame_sequence_buf.first(hdr_res->second.payload_size());
93
94 payload_buf.insert(payload_buf.end(), frame_payload.begin(),
95 frame_payload.end());
96
97 frame_sequence_buf = frame_sequence_buf.last(
98 frame_sequence_buf.size() - hdr_res->second.payload_size());
99 }
100
101 auto decode_res =
102 classic_protocol::decode<Msg>(net::buffer(payload_buf), caps);
103 if (!decode_res) return stdx::make_unexpected(decode_res.error());
104
105 return decode_res->second;
106 } else {
107 auto &recv_buf = src_channel->recv_plain_view();
108
109 auto decode_res =
110 classic_protocol::decode<classic_protocol::frame::Frame<Msg>>(
111 net::buffer(recv_buf), caps);
112 if (!decode_res) return stdx::make_unexpected(decode_res.error());
113
114 return decode_res->second.payload();
115 }
116 }
117
118 template <class Msg>
120 Channel *src_channel, ClassicProtocolState *src_protocol) {
121 return recv_msg<Msg>(src_channel, src_protocol,
122 src_protocol->shared_capabilities());
123 }
124
125 template <class Msg>
127 Channel *dst_channel, ClassicProtocolState *dst_protocol, Msg msg,
129 auto encode_res = classic_protocol::encode(
131 std::forward<Msg>(msg)),
132 caps, net::dynamic_buffer(dst_channel->send_plain_buffer()));
133 if (!encode_res) return encode_res;
134
135 return dst_channel->flush_to_send_buf();
136 }
137
138 template <class Msg>
140 Channel *dst_channel, ClassicProtocolState *dst_protocol, Msg msg) {
141 return send_msg<Msg>(dst_channel, dst_protocol, std::forward<Msg>(msg),
142 dst_protocol->shared_capabilities());
143 }
144
145 /**
146 * set attributes from the Ok message in the TraceEvent.
147 */
148 static void trace_set_attributes(
149 TraceEvent *ev, ClassicProtocolState *src_protocol,
151
152 /**
153 * set attributes from the Eof message in the TraceEvent.
154 */
155 static void trace_set_attributes(
156 TraceEvent *ev, ClassicProtocolState *src_protocol,
158
159 /**
160 * set attributes from the Eof message in the TraceEvent.
161 */
162 static void trace_set_attributes(
163 TraceEvent *ev, ClassicProtocolState *src_protocol,
165};
166
167/**
168 * receive a StmtExecute message from a channel.
169 *
170 * specialization of recv_msg<> as StmtExecute needs a the data from the
171 * StmtPrepareOk.
172 */
173template <>
175 std::error_code>
178 Channel *src_channel, ClassicProtocolState *src_protocol,
181
182 auto read_res = ClassicFrame::recv_frame_sequence(src_channel, src_protocol);
183 if (!read_res) return stdx::make_unexpected(read_res.error());
184
185 const auto &recv_buf = src_channel->recv_plain_view();
186
187 auto frame_decode_res = classic_protocol::decode<
189 net::buffer(recv_buf), caps);
190 if (!frame_decode_res) {
191 return stdx::make_unexpected(frame_decode_res.error());
192 }
193
194 src_protocol->seq_id(frame_decode_res->second.seq_id());
195
196 auto decode_res = classic_protocol::decode<msg_type>(
197 net::buffer(frame_decode_res->second.payload().value()), caps,
198 [src_protocol](auto stmt_id)
199 -> stdx::expected<std::vector<msg_type::ParamDef>, std::error_code> {
200 const auto it = src_protocol->prepared_statements().find(stmt_id);
201 if (it == src_protocol->prepared_statements().end()) {
202 return stdx::make_unexpected(make_error_code(
203 classic_protocol::codec_errc::statement_id_not_found));
204 }
205
206 std::vector<msg_type::ParamDef> params;
207 params.reserve(it->second.parameters.size());
208
209 for (const auto &param : it->second.parameters) {
210 params.emplace_back(param.type_and_flags, std::string_view{},
211 param.param_already_sent);
212 }
213
214 return params;
215 });
216 if (!decode_res) return stdx::make_unexpected(decode_res.error());
217
218 return decode_res->second;
219}
220
221#endif
SSL aware socket buffers.
Definition: channel.h:63
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:256
recv_buffer_type & send_plain_buffer()
unencrypted data to be sent to the socket.
Definition: channel.cc:276
const recv_view_type & recv_plain_view() const
decrypted data after a recv().
Definition: channel.cc:282
Definition: classic_frame.h:34
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:119
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:126
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:56
static stdx::expected< size_t, std::error_code > send_msg(Channel *dst_channel, ClassicProtocolState *dst_protocol, Msg msg)
Definition: classic_frame.h:139
static void trace_set_attributes(TraceEvent *ev, ClassicProtocolState *src_protocol, const classic_protocol::borrowed::message::server::Ok &msg)
set attributes from the Ok message in the TraceEvent.
Definition: classic_frame.cc:278
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:64
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:54
uint8_t & seq_id()
Definition: classic_connection_base.h:113
classic_protocol::capabilities::value_type shared_capabilities() const
Definition: classic_connection_base.h:89
Codec for a type.
Definition: classic_protocol_codec_base.h:71
execute a prepared statement.
Definition: classic_protocol_message.h:1089
Definition: classic_protocol_frame.h:84
Definition: expected.h:943
borrowable::message::client::StmtExecute< true > StmtExecute
Definition: classic_protocol_message.h:1487
borrowable::message::server::Eof< true > Eof
Definition: classic_protocol_message.h:1459
borrowable::message::server::Error< true > Error
Definition: classic_protocol_message.h:1458
borrowable::message::server::Ok< true > Ok
Definition: classic_protocol_message.h:1457
std::bitset< 32 > value_type
Definition: classic_protocol_constants.h:72
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:83
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:118
dynamic_vector_buffer< T, Allocator > dynamic_buffer(std::vector< T, Allocator > &vec) noexcept
Definition: buffer.h:660
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:417
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:124
Definition: trace_span.h:34