MySQL 8.0.40
Source Code Documentation
channel.h
Go to the documentation of this file.
1/*
2Copyright (c) 2020, 2024, Oracle and/or its affiliates.
3
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License, version 2.0,
6as published by the Free Software Foundation.
7
8This program is designed to work with certain software (including
9but not limited to OpenSSL) that is licensed under separate terms,
10as designated in a particular file or component or in included license
11documentation. The authors of MySQL hereby grant you an additional
12permission to link the program and your derivative works with the
13separately licensed software that they have either included with
14the program or referenced in the documentation.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef MYSQL_ROUTER_CHANNEL_INCLUDED
27#define MYSQL_ROUTER_CHANNEL_INCLUDED
28
29#include <memory>
30#include <system_error>
31#include <type_traits>
32#include <vector>
33
34#ifdef _WIN32
35// include winsock2.h before openssl/ssl.h
36#include <windows.h>
37#include <winsock2.h>
38#include <ws2tcpip.h>
39#endif
40
41#include <openssl/ssl.h>
42
49
50/**
51 * SSL aware socket buffers.
52 *
53 * manages the raw and plaintext socket buffers of connection which may switch
54 * to TLS.
55 *
56 * an external user like a socket class can
57 *
58 * - receive from a socket and store the socket data into the recv_buffer().
59 * - send to a socket from the send_buffer().
60 *
61 * Once init_ssl() is called, the recv_plain() and write_plain() methods
62 * transparently decrypt and encrypt.
63 */
64class Channel {
65 public:
66 Channel() = default;
67
69 std::vector<uint8_t, default_init_allocator<uint8_t>>;
72
73 explicit Channel(Ssl ssl) : ssl_{std::move(ssl)} {}
74
75 /**
76 * initialize the SSL session.
77 */
78 void init_ssl(SSL_CTX *ssl_ctx) {
79 ssl_.reset(SSL_new(ssl_ctx));
80 // the BIOs are owned by the SSL
81 SSL_set_bio(ssl_.get(), BIO_new(BIO_s_mem()), BIO_new(BIO_s_mem()));
82 }
83
84 /**
85 * accept a TLS session.
86 *
87 * expects a Tls::ClientHello in the recv_buf.
88 */
90
91 /**
92 * connect a TLS session.
93 *
94 *
95 */
98
99 /**
100 * @return on success, true if shutdown is finished, false if not
101 * @return on failure, an error-code
102 */
104
105 /**
106 * write unencrypted net::dynamic_buffer to the channel.
107 *
108 * if the channel has an ssl session it transparently encrypts before
109 * the data is appended to the send_buf()
110 */
111 template <class DynamicBuffer>
112 typename std::enable_if<net::is_dynamic_buffer<DynamicBuffer>::value,
114 write(DynamicBuffer &dyn_buf) {
115 auto orig_size = dyn_buf.size();
116 size_t transferred{};
117
118 auto write_res = write_plain(dyn_buf.data(0, orig_size));
119 if (!write_res) {
120 return write_res.get_unexpected();
121 }
122
123 transferred += write_res.value();
124 dyn_buf.consume(write_res.value());
125
126 return transferred;
127 }
128
129 /**
130 * write unencrypted net::const_buffer to the channel.
131 *
132 * if the channel has an ssl session it transparently encrypts before
133 * the data is appended to the send_buf()
134 */
136 return write_plain(b);
137 }
138
139 /**
140 * read unencrypted data from channel to a net::dynamic_buffer.
141 *
142 * if the channel has a ssl session in transparently decrypts before
143 * the data is appending to the recv_plain_buf()
144 */
145 template <class DynamicBuffer>
147 size_t sz) {
148 auto orig_size = dyn_buf.size();
149 auto grow_size = sz;
150 size_t transferred{};
151
152 dyn_buf.grow(grow_size);
153
154 const auto res_res = read_plain(dyn_buf.data(orig_size, grow_size));
155 if (!res_res) {
156 dyn_buf.shrink(grow_size);
157 return res_res.get_unexpected();
158 }
159
160 transferred += res_res.value();
161 dyn_buf.shrink(grow_size - res_res.value());
162
163 return transferred;
164 }
165
167
168 /**
169 * write unencrypted data from a net::const_buffer to the channel.
170 *
171 * call flush_to_send_buf() ensure data is written to the
172 * send-buffers for the socket.
173 *
174 * @see flush_to_send_buf()
175 */
177 const net::const_buffer &b);
178
179 /**
180 * read plaintext data from recv_plain_buffer() into b.
181 */
183 const net::mutable_buffer &b);
184
185 /**
186 * flush data from receive buffer to recv_plain_buffer().
187 *
188 * if an SSL session is active, flush_to_recv_buf() ensures that data
189 * encrypted data gets decrypted and added to the recv_plain_buffer().
190 *
191 * In case no SSL session is active, it is a no-op.
192 */
194
195 /**
196 * flush data to the send buffer.
197 *
198 * if write_plain() was used and an SSL session is active,
199 * flush_to_send_buf() ensures that data plaintext data gets encrypted and
200 * added to the send_buf().
201 *
202 * In case no SSL session is active, it is a no-op.
203 */
205
206 /**
207 * bytes wanted.
208 *
209 * signals to the socket layer how many bytes should be at least read into the
210 * buffer.
211 */
212 void want_recv(size_t wanted) { want_recv_ = wanted; }
213
214 /**
215 * bytes wanted.
216 *
217 * @return bytes wanted to be received at least.
218 */
219 size_t want_recv() const { return want_recv_; }
220
221 /**
222 * buffer of data that was received from the socket.
223 */
225
226 /**
227 * buffer of data to be sent to the socket.
228 *
229 * written into by write(), write_plain(), flush_to_send_buf().
230 */
232
233 /**
234 * unencrypted data to be sent to the socket.
235 */
237
238 /**
239 * buffer of data that was received from the socket.
240 *
241 */
242 const recv_buffer_type &recv_buffer() const { return recv_buffer_; }
243
244 /**
245 * network data after a recv().
246 */
247 const recv_view_type &recv_view() const;
248
249 /**
250 * buffer of data to be sent to the socket.
251 */
252 const recv_buffer_type &send_buffer() const { return send_buffer_; }
253
254 /**
255 * payload buffer for
256 */
258
260
261 /**
262 * decrypted data after a recv().
263 */
264 const recv_view_type &recv_plain_view() const;
265
266 // consume count bytes from the recv_buffers.
267 void consume_raw(size_t count);
268
269 // consume count bytes from the recv_plain_buffers.
270 void consume_plain(size_t count);
271
272 // discard the data from the recv-buffer that have been 'consumed'
273 void view_discard_raw();
274
275 // discard the data from the recv-plain-buffer that have been 'consumed'
276 void view_discard_plain();
277
278 // updated the recv-buffer's view with the recv-buffer.
279 void view_sync_raw();
280
281 // updated the recv-plain-buffer's view with the recv-plain-buffer.
282 void view_sync_plain();
283
284 /**
285 * mark channel as containing TLS data in the recv_buffer().
286 *
287 * it is independent of calling init_tls() as the channel
288 * may be used to transfer encrypted data as is without
289 * ever call init_ssl().
290 */
291 void is_tls(bool v) { is_tls_ = v; }
292
293 /**
294 * check if connection switched to TLS.
295 */
296 bool is_tls() const { return is_tls_; }
297
298 /**
299 * get access to the raw SSL handle.
300 *
301 * can be used to call:
302 *
303 * - SSL_get_cipher_name()
304 * - SSL_version()
305 *
306 * @retval nullptr if channel has no SSL initialized.
307 */
308 SSL *ssl() const { return ssl_.get(); }
309
310 /**
311 * release the internal Ssl structure.
312 */
314
315 private:
316 size_t want_recv_{};
317
322
324
327
328 bool is_tls_{false};
329
331};
332
333#endif
SSL aware socket buffers.
Definition: channel.h:64
Channel()=default
stdx::expected< size_t, std::error_code > flush_from_recv_buf()
flush data from receive buffer to recv_plain_buffer().
Definition: channel.cc:114
stdx::expected< size_t, std::error_code > flush_to_send_buf()
flush data to the send buffer.
Definition: channel.cc:152
stdx::expected< bool, std::error_code > tls_shutdown()
Definition: channel.cc:63
stdx::expected< void, std::error_code > tls_accept()
accept a TLS session.
Definition: channel.cc:37
void view_discard_raw()
Definition: channel.cc:304
stdx::expected< size_t, std::error_code > write(const net::const_buffer &b)
write unencrypted net::const_buffer to the channel.
Definition: channel.h:135
recv_buffer_type send_buffer_
Definition: channel.h:326
recv_buffer_type send_plain_buffer_
Definition: channel.h:325
void view_discard_plain()
Definition: channel.cc:309
const recv_buffer_type & recv_buffer() const
buffer of data that was received from the socket.
Definition: channel.h:242
void consume_plain(size_t count)
Definition: channel.cc:293
size_t want_recv() const
bytes wanted.
Definition: channel.h:219
stdx::expected< size_t, std::error_code > read(DynamicBuffer &dyn_buf, size_t sz)
read unencrypted data from channel to a net::dynamic_buffer.
Definition: channel.h:146
const recv_buffer_type & send_buffer() const
buffer of data to be sent to the socket.
Definition: channel.h:252
void init_ssl(SSL_CTX *ssl_ctx)
initialize the SSL session.
Definition: channel.h:78
void is_tls(bool v)
mark channel as containing TLS data in the recv_buffer().
Definition: channel.h:291
void want_recv(size_t wanted)
bytes wanted.
Definition: channel.h:212
recv_buffer_type & payload_buffer()
Definition: channel.h:259
stdx::expected< size_t, std::error_code > read_plain(const net::mutable_buffer &b)
read plaintext data from recv_plain_buffer() into b.
Definition: channel.cc:90
Ssl ssl_
Definition: channel.h:330
SSL * ssl() const
get access to the raw SSL handle.
Definition: channel.h:308
std::enable_if< net::is_dynamic_buffer< DynamicBuffer >::value, stdx::expected< size_t, std::error_code > >::type write(DynamicBuffer &dyn_buf)
write unencrypted net::dynamic_buffer to the channel.
Definition: channel.h:114
Ssl release_ssl()
release the internal Ssl structure.
Definition: channel.cc:271
const recv_buffer_type & payload_buffer() const
payload buffer for
Definition: channel.h:257
Channel(Ssl ssl)
Definition: channel.h:73
size_t want_recv_
Definition: channel.h:316
recv_buffer_type & send_plain_buffer()
unencrypted data to be sent to the socket.
Definition: channel.cc:277
recv_view_type recv_view_
Definition: channel.h:319
recv_buffer_type recv_buffer_
Definition: channel.h:318
recv_view_type recv_plain_view_
Definition: channel.h:321
mysql_harness::Ssl Ssl
Definition: channel.h:71
void view_sync_plain()
Definition: channel.cc:320
void view_sync_raw()
Definition: channel.cc:318
recv_buffer_type & send_buffer()
buffer of data to be sent to the socket.
Definition: channel.h:231
stdx::expected< size_t, std::error_code > read_to_plain(size_t sz)
Definition: channel.cc:219
stdx::expected< void, std::error_code > tls_connect()
connect a TLS session.
Definition: channel.cc:48
const recv_view_type & recv_plain_view() const
decrypted data after a recv().
Definition: channel.cc:283
stdx::expected< size_t, std::error_code > write_plain(const net::const_buffer &b)
write unencrypted data from a net::const_buffer to the channel.
Definition: channel.cc:79
std::vector< uint8_t, default_init_allocator< uint8_t > > recv_buffer_type
Definition: channel.h:69
bool tls_init_is_finished()
Definition: channel.cc:59
stdx::span< typename recv_buffer_type::value_type > recv_view_type
Definition: channel.h:70
bool is_tls_
Definition: channel.h:328
bool is_tls() const
check if connection switched to TLS.
Definition: channel.h:296
recv_buffer_type & recv_buffer()
buffer of data that was received from the socket.
Definition: channel.h:224
recv_buffer_type payload_buffer_
Definition: channel.h:323
const recv_view_type & recv_view() const
network data after a recv().
Definition: channel.cc:281
void consume_raw(size_t count)
Definition: channel.cc:287
recv_buffer_type recv_plain_buffer_
Definition: channel.h:320
Definition: buffer.h:135
Definition: buffer.h:113
Definition: expected.h:944
static int count
Definition: myisam_ftdump.cc:43
std::unique_ptr< SSL, mysql_harness::impl::Deleter_SSL > Ssl
Definition: tls_types.h:48
Definition: gcs_xcom_synode.h:64
required string type
Definition: replication_group_member_actions.proto:34