|
||||
File indexing completed on 2025-01-18 09:29:02
0001 // 0002 // ssl/stream.hpp 0003 // ~~~~~~~~~~~~~~ 0004 // 0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) 0006 // 0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0009 // 0010 0011 #ifndef BOOST_ASIO_SSL_STREAM_HPP 0012 #define BOOST_ASIO_SSL_STREAM_HPP 0013 0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 0015 # pragma once 0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 0017 0018 #include <boost/asio/detail/config.hpp> 0019 0020 #include <boost/asio/async_result.hpp> 0021 #include <boost/asio/buffer.hpp> 0022 #include <boost/asio/detail/buffer_sequence_adapter.hpp> 0023 #include <boost/asio/detail/handler_type_requirements.hpp> 0024 #include <boost/asio/detail/non_const_lvalue.hpp> 0025 #include <boost/asio/detail/noncopyable.hpp> 0026 #include <boost/asio/detail/type_traits.hpp> 0027 #include <boost/asio/ssl/context.hpp> 0028 #include <boost/asio/ssl/detail/buffered_handshake_op.hpp> 0029 #include <boost/asio/ssl/detail/handshake_op.hpp> 0030 #include <boost/asio/ssl/detail/io.hpp> 0031 #include <boost/asio/ssl/detail/read_op.hpp> 0032 #include <boost/asio/ssl/detail/shutdown_op.hpp> 0033 #include <boost/asio/ssl/detail/stream_core.hpp> 0034 #include <boost/asio/ssl/detail/write_op.hpp> 0035 #include <boost/asio/ssl/stream_base.hpp> 0036 0037 #include <boost/asio/detail/push_options.hpp> 0038 0039 namespace boost { 0040 namespace asio { 0041 namespace ssl { 0042 0043 /// Provides stream-oriented functionality using SSL. 0044 /** 0045 * The stream class template provides asynchronous and blocking stream-oriented 0046 * functionality using SSL. 0047 * 0048 * @par Thread Safety 0049 * @e Distinct @e objects: Safe.@n 0050 * @e Shared @e objects: Unsafe. The application must also ensure that all 0051 * asynchronous operations are performed within the same implicit or explicit 0052 * strand. 0053 * 0054 * @par Example 0055 * To use the SSL stream template with an ip::tcp::socket, you would write: 0056 * @code 0057 * boost::asio::io_context my_context; 0058 * boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); 0059 * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx); 0060 * @endcode 0061 * 0062 * @par Concepts: 0063 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. 0064 */ 0065 template <typename Stream> 0066 class stream : 0067 public stream_base, 0068 private noncopyable 0069 { 0070 private: 0071 class initiate_async_handshake; 0072 class initiate_async_buffered_handshake; 0073 class initiate_async_shutdown; 0074 class initiate_async_write_some; 0075 class initiate_async_read_some; 0076 0077 public: 0078 /// The native handle type of the SSL stream. 0079 typedef SSL* native_handle_type; 0080 0081 /// Structure for use with deprecated impl_type. 0082 struct impl_struct 0083 { 0084 SSL* ssl; 0085 }; 0086 0087 /// The type of the next layer. 0088 typedef remove_reference_t<Stream> next_layer_type; 0089 0090 /// The type of the lowest layer. 0091 typedef typename next_layer_type::lowest_layer_type lowest_layer_type; 0092 0093 /// The type of the executor associated with the object. 0094 typedef typename lowest_layer_type::executor_type executor_type; 0095 0096 /// Construct a stream. 0097 /** 0098 * This constructor creates a stream and initialises the underlying stream 0099 * object. 0100 * 0101 * @param arg The argument to be passed to initialise the underlying stream. 0102 * 0103 * @param ctx The SSL context to be used for the stream. 0104 */ 0105 template <typename Arg> 0106 stream(Arg&& arg, context& ctx) 0107 : next_layer_(static_cast<Arg&&>(arg)), 0108 core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor()) 0109 { 0110 } 0111 0112 /// Construct a stream from an existing native implementation. 0113 /** 0114 * This constructor creates a stream and initialises the underlying stream 0115 * object. On success, ownership of the native implementation is transferred 0116 * to the stream, and it will be cleaned up when the stream is destroyed. 0117 * 0118 * @param arg The argument to be passed to initialise the underlying stream. 0119 * 0120 * @param handle An existing native SSL implementation. 0121 */ 0122 template <typename Arg> 0123 stream(Arg&& arg, native_handle_type handle) 0124 : next_layer_(static_cast<Arg&&>(arg)), 0125 core_(handle, next_layer_.lowest_layer().get_executor()) 0126 { 0127 } 0128 0129 /// Move-construct a stream from another. 0130 /** 0131 * @param other The other stream object from which the move will occur. Must 0132 * have no outstanding asynchronous operations associated with it. Following 0133 * the move, @c other has a valid but unspecified state where the only safe 0134 * operation is destruction, or use as the target of a move assignment. 0135 */ 0136 stream(stream&& other) 0137 : next_layer_(static_cast<Stream&&>(other.next_layer_)), 0138 core_(static_cast<detail::stream_core&&>(other.core_)) 0139 { 0140 } 0141 0142 /// Move-assign a stream from another. 0143 /** 0144 * @param other The other stream object from which the move will occur. Must 0145 * have no outstanding asynchronous operations associated with it. Following 0146 * the move, @c other has a valid but unspecified state where the only safe 0147 * operation is destruction, or use as the target of a move assignment. 0148 */ 0149 stream& operator=(stream&& other) 0150 { 0151 if (this != &other) 0152 { 0153 next_layer_ = static_cast<Stream&&>(other.next_layer_); 0154 core_ = static_cast<detail::stream_core&&>(other.core_); 0155 } 0156 return *this; 0157 } 0158 0159 /// Destructor. 0160 /** 0161 * @note A @c stream object must not be destroyed while there are pending 0162 * asynchronous operations associated with it. 0163 */ 0164 ~stream() 0165 { 0166 } 0167 0168 /// Get the executor associated with the object. 0169 /** 0170 * This function may be used to obtain the executor object that the stream 0171 * uses to dispatch handlers for asynchronous operations. 0172 * 0173 * @return A copy of the executor that stream will use to dispatch handlers. 0174 */ 0175 executor_type get_executor() noexcept 0176 { 0177 return next_layer_.lowest_layer().get_executor(); 0178 } 0179 0180 /// Get the underlying implementation in the native type. 0181 /** 0182 * This function may be used to obtain the underlying implementation of the 0183 * context. This is intended to allow access to context functionality that is 0184 * not otherwise provided. 0185 * 0186 * @par Example 0187 * The native_handle() function returns a pointer of type @c SSL* that is 0188 * suitable for passing to functions such as @c SSL_get_verify_result and 0189 * @c SSL_get_peer_certificate: 0190 * @code 0191 * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx); 0192 * 0193 * // ... establish connection and perform handshake ... 0194 * 0195 * if (X509* cert = SSL_get_peer_certificate(sock.native_handle())) 0196 * { 0197 * if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK) 0198 * { 0199 * // ... 0200 * } 0201 * } 0202 * @endcode 0203 */ 0204 native_handle_type native_handle() 0205 { 0206 return core_.engine_.native_handle(); 0207 } 0208 0209 /// Get a reference to the next layer. 0210 /** 0211 * This function returns a reference to the next layer in a stack of stream 0212 * layers. 0213 * 0214 * @return A reference to the next layer in the stack of stream layers. 0215 * Ownership is not transferred to the caller. 0216 */ 0217 const next_layer_type& next_layer() const 0218 { 0219 return next_layer_; 0220 } 0221 0222 /// Get a reference to the next layer. 0223 /** 0224 * This function returns a reference to the next layer in a stack of stream 0225 * layers. 0226 * 0227 * @return A reference to the next layer in the stack of stream layers. 0228 * Ownership is not transferred to the caller. 0229 */ 0230 next_layer_type& next_layer() 0231 { 0232 return next_layer_; 0233 } 0234 0235 /// Get a reference to the lowest layer. 0236 /** 0237 * This function returns a reference to the lowest layer in a stack of 0238 * stream layers. 0239 * 0240 * @return A reference to the lowest layer in the stack of stream layers. 0241 * Ownership is not transferred to the caller. 0242 */ 0243 lowest_layer_type& lowest_layer() 0244 { 0245 return next_layer_.lowest_layer(); 0246 } 0247 0248 /// Get a reference to the lowest layer. 0249 /** 0250 * This function returns a reference to the lowest layer in a stack of 0251 * stream layers. 0252 * 0253 * @return A reference to the lowest layer in the stack of stream layers. 0254 * Ownership is not transferred to the caller. 0255 */ 0256 const lowest_layer_type& lowest_layer() const 0257 { 0258 return next_layer_.lowest_layer(); 0259 } 0260 0261 /// Set the peer verification mode. 0262 /** 0263 * This function may be used to configure the peer verification mode used by 0264 * the stream. The new mode will override the mode inherited from the context. 0265 * 0266 * @param v A bitmask of peer verification modes. See @ref verify_mode for 0267 * available values. 0268 * 0269 * @throws boost::system::system_error Thrown on failure. 0270 * 0271 * @note Calls @c SSL_set_verify. 0272 */ 0273 void set_verify_mode(verify_mode v) 0274 { 0275 boost::system::error_code ec; 0276 set_verify_mode(v, ec); 0277 boost::asio::detail::throw_error(ec, "set_verify_mode"); 0278 } 0279 0280 /// Set the peer verification mode. 0281 /** 0282 * This function may be used to configure the peer verification mode used by 0283 * the stream. The new mode will override the mode inherited from the context. 0284 * 0285 * @param v A bitmask of peer verification modes. See @ref verify_mode for 0286 * available values. 0287 * 0288 * @param ec Set to indicate what error occurred, if any. 0289 * 0290 * @note Calls @c SSL_set_verify. 0291 */ 0292 BOOST_ASIO_SYNC_OP_VOID set_verify_mode( 0293 verify_mode v, boost::system::error_code& ec) 0294 { 0295 core_.engine_.set_verify_mode(v, ec); 0296 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0297 } 0298 0299 /// Set the peer verification depth. 0300 /** 0301 * This function may be used to configure the maximum verification depth 0302 * allowed by the stream. 0303 * 0304 * @param depth Maximum depth for the certificate chain verification that 0305 * shall be allowed. 0306 * 0307 * @throws boost::system::system_error Thrown on failure. 0308 * 0309 * @note Calls @c SSL_set_verify_depth. 0310 */ 0311 void set_verify_depth(int depth) 0312 { 0313 boost::system::error_code ec; 0314 set_verify_depth(depth, ec); 0315 boost::asio::detail::throw_error(ec, "set_verify_depth"); 0316 } 0317 0318 /// Set the peer verification depth. 0319 /** 0320 * This function may be used to configure the maximum verification depth 0321 * allowed by the stream. 0322 * 0323 * @param depth Maximum depth for the certificate chain verification that 0324 * shall be allowed. 0325 * 0326 * @param ec Set to indicate what error occurred, if any. 0327 * 0328 * @note Calls @c SSL_set_verify_depth. 0329 */ 0330 BOOST_ASIO_SYNC_OP_VOID set_verify_depth( 0331 int depth, boost::system::error_code& ec) 0332 { 0333 core_.engine_.set_verify_depth(depth, ec); 0334 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0335 } 0336 0337 /// Set the callback used to verify peer certificates. 0338 /** 0339 * This function is used to specify a callback function that will be called 0340 * by the implementation when it needs to verify a peer certificate. 0341 * 0342 * @param callback The function object to be used for verifying a certificate. 0343 * The function signature of the handler must be: 0344 * @code bool verify_callback( 0345 * bool preverified, // True if the certificate passed pre-verification. 0346 * verify_context& ctx // The peer certificate and other context. 0347 * ); @endcode 0348 * The return value of the callback is true if the certificate has passed 0349 * verification, false otherwise. 0350 * 0351 * @throws boost::system::system_error Thrown on failure. 0352 * 0353 * @note Calls @c SSL_set_verify. 0354 */ 0355 template <typename VerifyCallback> 0356 void set_verify_callback(VerifyCallback callback) 0357 { 0358 boost::system::error_code ec; 0359 this->set_verify_callback(callback, ec); 0360 boost::asio::detail::throw_error(ec, "set_verify_callback"); 0361 } 0362 0363 /// Set the callback used to verify peer certificates. 0364 /** 0365 * This function is used to specify a callback function that will be called 0366 * by the implementation when it needs to verify a peer certificate. 0367 * 0368 * @param callback The function object to be used for verifying a certificate. 0369 * The function signature of the handler must be: 0370 * @code bool verify_callback( 0371 * bool preverified, // True if the certificate passed pre-verification. 0372 * verify_context& ctx // The peer certificate and other context. 0373 * ); @endcode 0374 * The return value of the callback is true if the certificate has passed 0375 * verification, false otherwise. 0376 * 0377 * @param ec Set to indicate what error occurred, if any. 0378 * 0379 * @note Calls @c SSL_set_verify. 0380 */ 0381 template <typename VerifyCallback> 0382 BOOST_ASIO_SYNC_OP_VOID set_verify_callback(VerifyCallback callback, 0383 boost::system::error_code& ec) 0384 { 0385 core_.engine_.set_verify_callback( 0386 new detail::verify_callback<VerifyCallback>(callback), ec); 0387 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0388 } 0389 0390 /// Perform SSL handshaking. 0391 /** 0392 * This function is used to perform SSL handshaking on the stream. The 0393 * function call will block until handshaking is complete or an error occurs. 0394 * 0395 * @param type The type of handshaking to be performed, i.e. as a client or as 0396 * a server. 0397 * 0398 * @throws boost::system::system_error Thrown on failure. 0399 */ 0400 void handshake(handshake_type type) 0401 { 0402 boost::system::error_code ec; 0403 handshake(type, ec); 0404 boost::asio::detail::throw_error(ec, "handshake"); 0405 } 0406 0407 /// Perform SSL handshaking. 0408 /** 0409 * This function is used to perform SSL handshaking on the stream. The 0410 * function call will block until handshaking is complete or an error occurs. 0411 * 0412 * @param type The type of handshaking to be performed, i.e. as a client or as 0413 * a server. 0414 * 0415 * @param ec Set to indicate what error occurred, if any. 0416 */ 0417 BOOST_ASIO_SYNC_OP_VOID handshake(handshake_type type, 0418 boost::system::error_code& ec) 0419 { 0420 detail::io(next_layer_, core_, detail::handshake_op(type), ec); 0421 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0422 } 0423 0424 /// Perform SSL handshaking. 0425 /** 0426 * This function is used to perform SSL handshaking on the stream. The 0427 * function call will block until handshaking is complete or an error occurs. 0428 * 0429 * @param type The type of handshaking to be performed, i.e. as a client or as 0430 * a server. 0431 * 0432 * @param buffers The buffered data to be reused for the handshake. 0433 * 0434 * @throws boost::system::system_error Thrown on failure. 0435 */ 0436 template <typename ConstBufferSequence> 0437 void handshake(handshake_type type, const ConstBufferSequence& buffers) 0438 { 0439 boost::system::error_code ec; 0440 handshake(type, buffers, ec); 0441 boost::asio::detail::throw_error(ec, "handshake"); 0442 } 0443 0444 /// Perform SSL handshaking. 0445 /** 0446 * This function is used to perform SSL handshaking on the stream. The 0447 * function call will block until handshaking is complete or an error occurs. 0448 * 0449 * @param type The type of handshaking to be performed, i.e. as a client or as 0450 * a server. 0451 * 0452 * @param buffers The buffered data to be reused for the handshake. 0453 * 0454 * @param ec Set to indicate what error occurred, if any. 0455 */ 0456 template <typename ConstBufferSequence> 0457 BOOST_ASIO_SYNC_OP_VOID handshake(handshake_type type, 0458 const ConstBufferSequence& buffers, boost::system::error_code& ec) 0459 { 0460 detail::io(next_layer_, core_, 0461 detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), ec); 0462 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0463 } 0464 0465 /// Start an asynchronous SSL handshake. 0466 /** 0467 * This function is used to asynchronously perform an SSL handshake on the 0468 * stream. It is an initiating function for an @ref asynchronous_operation, 0469 * and always returns immediately. 0470 * 0471 * @param type The type of handshaking to be performed, i.e. as a client or as 0472 * a server. 0473 * 0474 * @param token The @ref completion_token that will be used to produce a 0475 * completion handler, which will be called when the handshake completes. 0476 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0477 * @ref yield_context, or a function object with the correct completion 0478 * signature. The function signature of the completion handler must be: 0479 * @code void handler( 0480 * const boost::system::error_code& error // Result of operation. 0481 * ); @endcode 0482 * Regardless of whether the asynchronous operation completes immediately or 0483 * not, the completion handler will not be invoked from within this function. 0484 * On immediate completion, invocation of the handler will be performed in a 0485 * manner equivalent to using boost::asio::post(). 0486 * 0487 * @par Completion Signature 0488 * @code void(boost::system::error_code) @endcode 0489 * 0490 * @par Per-Operation Cancellation 0491 * This asynchronous operation supports cancellation for the following 0492 * boost::asio::cancellation_type values: 0493 * 0494 * @li @c cancellation_type::terminal 0495 * 0496 * @li @c cancellation_type::partial 0497 * 0498 * if they are also supported by the @c Stream type's @c async_read_some and 0499 * @c async_write_some operations. 0500 */ 0501 template < 0502 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 0503 HandshakeToken = default_completion_token_t<executor_type>> 0504 auto async_handshake(handshake_type type, 0505 HandshakeToken&& token = default_completion_token_t<executor_type>()) 0506 -> decltype( 0507 async_initiate<HandshakeToken, 0508 void (boost::system::error_code)>( 0509 declval<initiate_async_handshake>(), token, type)) 0510 { 0511 return async_initiate<HandshakeToken, 0512 void (boost::system::error_code)>( 0513 initiate_async_handshake(this), token, type); 0514 } 0515 0516 /// Start an asynchronous SSL handshake. 0517 /** 0518 * This function is used to asynchronously perform an SSL handshake on the 0519 * stream. It is an initiating function for an @ref asynchronous_operation, 0520 * and always returns immediately. 0521 * 0522 * @param type The type of handshaking to be performed, i.e. as a client or as 0523 * a server. 0524 * 0525 * @param buffers The buffered data to be reused for the handshake. Although 0526 * the buffers object may be copied as necessary, ownership of the underlying 0527 * buffers is retained by the caller, which must guarantee that they remain 0528 * valid until the completion handler is called. 0529 * 0530 * @param token The @ref completion_token that will be used to produce a 0531 * completion handler, which will be called when the handshake completes. 0532 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0533 * @ref yield_context, or a function object with the correct completion 0534 * signature. The function signature of the completion handler must be: 0535 * @code void handler( 0536 * const boost::system::error_code& error, // Result of operation. 0537 * std::size_t bytes_transferred // Amount of buffers used in handshake. 0538 * ); @endcode 0539 * Regardless of whether the asynchronous operation completes immediately or 0540 * not, the completion handler will not be invoked from within this function. 0541 * On immediate completion, invocation of the handler will be performed in a 0542 * manner equivalent to using boost::asio::post(). 0543 * 0544 * @par Completion Signature 0545 * @code void(boost::system::error_code, std::size_t) @endcode 0546 * 0547 * @par Per-Operation Cancellation 0548 * This asynchronous operation supports cancellation for the following 0549 * boost::asio::cancellation_type values: 0550 * 0551 * @li @c cancellation_type::terminal 0552 * 0553 * @li @c cancellation_type::partial 0554 * 0555 * if they are also supported by the @c Stream type's @c async_read_some and 0556 * @c async_write_some operations. 0557 */ 0558 template <typename ConstBufferSequence, 0559 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0560 std::size_t)) BufferedHandshakeToken 0561 = default_completion_token_t<executor_type>> 0562 auto async_handshake(handshake_type type, const ConstBufferSequence& buffers, 0563 BufferedHandshakeToken&& token 0564 = default_completion_token_t<executor_type>(), 0565 constraint_t< 0566 is_const_buffer_sequence<ConstBufferSequence>::value 0567 > = 0) 0568 -> decltype( 0569 async_initiate<BufferedHandshakeToken, 0570 void (boost::system::error_code, std::size_t)>( 0571 declval<initiate_async_buffered_handshake>(), token, type, buffers)) 0572 { 0573 return async_initiate<BufferedHandshakeToken, 0574 void (boost::system::error_code, std::size_t)>( 0575 initiate_async_buffered_handshake(this), token, type, buffers); 0576 } 0577 0578 /// Shut down SSL on the stream. 0579 /** 0580 * This function is used to shut down SSL on the stream. The function call 0581 * will block until SSL has been shut down or an error occurs. 0582 * 0583 * @throws boost::system::system_error Thrown on failure. 0584 */ 0585 void shutdown() 0586 { 0587 boost::system::error_code ec; 0588 shutdown(ec); 0589 boost::asio::detail::throw_error(ec, "shutdown"); 0590 } 0591 0592 /// Shut down SSL on the stream. 0593 /** 0594 * This function is used to shut down SSL on the stream. The function call 0595 * will block until SSL has been shut down or an error occurs. 0596 * 0597 * @param ec Set to indicate what error occurred, if any. 0598 */ 0599 BOOST_ASIO_SYNC_OP_VOID shutdown(boost::system::error_code& ec) 0600 { 0601 detail::io(next_layer_, core_, detail::shutdown_op(), ec); 0602 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0603 } 0604 0605 /// Asynchronously shut down SSL on the stream. 0606 /** 0607 * This function is used to asynchronously shut down SSL on the stream. It is 0608 * an initiating function for an @ref asynchronous_operation, and always 0609 * returns immediately. 0610 * 0611 * @param token The @ref completion_token that will be used to produce a 0612 * completion handler, which will be called when the shutdown completes. 0613 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0614 * @ref yield_context, or a function object with the correct completion 0615 * signature. The function signature of the completion handler must be: 0616 * @code void handler( 0617 * const boost::system::error_code& error // Result of operation. 0618 * ); @endcode 0619 * Regardless of whether the asynchronous operation completes immediately or 0620 * not, the completion handler will not be invoked from within this function. 0621 * On immediate completion, invocation of the handler will be performed in a 0622 * manner equivalent to using boost::asio::post(). 0623 * 0624 * @par Completion Signature 0625 * @code void(boost::system::error_code) @endcode 0626 * 0627 * @par Per-Operation Cancellation 0628 * This asynchronous operation supports cancellation for the following 0629 * boost::asio::cancellation_type values: 0630 * 0631 * @li @c cancellation_type::terminal 0632 * 0633 * @li @c cancellation_type::partial 0634 * 0635 * if they are also supported by the @c Stream type's @c async_read_some and 0636 * @c async_write_some operations. 0637 */ 0638 template < 0639 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 0640 ShutdownToken 0641 = default_completion_token_t<executor_type>> 0642 auto async_shutdown( 0643 ShutdownToken&& token = default_completion_token_t<executor_type>()) 0644 -> decltype( 0645 async_initiate<ShutdownToken, 0646 void (boost::system::error_code)>( 0647 declval<initiate_async_shutdown>(), token)) 0648 { 0649 return async_initiate<ShutdownToken, 0650 void (boost::system::error_code)>( 0651 initiate_async_shutdown(this), token); 0652 } 0653 0654 /// Write some data to the stream. 0655 /** 0656 * This function is used to write data on the stream. The function call will 0657 * block until one or more bytes of data has been written successfully, or 0658 * until an error occurs. 0659 * 0660 * @param buffers The data to be written. 0661 * 0662 * @returns The number of bytes written. 0663 * 0664 * @throws boost::system::system_error Thrown on failure. 0665 * 0666 * @note The write_some operation may not transmit all of the data to the 0667 * peer. Consider using the @ref write function if you need to ensure that all 0668 * data is written before the blocking operation completes. 0669 */ 0670 template <typename ConstBufferSequence> 0671 std::size_t write_some(const ConstBufferSequence& buffers) 0672 { 0673 boost::system::error_code ec; 0674 std::size_t n = write_some(buffers, ec); 0675 boost::asio::detail::throw_error(ec, "write_some"); 0676 return n; 0677 } 0678 0679 /// Write some data to the stream. 0680 /** 0681 * This function is used to write data on the stream. The function call will 0682 * block until one or more bytes of data has been written successfully, or 0683 * until an error occurs. 0684 * 0685 * @param buffers The data to be written to the stream. 0686 * 0687 * @param ec Set to indicate what error occurred, if any. 0688 * 0689 * @returns The number of bytes written. Returns 0 if an error occurred. 0690 * 0691 * @note The write_some operation may not transmit all of the data to the 0692 * peer. Consider using the @ref write function if you need to ensure that all 0693 * data is written before the blocking operation completes. 0694 */ 0695 template <typename ConstBufferSequence> 0696 std::size_t write_some(const ConstBufferSequence& buffers, 0697 boost::system::error_code& ec) 0698 { 0699 return detail::io(next_layer_, core_, 0700 detail::write_op<ConstBufferSequence>(buffers), ec); 0701 } 0702 0703 /// Start an asynchronous write. 0704 /** 0705 * This function is used to asynchronously write one or more bytes of data to 0706 * the stream. It is an initiating function for an @ref 0707 * asynchronous_operation, and always returns immediately. 0708 * 0709 * @param buffers The data to be written to the stream. Although the buffers 0710 * object may be copied as necessary, ownership of the underlying buffers is 0711 * retained by the caller, which must guarantee that they remain valid until 0712 * the completion handler is called. 0713 * 0714 * @param token The @ref completion_token that will be used to produce a 0715 * completion handler, which will be called when the write completes. 0716 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0717 * @ref yield_context, or a function object with the correct completion 0718 * signature. The function signature of the completion handler must be: 0719 * @code void handler( 0720 * const boost::system::error_code& error, // Result of operation. 0721 * std::size_t bytes_transferred // Number of bytes written. 0722 * ); @endcode 0723 * Regardless of whether the asynchronous operation completes immediately or 0724 * not, the completion handler will not be invoked from within this function. 0725 * On immediate completion, invocation of the handler will be performed in a 0726 * manner equivalent to using boost::asio::post(). 0727 * 0728 * @par Completion Signature 0729 * @code void(boost::system::error_code, std::size_t) @endcode 0730 * 0731 * @note The async_write_some operation may not transmit all of the data to 0732 * the peer. Consider using the @ref async_write function if you need to 0733 * ensure that all data is written before the asynchronous operation 0734 * completes. 0735 * 0736 * @par Per-Operation Cancellation 0737 * This asynchronous operation supports cancellation for the following 0738 * boost::asio::cancellation_type values: 0739 * 0740 * @li @c cancellation_type::terminal 0741 * 0742 * @li @c cancellation_type::partial 0743 * 0744 * if they are also supported by the @c Stream type's @c async_read_some and 0745 * @c async_write_some operations. 0746 */ 0747 template <typename ConstBufferSequence, 0748 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0749 std::size_t)) WriteToken = default_completion_token_t<executor_type>> 0750 auto async_write_some(const ConstBufferSequence& buffers, 0751 WriteToken&& token = default_completion_token_t<executor_type>()) 0752 -> decltype( 0753 async_initiate<WriteToken, 0754 void (boost::system::error_code, std::size_t)>( 0755 declval<initiate_async_write_some>(), token, buffers)) 0756 { 0757 return async_initiate<WriteToken, 0758 void (boost::system::error_code, std::size_t)>( 0759 initiate_async_write_some(this), token, buffers); 0760 } 0761 0762 /// Read some data from the stream. 0763 /** 0764 * This function is used to read data from the stream. The function call will 0765 * block until one or more bytes of data has been read successfully, or until 0766 * an error occurs. 0767 * 0768 * @param buffers The buffers into which the data will be read. 0769 * 0770 * @returns The number of bytes read. 0771 * 0772 * @throws boost::system::system_error Thrown on failure. 0773 * 0774 * @note The read_some operation may not read all of the requested number of 0775 * bytes. Consider using the @ref read function if you need to ensure that the 0776 * requested amount of data is read before the blocking operation completes. 0777 */ 0778 template <typename MutableBufferSequence> 0779 std::size_t read_some(const MutableBufferSequence& buffers) 0780 { 0781 boost::system::error_code ec; 0782 std::size_t n = read_some(buffers, ec); 0783 boost::asio::detail::throw_error(ec, "read_some"); 0784 return n; 0785 } 0786 0787 /// Read some data from the stream. 0788 /** 0789 * This function is used to read data from the stream. The function call will 0790 * block until one or more bytes of data has been read successfully, or until 0791 * an error occurs. 0792 * 0793 * @param buffers The buffers into which the data will be read. 0794 * 0795 * @param ec Set to indicate what error occurred, if any. 0796 * 0797 * @returns The number of bytes read. Returns 0 if an error occurred. 0798 * 0799 * @note The read_some operation may not read all of the requested number of 0800 * bytes. Consider using the @ref read function if you need to ensure that the 0801 * requested amount of data is read before the blocking operation completes. 0802 */ 0803 template <typename MutableBufferSequence> 0804 std::size_t read_some(const MutableBufferSequence& buffers, 0805 boost::system::error_code& ec) 0806 { 0807 return detail::io(next_layer_, core_, 0808 detail::read_op<MutableBufferSequence>(buffers), ec); 0809 } 0810 0811 /// Start an asynchronous read. 0812 /** 0813 * This function is used to asynchronously read one or more bytes of data from 0814 * the stream. It is an initiating function for an @ref 0815 * asynchronous_operation, and always returns immediately. 0816 * 0817 * @param buffers The buffers into which the data will be read. Although the 0818 * buffers object may be copied as necessary, ownership of the underlying 0819 * buffers is retained by the caller, which must guarantee that they remain 0820 * valid until the completion handler is called. 0821 * 0822 * @param token The @ref completion_token that will be used to produce a 0823 * completion handler, which will be called when the read completes. 0824 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0825 * @ref yield_context, or a function object with the correct completion 0826 * signature. The function signature of the completion handler must be: 0827 * @code void handler( 0828 * const boost::system::error_code& error, // Result of operation. 0829 * std::size_t bytes_transferred // Number of bytes read. 0830 * ); @endcode 0831 * Regardless of whether the asynchronous operation completes immediately or 0832 * not, the completion handler will not be invoked from within this function. 0833 * On immediate completion, invocation of the handler will be performed in a 0834 * manner equivalent to using boost::asio::post(). 0835 * 0836 * @par Completion Signature 0837 * @code void(boost::system::error_code, std::size_t) @endcode 0838 * 0839 * @note The async_read_some operation may not read all of the requested 0840 * number of bytes. Consider using the @ref async_read function if you need to 0841 * ensure that the requested amount of data is read before the asynchronous 0842 * operation completes. 0843 * 0844 * @par Per-Operation Cancellation 0845 * This asynchronous operation supports cancellation for the following 0846 * boost::asio::cancellation_type values: 0847 * 0848 * @li @c cancellation_type::terminal 0849 * 0850 * @li @c cancellation_type::partial 0851 * 0852 * if they are also supported by the @c Stream type's @c async_read_some and 0853 * @c async_write_some operations. 0854 */ 0855 template <typename MutableBufferSequence, 0856 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0857 std::size_t)) ReadToken = default_completion_token_t<executor_type>> 0858 auto async_read_some(const MutableBufferSequence& buffers, 0859 ReadToken&& token = default_completion_token_t<executor_type>()) 0860 -> decltype( 0861 async_initiate<ReadToken, 0862 void (boost::system::error_code, std::size_t)>( 0863 declval<initiate_async_read_some>(), token, buffers)) 0864 { 0865 return async_initiate<ReadToken, 0866 void (boost::system::error_code, std::size_t)>( 0867 initiate_async_read_some(this), token, buffers); 0868 } 0869 0870 private: 0871 class initiate_async_handshake 0872 { 0873 public: 0874 typedef typename stream::executor_type executor_type; 0875 0876 explicit initiate_async_handshake(stream* self) 0877 : self_(self) 0878 { 0879 } 0880 0881 executor_type get_executor() const noexcept 0882 { 0883 return self_->get_executor(); 0884 } 0885 0886 template <typename HandshakeHandler> 0887 void operator()(HandshakeHandler&& handler, 0888 handshake_type type) const 0889 { 0890 // If you get an error on the following line it means that your handler 0891 // does not meet the documented type requirements for a HandshakeHandler. 0892 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check; 0893 0894 boost::asio::detail::non_const_lvalue<HandshakeHandler> handler2(handler); 0895 detail::async_io(self_->next_layer_, self_->core_, 0896 detail::handshake_op(type), handler2.value); 0897 } 0898 0899 private: 0900 stream* self_; 0901 }; 0902 0903 class initiate_async_buffered_handshake 0904 { 0905 public: 0906 typedef typename stream::executor_type executor_type; 0907 0908 explicit initiate_async_buffered_handshake(stream* self) 0909 : self_(self) 0910 { 0911 } 0912 0913 executor_type get_executor() const noexcept 0914 { 0915 return self_->get_executor(); 0916 } 0917 0918 template <typename BufferedHandshakeHandler, typename ConstBufferSequence> 0919 void operator()(BufferedHandshakeHandler&& handler, 0920 handshake_type type, const ConstBufferSequence& buffers) const 0921 { 0922 // If you get an error on the following line it means that your 0923 // handler does not meet the documented type requirements for a 0924 // BufferedHandshakeHandler. 0925 BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( 0926 BufferedHandshakeHandler, handler) type_check; 0927 0928 boost::asio::detail::non_const_lvalue< 0929 BufferedHandshakeHandler> handler2(handler); 0930 detail::async_io(self_->next_layer_, self_->core_, 0931 detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), 0932 handler2.value); 0933 } 0934 0935 private: 0936 stream* self_; 0937 }; 0938 0939 class initiate_async_shutdown 0940 { 0941 public: 0942 typedef typename stream::executor_type executor_type; 0943 0944 explicit initiate_async_shutdown(stream* self) 0945 : self_(self) 0946 { 0947 } 0948 0949 executor_type get_executor() const noexcept 0950 { 0951 return self_->get_executor(); 0952 } 0953 0954 template <typename ShutdownHandler> 0955 void operator()(ShutdownHandler&& handler) const 0956 { 0957 // If you get an error on the following line it means that your handler 0958 // does not meet the documented type requirements for a ShutdownHandler. 0959 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(ShutdownHandler, handler) type_check; 0960 0961 boost::asio::detail::non_const_lvalue<ShutdownHandler> handler2(handler); 0962 detail::async_io(self_->next_layer_, self_->core_, 0963 detail::shutdown_op(), handler2.value); 0964 } 0965 0966 private: 0967 stream* self_; 0968 }; 0969 0970 class initiate_async_write_some 0971 { 0972 public: 0973 typedef typename stream::executor_type executor_type; 0974 0975 explicit initiate_async_write_some(stream* self) 0976 : self_(self) 0977 { 0978 } 0979 0980 executor_type get_executor() const noexcept 0981 { 0982 return self_->get_executor(); 0983 } 0984 0985 template <typename WriteHandler, typename ConstBufferSequence> 0986 void operator()(WriteHandler&& handler, 0987 const ConstBufferSequence& buffers) const 0988 { 0989 // If you get an error on the following line it means that your handler 0990 // does not meet the documented type requirements for a WriteHandler. 0991 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; 0992 0993 boost::asio::detail::non_const_lvalue<WriteHandler> handler2(handler); 0994 detail::async_io(self_->next_layer_, self_->core_, 0995 detail::write_op<ConstBufferSequence>(buffers), handler2.value); 0996 } 0997 0998 private: 0999 stream* self_; 1000 }; 1001 1002 class initiate_async_read_some 1003 { 1004 public: 1005 typedef typename stream::executor_type executor_type; 1006 1007 explicit initiate_async_read_some(stream* self) 1008 : self_(self) 1009 { 1010 } 1011 1012 executor_type get_executor() const noexcept 1013 { 1014 return self_->get_executor(); 1015 } 1016 1017 template <typename ReadHandler, typename MutableBufferSequence> 1018 void operator()(ReadHandler&& handler, 1019 const MutableBufferSequence& buffers) const 1020 { 1021 // If you get an error on the following line it means that your handler 1022 // does not meet the documented type requirements for a ReadHandler. 1023 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 1024 1025 boost::asio::detail::non_const_lvalue<ReadHandler> handler2(handler); 1026 detail::async_io(self_->next_layer_, self_->core_, 1027 detail::read_op<MutableBufferSequence>(buffers), handler2.value); 1028 } 1029 1030 private: 1031 stream* self_; 1032 }; 1033 1034 Stream next_layer_; 1035 detail::stream_core core_; 1036 }; 1037 1038 } // namespace ssl 1039 } // namespace asio 1040 } // namespace boost 1041 1042 #include <boost/asio/detail/pop_options.hpp> 1043 1044 #endif // BOOST_ASIO_SSL_STREAM_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |