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