stream.hpp 38 KB

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