stream.hpp 35 KB

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