stream.hpp 35 KB

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