]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/ssl/stream.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / asio / ssl / stream.hpp
CommitLineData
7c673cae
FG
1//
2// ssl/stream.hpp
3// ~~~~~~~~~~~~~~
4//
92f5a8d4 5// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_SSL_STREAM_HPP
12#define BOOST_ASIO_SSL_STREAM_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19
b32b8144
FG
20#include <boost/asio/async_result.hpp>
21#include <boost/asio/detail/buffer_sequence_adapter.hpp>
22#include <boost/asio/detail/handler_type_requirements.hpp>
92f5a8d4 23#include <boost/asio/detail/non_const_lvalue.hpp>
b32b8144
FG
24#include <boost/asio/detail/noncopyable.hpp>
25#include <boost/asio/detail/type_traits.hpp>
26#include <boost/asio/ssl/context.hpp>
27#include <boost/asio/ssl/detail/buffered_handshake_op.hpp>
28#include <boost/asio/ssl/detail/handshake_op.hpp>
29#include <boost/asio/ssl/detail/io.hpp>
30#include <boost/asio/ssl/detail/read_op.hpp>
31#include <boost/asio/ssl/detail/shutdown_op.hpp>
32#include <boost/asio/ssl/detail/stream_core.hpp>
33#include <boost/asio/ssl/detail/write_op.hpp>
34#include <boost/asio/ssl/stream_base.hpp>
7c673cae
FG
35
36#include <boost/asio/detail/push_options.hpp>
37
38namespace boost {
39namespace asio {
40namespace ssl {
41
7c673cae
FG
42/// Provides stream-oriented functionality using SSL.
43/**
44 * The stream class template provides asynchronous and blocking stream-oriented
45 * functionality using SSL.
46 *
47 * @par Thread Safety
48 * @e Distinct @e objects: Safe.@n
49 * @e Shared @e objects: Unsafe. The application must also ensure that all
50 * asynchronous operations are performed within the same implicit or explicit
51 * strand.
52 *
53 * @par Example
54 * To use the SSL stream template with an ip::tcp::socket, you would write:
55 * @code
92f5a8d4 56 * boost::asio::io_context my_context;
7c673cae 57 * boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
92f5a8d4 58 * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);
7c673cae
FG
59 * @endcode
60 *
61 * @par Concepts:
62 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
63 */
64template <typename Stream>
65class stream :
66 public stream_base,
67 private noncopyable
68{
69public:
70 /// The native handle type of the SSL stream.
71 typedef SSL* native_handle_type;
72
73 /// Structure for use with deprecated impl_type.
74 struct impl_struct
75 {
76 SSL* ssl;
77 };
78
7c673cae
FG
79 /// The type of the next layer.
80 typedef typename remove_reference<Stream>::type next_layer_type;
81
82 /// The type of the lowest layer.
83 typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
84
b32b8144
FG
85 /// The type of the executor associated with the object.
86 typedef typename lowest_layer_type::executor_type executor_type;
87
88#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
7c673cae
FG
89 /// Construct a stream.
90 /**
91 * This constructor creates a stream and initialises the underlying stream
92 * object.
93 *
94 * @param arg The argument to be passed to initialise the underlying stream.
95 *
96 * @param ctx The SSL context to be used for the stream.
97 */
98 template <typename Arg>
b32b8144
FG
99 stream(Arg&& arg, context& ctx)
100 : next_layer_(BOOST_ASIO_MOVE_CAST(Arg)(arg)),
92f5a8d4 101 core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
b32b8144
FG
102 {
103 }
104#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
105 template <typename Arg>
7c673cae
FG
106 stream(Arg& arg, context& ctx)
107 : next_layer_(arg),
92f5a8d4 108 core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
7c673cae 109 {
7c673cae 110 }
b32b8144 111#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
7c673cae
FG
112
113 /// Destructor.
b32b8144
FG
114 /**
115 * @note A @c stream object must not be destroyed while there are pending
116 * asynchronous operations associated with it.
117 */
7c673cae
FG
118 ~stream()
119 {
120 }
121
b32b8144 122 /// Get the executor associated with the object.
7c673cae 123 /**
b32b8144 124 * This function may be used to obtain the executor object that the stream
7c673cae
FG
125 * uses to dispatch handlers for asynchronous operations.
126 *
b32b8144 127 * @return A copy of the executor that stream will use to dispatch handlers.
7c673cae 128 */
b32b8144
FG
129 executor_type get_executor() BOOST_ASIO_NOEXCEPT
130 {
131 return next_layer_.lowest_layer().get_executor();
132 }
133
7c673cae
FG
134 /// Get the underlying implementation in the native type.
135 /**
136 * This function may be used to obtain the underlying implementation of the
137 * context. This is intended to allow access to context functionality that is
138 * not otherwise provided.
139 *
140 * @par Example
141 * The native_handle() function returns a pointer of type @c SSL* that is
142 * suitable for passing to functions such as @c SSL_get_verify_result and
143 * @c SSL_get_peer_certificate:
144 * @code
92f5a8d4 145 * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);
7c673cae
FG
146 *
147 * // ... establish connection and perform handshake ...
148 *
149 * if (X509* cert = SSL_get_peer_certificate(sock.native_handle()))
150 * {
151 * if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK)
152 * {
153 * // ...
154 * }
155 * }
156 * @endcode
157 */
158 native_handle_type native_handle()
159 {
160 return core_.engine_.native_handle();
161 }
162
7c673cae
FG
163 /// Get a reference to the next layer.
164 /**
165 * This function returns a reference to the next layer in a stack of stream
166 * layers.
167 *
168 * @return A reference to the next layer in the stack of stream layers.
169 * Ownership is not transferred to the caller.
170 */
171 const next_layer_type& next_layer() const
172 {
173 return next_layer_;
174 }
175
176 /// Get a reference to the next layer.
177 /**
178 * This function returns a reference to the next layer in a stack of stream
179 * layers.
180 *
181 * @return A reference to the next layer in the stack of stream layers.
182 * Ownership is not transferred to the caller.
183 */
184 next_layer_type& next_layer()
185 {
186 return next_layer_;
187 }
188
189 /// Get a reference to the lowest layer.
190 /**
191 * This function returns a reference to the lowest layer in a stack of
192 * stream layers.
193 *
194 * @return A reference to the lowest layer in the stack of stream layers.
195 * Ownership is not transferred to the caller.
196 */
197 lowest_layer_type& lowest_layer()
198 {
199 return next_layer_.lowest_layer();
200 }
201
202 /// Get a reference to the lowest layer.
203 /**
204 * This function returns a reference to the lowest layer in a stack of
205 * stream layers.
206 *
207 * @return A reference to the lowest layer in the stack of stream layers.
208 * Ownership is not transferred to the caller.
209 */
210 const lowest_layer_type& lowest_layer() const
211 {
212 return next_layer_.lowest_layer();
213 }
214
215 /// Set the peer verification mode.
216 /**
217 * This function may be used to configure the peer verification mode used by
218 * the stream. The new mode will override the mode inherited from the context.
219 *
220 * @param v A bitmask of peer verification modes. See @ref verify_mode for
221 * available values.
222 *
223 * @throws boost::system::system_error Thrown on failure.
224 *
225 * @note Calls @c SSL_set_verify.
226 */
227 void set_verify_mode(verify_mode v)
228 {
229 boost::system::error_code ec;
230 set_verify_mode(v, ec);
231 boost::asio::detail::throw_error(ec, "set_verify_mode");
232 }
233
234 /// Set the peer verification mode.
235 /**
236 * This function may be used to configure the peer verification mode used by
237 * the stream. The new mode will override the mode inherited from the context.
238 *
239 * @param v A bitmask of peer verification modes. See @ref verify_mode for
240 * available values.
241 *
242 * @param ec Set to indicate what error occurred, if any.
243 *
244 * @note Calls @c SSL_set_verify.
245 */
b32b8144 246 BOOST_ASIO_SYNC_OP_VOID set_verify_mode(
7c673cae
FG
247 verify_mode v, boost::system::error_code& ec)
248 {
b32b8144
FG
249 core_.engine_.set_verify_mode(v, ec);
250 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
251 }
252
253 /// Set the peer verification depth.
254 /**
255 * This function may be used to configure the maximum verification depth
256 * allowed by the stream.
257 *
258 * @param depth Maximum depth for the certificate chain verification that
259 * shall be allowed.
260 *
261 * @throws boost::system::system_error Thrown on failure.
262 *
263 * @note Calls @c SSL_set_verify_depth.
264 */
265 void set_verify_depth(int depth)
266 {
267 boost::system::error_code ec;
268 set_verify_depth(depth, ec);
269 boost::asio::detail::throw_error(ec, "set_verify_depth");
270 }
271
272 /// Set the peer verification depth.
273 /**
274 * This function may be used to configure the maximum verification depth
275 * allowed by the stream.
276 *
277 * @param depth Maximum depth for the certificate chain verification that
278 * shall be allowed.
279 *
280 * @param ec Set to indicate what error occurred, if any.
281 *
282 * @note Calls @c SSL_set_verify_depth.
283 */
b32b8144 284 BOOST_ASIO_SYNC_OP_VOID set_verify_depth(
7c673cae
FG
285 int depth, boost::system::error_code& ec)
286 {
b32b8144
FG
287 core_.engine_.set_verify_depth(depth, ec);
288 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
289 }
290
291 /// Set the callback used to verify peer certificates.
292 /**
293 * This function is used to specify a callback function that will be called
294 * by the implementation when it needs to verify a peer certificate.
295 *
296 * @param callback The function object to be used for verifying a certificate.
297 * The function signature of the handler must be:
298 * @code bool verify_callback(
299 * bool preverified, // True if the certificate passed pre-verification.
300 * verify_context& ctx // The peer certificate and other context.
301 * ); @endcode
302 * The return value of the callback is true if the certificate has passed
303 * verification, false otherwise.
304 *
305 * @throws boost::system::system_error Thrown on failure.
306 *
307 * @note Calls @c SSL_set_verify.
308 */
309 template <typename VerifyCallback>
310 void set_verify_callback(VerifyCallback callback)
311 {
312 boost::system::error_code ec;
313 this->set_verify_callback(callback, ec);
314 boost::asio::detail::throw_error(ec, "set_verify_callback");
315 }
316
317 /// Set the callback used to verify peer certificates.
318 /**
319 * This function is used to specify a callback function that will be called
320 * by the implementation when it needs to verify a peer certificate.
321 *
322 * @param callback The function object to be used for verifying a certificate.
323 * The function signature of the handler must be:
324 * @code bool verify_callback(
325 * bool preverified, // True if the certificate passed pre-verification.
326 * verify_context& ctx // The peer certificate and other context.
327 * ); @endcode
328 * The return value of the callback is true if the certificate has passed
329 * verification, false otherwise.
330 *
331 * @param ec Set to indicate what error occurred, if any.
332 *
333 * @note Calls @c SSL_set_verify.
334 */
335 template <typename VerifyCallback>
b32b8144 336 BOOST_ASIO_SYNC_OP_VOID set_verify_callback(VerifyCallback callback,
7c673cae
FG
337 boost::system::error_code& ec)
338 {
b32b8144 339 core_.engine_.set_verify_callback(
7c673cae 340 new detail::verify_callback<VerifyCallback>(callback), ec);
b32b8144 341 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
342 }
343
344 /// Perform SSL handshaking.
345 /**
346 * This function is used to perform SSL handshaking on the stream. The
347 * function call will block until handshaking is complete or an error occurs.
348 *
349 * @param type The type of handshaking to be performed, i.e. as a client or as
350 * a server.
351 *
352 * @throws boost::system::system_error Thrown on failure.
353 */
354 void handshake(handshake_type type)
355 {
356 boost::system::error_code ec;
357 handshake(type, ec);
358 boost::asio::detail::throw_error(ec, "handshake");
359 }
360
361 /// Perform SSL handshaking.
362 /**
363 * This function is used to perform SSL handshaking on the stream. The
364 * function call will block until handshaking is complete or an error occurs.
365 *
366 * @param type The type of handshaking to be performed, i.e. as a client or as
367 * a server.
368 *
369 * @param ec Set to indicate what error occurred, if any.
370 */
b32b8144 371 BOOST_ASIO_SYNC_OP_VOID handshake(handshake_type type,
7c673cae
FG
372 boost::system::error_code& ec)
373 {
374 detail::io(next_layer_, core_, detail::handshake_op(type), ec);
b32b8144 375 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
376 }
377
378 /// Perform SSL handshaking.
379 /**
380 * This function is used to perform SSL handshaking on the stream. The
381 * function call will block until handshaking is complete or an error occurs.
382 *
383 * @param type The type of handshaking to be performed, i.e. as a client or as
384 * a server.
385 *
386 * @param buffers The buffered data to be reused for the handshake.
387 *
388 * @throws boost::system::system_error Thrown on failure.
389 */
390 template <typename ConstBufferSequence>
391 void handshake(handshake_type type, const ConstBufferSequence& buffers)
392 {
393 boost::system::error_code ec;
394 handshake(type, buffers, ec);
395 boost::asio::detail::throw_error(ec, "handshake");
396 }
397
398 /// Perform SSL handshaking.
399 /**
400 * This function is used to perform SSL handshaking on the stream. The
401 * function call will block until handshaking is complete or an error occurs.
402 *
403 * @param type The type of handshaking to be performed, i.e. as a client or as
404 * a server.
405 *
406 * @param buffers The buffered data to be reused for the handshake.
407 *
408 * @param ec Set to indicate what error occurred, if any.
409 */
410 template <typename ConstBufferSequence>
b32b8144 411 BOOST_ASIO_SYNC_OP_VOID handshake(handshake_type type,
7c673cae
FG
412 const ConstBufferSequence& buffers, boost::system::error_code& ec)
413 {
414 detail::io(next_layer_, core_,
415 detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), ec);
b32b8144 416 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
417 }
418
419 /// Start an asynchronous SSL handshake.
420 /**
421 * This function is used to asynchronously perform an SSL handshake on the
422 * stream. This function call always returns immediately.
423 *
424 * @param type The type of handshaking to be performed, i.e. as a client or as
425 * a server.
426 *
427 * @param handler The handler to be called when the handshake operation
428 * completes. Copies will be made of the handler as required. The equivalent
429 * function signature of the handler must be:
430 * @code void handler(
431 * const boost::system::error_code& error // Result of operation.
432 * ); @endcode
433 */
92f5a8d4
TL
434 template <
435 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
436 HandshakeHandler
437 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
438 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(HandshakeHandler,
7c673cae
FG
439 void (boost::system::error_code))
440 async_handshake(handshake_type type,
92f5a8d4
TL
441 BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler
442 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 443 {
92f5a8d4
TL
444 return async_initiate<HandshakeHandler,
445 void (boost::system::error_code)>(
446 initiate_async_handshake(this), handler, type);
7c673cae
FG
447 }
448
449 /// Start an asynchronous SSL handshake.
450 /**
451 * This function is used to asynchronously perform an SSL handshake on the
452 * stream. This function call always returns immediately.
453 *
454 * @param type The type of handshaking to be performed, i.e. as a client or as
455 * a server.
456 *
457 * @param buffers The buffered data to be reused for the handshake. Although
458 * the buffers object may be copied as necessary, ownership of the underlying
459 * buffers is retained by the caller, which must guarantee that they remain
460 * valid until the handler is called.
461 *
462 * @param handler The handler to be called when the handshake operation
463 * completes. Copies will be made of the handler as required. The equivalent
464 * function signature of the handler must be:
465 * @code void handler(
466 * const boost::system::error_code& error, // Result of operation.
467 * std::size_t bytes_transferred // Amount of buffers used in handshake.
468 * ); @endcode
469 */
92f5a8d4
TL
470 template <typename ConstBufferSequence,
471 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
472 std::size_t)) BufferedHandshakeHandler
473 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
474 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(BufferedHandshakeHandler,
7c673cae
FG
475 void (boost::system::error_code, std::size_t))
476 async_handshake(handshake_type type, const ConstBufferSequence& buffers,
92f5a8d4
TL
477 BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler
478 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 479 {
92f5a8d4
TL
480 return async_initiate<BufferedHandshakeHandler,
481 void (boost::system::error_code, std::size_t)>(
482 initiate_async_buffered_handshake(this), handler, type, buffers);
7c673cae
FG
483 }
484
485 /// Shut down SSL on the stream.
486 /**
487 * This function is used to shut down SSL on the stream. The function call
488 * will block until SSL has been shut down or an error occurs.
489 *
490 * @throws boost::system::system_error Thrown on failure.
491 */
492 void shutdown()
493 {
494 boost::system::error_code ec;
495 shutdown(ec);
496 boost::asio::detail::throw_error(ec, "shutdown");
497 }
498
499 /// Shut down SSL on the stream.
500 /**
501 * This function is used to shut down SSL on the stream. The function call
502 * will block until SSL has been shut down or an error occurs.
503 *
504 * @param ec Set to indicate what error occurred, if any.
505 */
b32b8144 506 BOOST_ASIO_SYNC_OP_VOID shutdown(boost::system::error_code& ec)
7c673cae
FG
507 {
508 detail::io(next_layer_, core_, detail::shutdown_op(), ec);
b32b8144 509 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
510 }
511
512 /// Asynchronously shut down SSL on the stream.
513 /**
514 * This function is used to asynchronously shut down SSL on the stream. This
515 * function call always returns immediately.
516 *
517 * @param handler The handler to be called when the handshake operation
518 * completes. Copies will be made of the handler as required. The equivalent
519 * function signature of the handler must be:
520 * @code void handler(
521 * const boost::system::error_code& error // Result of operation.
522 * ); @endcode
523 */
92f5a8d4
TL
524 template <
525 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
526 ShutdownHandler
527 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
528 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ShutdownHandler,
7c673cae 529 void (boost::system::error_code))
92f5a8d4
TL
530 async_shutdown(
531 BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler
532 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 533 {
92f5a8d4
TL
534 return async_initiate<ShutdownHandler,
535 void (boost::system::error_code)>(
536 initiate_async_shutdown(this), handler);
7c673cae
FG
537 }
538
539 /// Write some data to the stream.
540 /**
541 * This function is used to write data on the stream. The function call will
542 * block until one or more bytes of data has been written successfully, or
543 * until an error occurs.
544 *
545 * @param buffers The data to be written.
546 *
547 * @returns The number of bytes written.
548 *
549 * @throws boost::system::system_error Thrown on failure.
550 *
551 * @note The write_some operation may not transmit all of the data to the
552 * peer. Consider using the @ref write function if you need to ensure that all
553 * data is written before the blocking operation completes.
554 */
555 template <typename ConstBufferSequence>
556 std::size_t write_some(const ConstBufferSequence& buffers)
557 {
558 boost::system::error_code ec;
559 std::size_t n = write_some(buffers, ec);
560 boost::asio::detail::throw_error(ec, "write_some");
561 return n;
562 }
563
564 /// Write some data to the stream.
565 /**
566 * This function is used to write data on the stream. The function call will
567 * block until one or more bytes of data has been written successfully, or
568 * until an error occurs.
569 *
570 * @param buffers The data to be written to the stream.
571 *
572 * @param ec Set to indicate what error occurred, if any.
573 *
574 * @returns The number of bytes written. Returns 0 if an error occurred.
575 *
576 * @note The write_some operation may not transmit all of the data to the
577 * peer. Consider using the @ref write function if you need to ensure that all
578 * data is written before the blocking operation completes.
579 */
580 template <typename ConstBufferSequence>
581 std::size_t write_some(const ConstBufferSequence& buffers,
582 boost::system::error_code& ec)
583 {
584 return detail::io(next_layer_, core_,
585 detail::write_op<ConstBufferSequence>(buffers), ec);
586 }
587
588 /// Start an asynchronous write.
589 /**
590 * This function is used to asynchronously write one or more bytes of data to
591 * the stream. The function call always returns immediately.
592 *
593 * @param buffers The data to be written to the stream. Although the buffers
594 * object may be copied as necessary, ownership of the underlying buffers is
595 * retained by the caller, which must guarantee that they remain valid until
596 * the handler is called.
597 *
598 * @param handler The handler to be called when the write operation completes.
599 * Copies will be made of the handler as required. The equivalent function
600 * signature of the handler must be:
601 * @code void handler(
602 * const boost::system::error_code& error, // Result of operation.
603 * std::size_t bytes_transferred // Number of bytes written.
604 * ); @endcode
605 *
606 * @note The async_write_some operation may not transmit all of the data to
607 * the peer. Consider using the @ref async_write function if you need to
92f5a8d4
TL
608 * ensure that all data is written before the asynchronous operation
609 * completes.
7c673cae 610 */
92f5a8d4
TL
611 template <typename ConstBufferSequence,
612 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
613 std::size_t)) WriteHandler
614 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
615 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
7c673cae
FG
616 void (boost::system::error_code, std::size_t))
617 async_write_some(const ConstBufferSequence& buffers,
92f5a8d4
TL
618 BOOST_ASIO_MOVE_ARG(WriteHandler) handler
619 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 620 {
92f5a8d4
TL
621 return async_initiate<WriteHandler,
622 void (boost::system::error_code, std::size_t)>(
623 initiate_async_write_some(this), handler, buffers);
7c673cae
FG
624 }
625
626 /// Read some data from the stream.
627 /**
628 * This function is used to read data from the stream. The function call will
629 * block until one or more bytes of data has been read successfully, or until
630 * an error occurs.
631 *
632 * @param buffers The buffers into which the data will be read.
633 *
634 * @returns The number of bytes read.
635 *
636 * @throws boost::system::system_error Thrown on failure.
637 *
638 * @note The read_some operation may not read all of the requested number of
639 * bytes. Consider using the @ref read function if you need to ensure that the
640 * requested amount of data is read before the blocking operation completes.
641 */
642 template <typename MutableBufferSequence>
643 std::size_t read_some(const MutableBufferSequence& buffers)
644 {
645 boost::system::error_code ec;
646 std::size_t n = read_some(buffers, ec);
647 boost::asio::detail::throw_error(ec, "read_some");
648 return n;
649 }
650
651 /// Read some data from the stream.
652 /**
653 * This function is used to read data from the stream. The function call will
654 * block until one or more bytes of data has been read successfully, or until
655 * an error occurs.
656 *
657 * @param buffers The buffers into which the data will be read.
658 *
659 * @param ec Set to indicate what error occurred, if any.
660 *
661 * @returns The number of bytes read. Returns 0 if an error occurred.
662 *
663 * @note The read_some operation may not read all of the requested number of
664 * bytes. Consider using the @ref read function if you need to ensure that the
665 * requested amount of data is read before the blocking operation completes.
666 */
667 template <typename MutableBufferSequence>
668 std::size_t read_some(const MutableBufferSequence& buffers,
669 boost::system::error_code& ec)
670 {
671 return detail::io(next_layer_, core_,
672 detail::read_op<MutableBufferSequence>(buffers), ec);
673 }
674
675 /// Start an asynchronous read.
676 /**
677 * This function is used to asynchronously read one or more bytes of data from
678 * the stream. The function call always returns immediately.
679 *
680 * @param buffers The buffers into which the data will be read. Although the
681 * buffers object may be copied as necessary, ownership of the underlying
682 * buffers is retained by the caller, which must guarantee that they remain
683 * valid until the handler is called.
684 *
685 * @param handler The handler to be called when the read operation completes.
686 * Copies will be made of the handler as required. The equivalent function
687 * signature of the handler must be:
688 * @code void handler(
689 * const boost::system::error_code& error, // Result of operation.
690 * std::size_t bytes_transferred // Number of bytes read.
691 * ); @endcode
692 *
693 * @note The async_read_some operation may not read all of the requested
694 * number of bytes. Consider using the @ref async_read function if you need to
695 * ensure that the requested amount of data is read before the asynchronous
696 * operation completes.
697 */
92f5a8d4
TL
698 template <typename MutableBufferSequence,
699 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
700 std::size_t)) ReadHandler
701 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
702 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
7c673cae
FG
703 void (boost::system::error_code, std::size_t))
704 async_read_some(const MutableBufferSequence& buffers,
92f5a8d4
TL
705 BOOST_ASIO_MOVE_ARG(ReadHandler) handler
706 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 707 {
92f5a8d4
TL
708 return async_initiate<ReadHandler,
709 void (boost::system::error_code, std::size_t)>(
710 initiate_async_read_some(this), handler, buffers);
711 }
7c673cae 712
92f5a8d4
TL
713private:
714 class initiate_async_handshake
715 {
716 public:
717 typedef typename stream::executor_type executor_type;
718
719 explicit initiate_async_handshake(stream* self)
720 : self_(self)
721 {
722 }
723
724 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
725 {
726 return self_->get_executor();
727 }
728
729 template <typename HandshakeHandler>
730 void operator()(BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
731 handshake_type type) const
732 {
733 // If you get an error on the following line it means that your handler
734 // does not meet the documented type requirements for a HandshakeHandler.
735 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
736
737 boost::asio::detail::non_const_lvalue<HandshakeHandler> handler2(handler);
738 detail::async_io(self_->next_layer_, self_->core_,
739 detail::handshake_op(type), handler2.value);
740 }
741
742 private:
743 stream* self_;
744 };
7c673cae 745
92f5a8d4
TL
746 class initiate_async_buffered_handshake
747 {
748 public:
749 typedef typename stream::executor_type executor_type;
750
751 explicit initiate_async_buffered_handshake(stream* self)
752 : self_(self)
753 {
754 }
755
756 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
757 {
758 return self_->get_executor();
759 }
760
761 template <typename BufferedHandshakeHandler, typename ConstBufferSequence>
762 void operator()(BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
763 handshake_type type, const ConstBufferSequence& buffers) const
764 {
765 // If you get an error on the following line it means that your
766 // handler does not meet the documented type requirements for a
767 // BufferedHandshakeHandler.
768 BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
769 BufferedHandshakeHandler, handler) type_check;
770
771 boost::asio::detail::non_const_lvalue<
772 BufferedHandshakeHandler> handler2(handler);
773 detail::async_io(self_->next_layer_, self_->core_,
774 detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
775 handler2.value);
776 }
777
778 private:
779 stream* self_;
780 };
7c673cae 781
92f5a8d4
TL
782 class initiate_async_shutdown
783 {
784 public:
785 typedef typename stream::executor_type executor_type;
786
787 explicit initiate_async_shutdown(stream* self)
788 : self_(self)
789 {
790 }
791
792 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
793 {
794 return self_->get_executor();
795 }
796
797 template <typename ShutdownHandler>
798 void operator()(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler) const
799 {
800 // If you get an error on the following line it means that your handler
801 // does not meet the documented type requirements for a ShutdownHandler.
802 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(ShutdownHandler, handler) type_check;
803
804 boost::asio::detail::non_const_lvalue<ShutdownHandler> handler2(handler);
805 detail::async_io(self_->next_layer_, self_->core_,
806 detail::shutdown_op(), handler2.value);
807 }
808
809 private:
810 stream* self_;
811 };
812
813 class initiate_async_write_some
814 {
815 public:
816 typedef typename stream::executor_type executor_type;
817
818 explicit initiate_async_write_some(stream* self)
819 : self_(self)
820 {
821 }
822
823 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
824 {
825 return self_->get_executor();
826 }
827
828 template <typename WriteHandler, typename ConstBufferSequence>
829 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
830 const ConstBufferSequence& buffers) const
831 {
832 // If you get an error on the following line it means that your handler
833 // does not meet the documented type requirements for a WriteHandler.
834 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
835
836 boost::asio::detail::non_const_lvalue<WriteHandler> handler2(handler);
837 detail::async_io(self_->next_layer_, self_->core_,
838 detail::write_op<ConstBufferSequence>(buffers), handler2.value);
839 }
840
841 private:
842 stream* self_;
843 };
844
845 class initiate_async_read_some
846 {
847 public:
848 typedef typename stream::executor_type executor_type;
849
850 explicit initiate_async_read_some(stream* self)
851 : self_(self)
852 {
853 }
854
855 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
856 {
857 return self_->get_executor();
858 }
859
860 template <typename ReadHandler, typename MutableBufferSequence>
861 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
862 const MutableBufferSequence& buffers) const
863 {
864 // If you get an error on the following line it means that your handler
865 // does not meet the documented type requirements for a ReadHandler.
866 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
867
868 boost::asio::detail::non_const_lvalue<ReadHandler> handler2(handler);
869 detail::async_io(self_->next_layer_, self_->core_,
870 detail::read_op<MutableBufferSequence>(buffers), handler2.value);
871 }
872
873 private:
874 stream* self_;
875 };
7c673cae 876
7c673cae
FG
877 Stream next_layer_;
878 detail::stream_core core_;
7c673cae
FG
879};
880
7c673cae
FG
881} // namespace ssl
882} // namespace asio
883} // namespace boost
884
885#include <boost/asio/detail/pop_options.hpp>
886
887#endif // BOOST_ASIO_SSL_STREAM_HPP