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