New SSL implementation.
This commit is contained in:
parent
3f06a8c38d
commit
70e93c3e24
@ -2,8 +2,7 @@
|
||||
// ssl/basic_context.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -18,15 +17,21 @@
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#include "asio/ssl/old/basic_context.hpp"
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/ssl/old/basic_context.hpp"
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
using asio::ssl::old::basic_context;
|
||||
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
|
@ -2,8 +2,7 @@
|
||||
// ssl/context.hpp
|
||||
// ~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -17,16 +16,382 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
#include "asio/ssl/basic_context.hpp"
|
||||
#include "asio/ssl/context_service.hpp"
|
||||
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/ssl/basic_context.hpp"
|
||||
# include "asio/ssl/context_service.hpp"
|
||||
#else // defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include <string>
|
||||
# include "asio/io_service.hpp"
|
||||
# include "asio/ssl/context_base.hpp"
|
||||
# include "asio/ssl/detail/openssl_types.hpp"
|
||||
# include "asio/ssl/detail/openssl_init.hpp"
|
||||
# include "asio/ssl/detail/password_callback.hpp"
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
/// Typedef for the typical usage of context.
|
||||
typedef basic_context<context_service> context;
|
||||
|
||||
#else // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
class context
|
||||
: public context_base,
|
||||
private noncopyable
|
||||
{
|
||||
public:
|
||||
/// The native handle type of the SSL context.
|
||||
typedef SSL_CTX* native_handle_type;
|
||||
|
||||
/// Constructor.
|
||||
ASIO_DECL explicit context(method m);
|
||||
|
||||
/// Deprecated constructor taking a reference to an io_service object.
|
||||
ASIO_DECL context(asio::io_service&, method m);
|
||||
|
||||
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a context from another.
|
||||
/**
|
||||
* This constructor moves an SSL context from one object to another.
|
||||
*
|
||||
* @param other The other context object from which the move will occur.
|
||||
*
|
||||
* @note Following the move, the following operations only are valid for the
|
||||
* moved-from object:
|
||||
* @li Destruction.
|
||||
* @li As a target for move-assignment.
|
||||
*/
|
||||
ASIO_DECL context(context&& other);
|
||||
|
||||
/// Move-assign a context from another.
|
||||
/**
|
||||
* This assignment operator moves an SSL context from one object to another.
|
||||
*
|
||||
* @param other The other context object from which the move will occur.
|
||||
*
|
||||
* @note Following the move, the following operations only are valid for the
|
||||
* moved-from object:
|
||||
* @li Destruction.
|
||||
* @li As a target for move-assignment.
|
||||
*/
|
||||
ASIO_DECL context& operator=(context&& other);
|
||||
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destructor.
|
||||
ASIO_DECL ~context();
|
||||
|
||||
/// Get the underlying implementation in the native type.
|
||||
/**
|
||||
* This function may be used to obtain the underlying implementation of the
|
||||
* context. This is intended to allow access to context functionality that is
|
||||
* not otherwise provided.
|
||||
*/
|
||||
ASIO_DECL native_handle_type native_handle();
|
||||
|
||||
/// Set options on the context.
|
||||
/**
|
||||
* This function may be used to configure the SSL options used by the context.
|
||||
*
|
||||
* @param o A bitmask of options. The available option values are defined in
|
||||
* the context_base class. The options are bitwise-ored with any existing
|
||||
* value for the options.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void set_options(options o);
|
||||
|
||||
/// Set options on the context.
|
||||
/**
|
||||
* This function may be used to configure the SSL options used by the context.
|
||||
*
|
||||
* @param o A bitmask of options. The available option values are defined in
|
||||
* the context_base class. The options are bitwise-ored with any existing
|
||||
* value for the options.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code set_options(options o,
|
||||
asio::error_code& ec);
|
||||
|
||||
/// Set the peer verification mode.
|
||||
/**
|
||||
* This function may be used to configure the peer verification mode used by
|
||||
* the context.
|
||||
*
|
||||
* @param v A bitmask of peer verification modes. The available verify_mode
|
||||
* values are defined in the context_base class.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void set_verify_mode(verify_mode v);
|
||||
|
||||
/// Set the peer verification mode.
|
||||
/**
|
||||
* This function may be used to configure the peer verification mode used by
|
||||
* the context.
|
||||
*
|
||||
* @param v A bitmask of peer verification modes. The available verify_mode
|
||||
* values are defined in the context_base class.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code set_verify_mode(
|
||||
verify_mode v, asio::error_code& ec);
|
||||
|
||||
/// Load a certification authority file for performing verification.
|
||||
/**
|
||||
* This function is used to load one or more trusted certification authorities
|
||||
* from a file.
|
||||
*
|
||||
* @param filename The name of a file containing certification authority
|
||||
* certificates in PEM format.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void load_verify_file(const std::string& filename);
|
||||
|
||||
/// Load a certification authority file for performing verification.
|
||||
/**
|
||||
* This function is used to load the certificates for one or more trusted
|
||||
* certification authorities from a file.
|
||||
*
|
||||
* @param filename The name of a file containing certification authority
|
||||
* certificates in PEM format.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code load_verify_file(
|
||||
const std::string& filename, asio::error_code& ec);
|
||||
|
||||
/// Add a directory containing certificate authority files to be used for
|
||||
/// performing verification.
|
||||
/**
|
||||
* This function is used to specify the name of a directory containing
|
||||
* certification authority certificates. Each file in the directory must
|
||||
* contain a single certificate. The files must be named using the subject
|
||||
* name's hash and an extension of ".0".
|
||||
*
|
||||
* @param path The name of a directory containing the certificates.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void add_verify_path(const std::string& path);
|
||||
|
||||
/// Add a directory containing certificate authority files to be used for
|
||||
/// performing verification.
|
||||
/**
|
||||
* This function is used to specify the name of a directory containing
|
||||
* certification authority certificates. Each file in the directory must
|
||||
* contain a single certificate. The files must be named using the subject
|
||||
* name's hash and an extension of ".0".
|
||||
*
|
||||
* @param path The name of a directory containing the certificates.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code add_verify_path(
|
||||
const std::string& path, asio::error_code& ec);
|
||||
|
||||
/// Use a certificate from a file.
|
||||
/**
|
||||
* This function is used to load a certificate into the context from a file.
|
||||
*
|
||||
* @param filename The name of the file containing the certificate.
|
||||
*
|
||||
* @param format The file format (ASN.1 or PEM).
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void use_certificate_file(
|
||||
const std::string& filename, file_format format);
|
||||
|
||||
/// Use a certificate from a file.
|
||||
/**
|
||||
* This function is used to load a certificate into the context from a file.
|
||||
*
|
||||
* @param filename The name of the file containing the certificate.
|
||||
*
|
||||
* @param format The file format (ASN.1 or PEM).
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code use_certificate_file(
|
||||
const std::string& filename, file_format format,
|
||||
asio::error_code& ec);
|
||||
|
||||
/// Use a certificate chain from a file.
|
||||
/**
|
||||
* This function is used to load a certificate chain into the context from a
|
||||
* file.
|
||||
*
|
||||
* @param filename The name of the file containing the certificate. The file
|
||||
* must use the PEM format.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void use_certificate_chain_file(const std::string& filename);
|
||||
|
||||
/// Use a certificate chain from a file.
|
||||
/**
|
||||
* This function is used to load a certificate chain into the context from a
|
||||
* file.
|
||||
*
|
||||
* @param filename The name of the file containing the certificate. The file
|
||||
* must use the PEM format.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code use_certificate_chain_file(
|
||||
const std::string& filename, asio::error_code& ec);
|
||||
|
||||
/// Use a private key from a file.
|
||||
/**
|
||||
* This function is used to load a private key into the context from a file.
|
||||
*
|
||||
* @param filename The name of the file containing the private key.
|
||||
*
|
||||
* @param format The file format (ASN.1 or PEM).
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void use_private_key_file(
|
||||
const std::string& filename, file_format format);
|
||||
|
||||
/// Use a private key from a file.
|
||||
/**
|
||||
* This function is used to load a private key into the context from a file.
|
||||
*
|
||||
* @param filename The name of the file containing the private key.
|
||||
*
|
||||
* @param format The file format (ASN.1 or PEM).
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code use_private_key_file(
|
||||
const std::string& filename, file_format format,
|
||||
asio::error_code& ec);
|
||||
|
||||
/// Use an RSA private key from a file.
|
||||
/**
|
||||
* This function is used to load an RSA private key into the context from a
|
||||
* file.
|
||||
*
|
||||
* @param filename The name of the file containing the RSA private key.
|
||||
*
|
||||
* @param format The file format (ASN.1 or PEM).
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void use_rsa_private_key_file(
|
||||
const std::string& filename, file_format format);
|
||||
|
||||
/// Use an RSA private key from a file.
|
||||
/**
|
||||
* This function is used to load an RSA private key into the context from a
|
||||
* file.
|
||||
*
|
||||
* @param filename The name of the file containing the RSA private key.
|
||||
*
|
||||
* @param format The file format (ASN.1 or PEM).
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code use_rsa_private_key_file(
|
||||
const std::string& filename, file_format format,
|
||||
asio::error_code& ec);
|
||||
|
||||
/// Use the specified file to obtain the temporary Diffie-Hellman parameters.
|
||||
/**
|
||||
* This function is used to load Diffie-Hellman parameters into the context
|
||||
* from a file.
|
||||
*
|
||||
* @param filename The name of the file containing the Diffie-Hellman
|
||||
* parameters. The file must use the PEM format.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
ASIO_DECL void use_tmp_dh_file(const std::string& filename);
|
||||
|
||||
/// Use the specified file to obtain the temporary Diffie-Hellman parameters.
|
||||
/**
|
||||
* This function is used to load Diffie-Hellman parameters into the context
|
||||
* from a file.
|
||||
*
|
||||
* @param filename The name of the file containing the Diffie-Hellman
|
||||
* parameters. The file must use the PEM format.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
ASIO_DECL asio::error_code use_tmp_dh_file(
|
||||
const std::string& filename, asio::error_code& ec);
|
||||
|
||||
/// Set the password callback.
|
||||
/**
|
||||
* This function is used to specify a callback function to obtain password
|
||||
* information about an encrypted key in PEM format.
|
||||
*
|
||||
* @param callback The function object to be used for obtaining the password.
|
||||
* The function signature of the handler must be:
|
||||
* @code std::string password_callback(
|
||||
* std::size_t max_length, // The maximum size for a password.
|
||||
* password_purpose purpose // Whether password is for reading or writing.
|
||||
* ); @endcode
|
||||
* The return value of the callback is a string containing the password.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename PasswordCallback>
|
||||
void set_password_callback(PasswordCallback callback);
|
||||
|
||||
/// Set the password callback.
|
||||
/**
|
||||
* This function is used to specify a callback function to obtain password
|
||||
* information about an encrypted key in PEM format.
|
||||
*
|
||||
* @param callback The function object to be used for obtaining the password.
|
||||
* The function signature of the handler must be:
|
||||
* @code std::string password_callback(
|
||||
* std::size_t max_length, // The maximum size for a password.
|
||||
* password_purpose purpose // Whether password is for reading or writing.
|
||||
* ); @endcode
|
||||
* The return value of the callback is a string containing the password.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
template <typename PasswordCallback>
|
||||
asio::error_code set_password_callback(PasswordCallback callback,
|
||||
asio::error_code& ec);
|
||||
|
||||
private:
|
||||
// Helper function used to set a password callback.
|
||||
ASIO_DECL asio::error_code do_set_password_callback(
|
||||
detail::password_callback_base* callback, asio::error_code& ec);
|
||||
|
||||
// Callback used when the SSL implementation wants a password.
|
||||
ASIO_DECL static int password_callback_function(
|
||||
char* buf, int size, int purpose, void* data);
|
||||
|
||||
// The underlying native implementation.
|
||||
native_handle_type handle_;
|
||||
|
||||
// Ensure openssl is initialised.
|
||||
asio::ssl::detail::openssl_init<> init_;
|
||||
};
|
||||
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/ssl/impl/context.hpp"
|
||||
#if defined(ASIO_HEADER_ONLY)
|
||||
# include "asio/ssl/impl/context.ipp"
|
||||
#endif // defined(ASIO_HEADER_ONLY)
|
||||
|
||||
#endif // ASIO_SSL_CONTEXT_HPP
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ssl/context_base.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
@ -2,8 +2,7 @@
|
||||
// ssl/context_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -18,15 +17,21 @@
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#include "asio/ssl/old/context_service.hpp"
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/ssl/old/context_service.hpp"
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
using asio::ssl::old::context_service;
|
||||
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
|
71
asio/include/asio/ssl/detail/buffer_space.hpp
Normal file
71
asio/include/asio/ssl/detail/buffer_space.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// ssl/detail/buffer_space.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_BUFFER_SPACE_HPP
|
||||
#define ASIO_SSL_DETAIL_BUFFER_SPACE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include <vector>
|
||||
# include "asio/buffer.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
struct buffer_space
|
||||
{
|
||||
// Returned by functions to indicate that the engine wants input. The input
|
||||
// buffer should be updated to point to the data.
|
||||
static const int want_input = -1;
|
||||
|
||||
// Returned by functions to indicate that the engine wants to write output.
|
||||
// The output buffer points to the data to be written.
|
||||
static const int want_output = -2;
|
||||
|
||||
// A buffer that may be used to prepare output intended for the transport.
|
||||
std::vector<unsigned char> output_buffer;
|
||||
|
||||
// The buffer pointing to the data to be written by the transport.
|
||||
asio::const_buffer output;
|
||||
|
||||
// A buffer that may be used to read input intended for the engine.
|
||||
std::vector<unsigned char> input_buffer;
|
||||
|
||||
// The buffer pointing to the engine's unconsumed input.
|
||||
asio::const_buffer input;
|
||||
|
||||
// Constructor sets up the buffers.
|
||||
buffer_space()
|
||||
: output_buffer(16384),
|
||||
input_buffer(16384)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_BUFFER_SPACE_HPP
|
117
asio/include/asio/ssl/detail/engine.hpp
Normal file
117
asio/include/asio/ssl/detail/engine.hpp
Normal file
@ -0,0 +1,117 @@
|
||||
//
|
||||
// ssl/detail/engine.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_ENGINE_HPP
|
||||
#define ASIO_SSL_DETAIL_ENGINE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/detail/static_mutex.hpp"
|
||||
# include "asio/ssl/detail/buffer_space.hpp"
|
||||
# include "asio/ssl/detail/openssl_types.hpp"
|
||||
# include "asio/ssl/stream_base.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
class engine
|
||||
{
|
||||
public:
|
||||
// Construct a new engine for the specified context.
|
||||
ASIO_DECL explicit engine(SSL_CTX* context);
|
||||
|
||||
// Destructor.
|
||||
ASIO_DECL ~engine();
|
||||
|
||||
// Get the underlying implementation in the native type.
|
||||
ASIO_DECL SSL* native_handle();
|
||||
|
||||
// Perform an SSL handshake using either SSL_connect (client-side) or
|
||||
// SSL_accept (server-side).
|
||||
ASIO_DECL int handshake(stream_base::handshake_type type,
|
||||
buffer_space& space, asio::error_code& ec);
|
||||
|
||||
// Perform a graceful shutdown of the SSL session.
|
||||
ASIO_DECL int shutdown(buffer_space& space,
|
||||
asio::error_code& ec);
|
||||
|
||||
// Write bytes to the SSL session.
|
||||
ASIO_DECL int write(const asio::const_buffer& data,
|
||||
buffer_space& space, asio::error_code& ec);
|
||||
|
||||
// Read bytes from the SSL session.
|
||||
ASIO_DECL int read(const asio::mutable_buffer& data,
|
||||
buffer_space& space, asio::error_code& ec);
|
||||
|
||||
// Map an error::eof code returned by the underlying transport according to
|
||||
// the type and state of the SSL session. Returns a const reference to the
|
||||
// error code object, suitable for passing to a completion handler.
|
||||
ASIO_DECL const asio::error_code& map_error_code(
|
||||
asio::error_code& ec) const;
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
engine(const engine&);
|
||||
engine& operator=(const engine&);
|
||||
|
||||
// The SSL_accept function may not be thread safe. This mutex is used to
|
||||
// protect all calls to the SSL_accept function.
|
||||
ASIO_DECL static asio::detail::static_mutex& accept_mutex();
|
||||
|
||||
// Perform one operation. Returns >= 0 on success or error, want_read if the
|
||||
// operation needs more input, or want_write if it needs to write some output
|
||||
// before the operation can complete.
|
||||
ASIO_DECL int perform(int (engine::* op)(void*, std::size_t),
|
||||
void* data, std::size_t length,
|
||||
buffer_space& space, asio::error_code& ec);
|
||||
|
||||
// Adapt the SSL_accept function to the signature needed for perform().
|
||||
ASIO_DECL int do_accept(void*, std::size_t);
|
||||
|
||||
// Adapt the SSL_connect function to the signature needed for perform().
|
||||
ASIO_DECL int do_connect(void*, std::size_t);
|
||||
|
||||
// Adapt the SSL_shutdown function to the signature needed for perform().
|
||||
ASIO_DECL int do_shutdown(void*, std::size_t);
|
||||
|
||||
// Adapt the SSL_read function to the signature needed for perform().
|
||||
ASIO_DECL int do_read(void* data, std::size_t length);
|
||||
|
||||
// Adapt the SSL_write function to the signature needed for perform().
|
||||
ASIO_DECL int do_write(void* data, std::size_t length);
|
||||
|
||||
SSL* ssl_;
|
||||
BIO* ext_bio_;
|
||||
};
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#if defined(ASIO_HEADER_ONLY)
|
||||
# include "asio/ssl/detail/impl/engine.ipp"
|
||||
#endif // defined(ASIO_HEADER_ONLY)
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_ENGINE_HPP
|
107
asio/include/asio/ssl/detail/handshake_op.hpp
Normal file
107
asio/include/asio/ssl/detail/handshake_op.hpp
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// ssl/detail/handshake_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP
|
||||
#define ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/detail/handler_alloc_helpers.hpp"
|
||||
# include "asio/detail/handler_invoke_helpers.hpp"
|
||||
# include "asio/ssl/detail/buffer_space.hpp"
|
||||
# include "asio/ssl/detail/engine.hpp"
|
||||
# include "asio/ssl/detail/transport.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
template <typename Stream, typename HandshakeHandler>
|
||||
class handshake_op
|
||||
{
|
||||
public:
|
||||
handshake_op(detail::engine& engine, detail::transport<Stream>& transport,
|
||||
detail::buffer_space& space, stream_base::handshake_type type,
|
||||
HandshakeHandler& handler)
|
||||
: engine_(engine),
|
||||
transport_(transport),
|
||||
space_(space),
|
||||
type_(type),
|
||||
handler_(ASIO_MOVE_CAST(HandshakeHandler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(asio::error_code ec, int result, int start = 0)
|
||||
{
|
||||
switch (start)
|
||||
{
|
||||
case 1:
|
||||
do
|
||||
{
|
||||
result = engine_.handshake(type_, space_, ec);
|
||||
transport_.async(result, space_, ec, start, *this);
|
||||
return; default:;
|
||||
} while (result < 0);
|
||||
|
||||
handler_(engine_.map_error_code(ec));
|
||||
}
|
||||
}
|
||||
|
||||
//private:
|
||||
detail::engine& engine_;
|
||||
detail::transport<Stream>& transport_;
|
||||
detail::buffer_space& space_;
|
||||
stream_base::handshake_type type_;
|
||||
HandshakeHandler handler_;
|
||||
};
|
||||
|
||||
template <typename Stream, typename HandshakeHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
handshake_op<Stream, HandshakeHandler>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Stream, typename HandshakeHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
handshake_op<Stream, HandshakeHandler>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Stream, typename HandshakeHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
handshake_op<Stream, HandshakeHandler>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP
|
219
asio/include/asio/ssl/detail/impl/engine.ipp
Normal file
219
asio/include/asio/ssl/detail/impl/engine.ipp
Normal file
@ -0,0 +1,219 @@
|
||||
//
|
||||
// ssl/detail/impl/engine.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_IMPL_ENGINE_IPP
|
||||
#define ASIO_SSL_DETAIL_IMPL_ENGINE_IPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/ssl/detail/engine.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
engine::engine(SSL_CTX* context)
|
||||
: ssl_(::SSL_new(context))
|
||||
{
|
||||
accept_mutex().init();
|
||||
|
||||
::SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
::SSL_set_mode(ssl_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
::BIO* int_bio = 0;
|
||||
::BIO_new_bio_pair(&int_bio, 0, &ext_bio_, 0);
|
||||
::SSL_set_bio(ssl_, int_bio, int_bio);
|
||||
}
|
||||
|
||||
engine::~engine()
|
||||
{
|
||||
::BIO_free(ext_bio_);
|
||||
::SSL_free(ssl_);
|
||||
}
|
||||
|
||||
SSL* engine::native_handle()
|
||||
{
|
||||
return ssl_;
|
||||
}
|
||||
|
||||
int engine::handshake(stream_base::handshake_type type,
|
||||
buffer_space& space, asio::error_code& ec)
|
||||
{
|
||||
return perform((type == asio::ssl::stream_base::client)
|
||||
? &engine::do_connect : &engine::do_accept, 0, 0, space, ec);
|
||||
}
|
||||
|
||||
int engine::shutdown(buffer_space& space, asio::error_code& ec)
|
||||
{
|
||||
return perform(&engine::do_shutdown, 0, 0, space, ec);
|
||||
}
|
||||
|
||||
int engine::write(const asio::const_buffer& data,
|
||||
buffer_space& space, asio::error_code& ec)
|
||||
{
|
||||
return perform(&engine::do_write,
|
||||
const_cast<void*>(asio::buffer_cast<const void*>(data)),
|
||||
asio::buffer_size(data), space, ec);
|
||||
}
|
||||
|
||||
int engine::read(const asio::mutable_buffer& data,
|
||||
buffer_space& space, asio::error_code& ec)
|
||||
{
|
||||
return perform(&engine::do_read,
|
||||
asio::buffer_cast<void*>(data),
|
||||
asio::buffer_size(data), space, ec);
|
||||
}
|
||||
|
||||
const asio::error_code& engine::map_error_code(
|
||||
asio::error_code& ec) const
|
||||
{
|
||||
// We only want to map the error::eof code.
|
||||
if (ec != asio::error::eof)
|
||||
return ec;
|
||||
|
||||
// If there's data yet to be read, it's an error.
|
||||
if (BIO_wpending(ext_bio_))
|
||||
{
|
||||
ec = asio::error_code(
|
||||
ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
// SSL v2 doesn't provide a protocol-level shutdown, so an eof on the
|
||||
// underlying transport is passed through.
|
||||
if (ssl_ && ssl_->version == SSL2_VERSION)
|
||||
return ec;
|
||||
|
||||
// Otherwise, the peer should have negotiated a proper shutdown.
|
||||
ec = asio::error_code(
|
||||
ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
asio::detail::static_mutex& engine::accept_mutex()
|
||||
{
|
||||
static asio::detail::static_mutex mutex = ASIO_STATIC_MUTEX_INIT;
|
||||
return mutex;
|
||||
}
|
||||
|
||||
int engine::perform(int (engine::* op)(void*, std::size_t),
|
||||
void* data, std::size_t length,
|
||||
buffer_space& space, asio::error_code& ec)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
std::size_t pending_output_before = ::BIO_ctrl_pending(ext_bio_);
|
||||
int result = (this->*op)(data, length);
|
||||
int ssl_error = ::SSL_get_error(ssl_, result);
|
||||
int sys_error = ::ERR_get_error();
|
||||
std::size_t pending_output_after = ::BIO_ctrl_pending(ext_bio_);
|
||||
|
||||
if (ssl_error == SSL_ERROR_SSL)
|
||||
{
|
||||
ec = asio::error_code(sys_error,
|
||||
asio::error::get_ssl_category());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssl_error == SSL_ERROR_SYSCALL)
|
||||
{
|
||||
ec = asio::error_code(sys_error,
|
||||
asio::error::get_system_category());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pending_output_after > 0 && asio::buffer_size(space.output) == 0)
|
||||
{
|
||||
int length = ::BIO_read(ext_bio_, &space.output_buffer[0], 16384);
|
||||
space.output = asio::buffer(space.output_buffer, length);
|
||||
}
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
ec = asio::error_code();
|
||||
return result;
|
||||
}
|
||||
|
||||
if (ssl_error == SSL_ERROR_WANT_WRITE
|
||||
|| pending_output_after > pending_output_before)
|
||||
{
|
||||
ec = asio::error_code();
|
||||
return buffer_space::want_output;
|
||||
}
|
||||
else if (ssl_error == SSL_ERROR_WANT_READ)
|
||||
{
|
||||
if (asio::buffer_size(space.input) == 0)
|
||||
{
|
||||
ec = asio::error_code();
|
||||
return buffer_space::want_input;
|
||||
}
|
||||
|
||||
int length = ::BIO_write(ext_bio_,
|
||||
asio::buffer_cast<const void*>(space.input),
|
||||
static_cast<int>(asio::buffer_size(space.input)));
|
||||
space.input = space.input + length;
|
||||
}
|
||||
else if (::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN)
|
||||
{
|
||||
ec = asio::error::eof;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int engine::do_accept(void*, std::size_t)
|
||||
{
|
||||
asio::detail::static_mutex lock(accept_mutex());
|
||||
return ::SSL_accept(ssl_);
|
||||
}
|
||||
|
||||
int engine::do_connect(void*, std::size_t)
|
||||
{
|
||||
return ::SSL_connect(ssl_);
|
||||
}
|
||||
|
||||
int engine::do_shutdown(void*, std::size_t)
|
||||
{
|
||||
int result = ::SSL_shutdown(ssl_);
|
||||
if (result == 0)
|
||||
result = ::SSL_shutdown(ssl_);
|
||||
return result;
|
||||
}
|
||||
|
||||
int engine::do_read(void* data, std::size_t length)
|
||||
{
|
||||
return ::SSL_read(ssl_, data, length < INT_MAX ? length : INT_MAX);
|
||||
}
|
||||
|
||||
int engine::do_write(void* data, std::size_t length)
|
||||
{
|
||||
return ::SSL_write(ssl_, data, length < INT_MAX ? length : INT_MAX);
|
||||
}
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_IMPL_ENGINE_IPP
|
@ -2,7 +2,7 @@
|
||||
// ssl/detail/openssl_types.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
72
asio/include/asio/ssl/detail/password_callback.hpp
Normal file
72
asio/include/asio/ssl/detail/password_callback.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// ssl/detail/password_callback.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP
|
||||
#define ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include <cstddef>
|
||||
# include <string>
|
||||
# include "asio/ssl/context_base.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
class password_callback_base
|
||||
{
|
||||
public:
|
||||
virtual ~password_callback_base()
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::string call(std::size_t size,
|
||||
context_base::password_purpose purpose) = 0;
|
||||
};
|
||||
|
||||
template <typename PasswordCallback>
|
||||
class password_callback : public password_callback_base
|
||||
{
|
||||
public:
|
||||
explicit password_callback(PasswordCallback callback)
|
||||
: callback_(callback)
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::string call(std::size_t size,
|
||||
context_base::password_purpose purpose)
|
||||
{
|
||||
return callback_(size, purpose);
|
||||
}
|
||||
|
||||
private:
|
||||
PasswordCallback callback_;
|
||||
};
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP
|
114
asio/include/asio/ssl/detail/read_op.hpp
Normal file
114
asio/include/asio/ssl/detail/read_op.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
//
|
||||
// ssl/detail/read_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_READ_OP_HPP
|
||||
#define ASIO_SSL_DETAIL_READ_OP_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/detail/buffer_sequence_adapter.hpp"
|
||||
# include "asio/detail/handler_alloc_helpers.hpp"
|
||||
# include "asio/detail/handler_invoke_helpers.hpp"
|
||||
# include "asio/ssl/detail/buffer_space.hpp"
|
||||
# include "asio/ssl/detail/engine.hpp"
|
||||
# include "asio/ssl/detail/transport.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
template <typename Stream, typename MutableBufferSequence, typename ReadHandler>
|
||||
class read_op
|
||||
{
|
||||
public:
|
||||
read_op(detail::engine& engine, detail::transport<Stream>& transport,
|
||||
detail::buffer_space& space, const MutableBufferSequence& buffers,
|
||||
ReadHandler& handler)
|
||||
: engine_(engine),
|
||||
transport_(transport),
|
||||
space_(space),
|
||||
buffers_(buffers),
|
||||
handler_(ASIO_MOVE_CAST(ReadHandler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(asio::error_code ec, int result, int start = 0)
|
||||
{
|
||||
asio::mutable_buffer buffer =
|
||||
asio::detail::buffer_sequence_adapter<asio::mutable_buffer,
|
||||
MutableBufferSequence>::first(buffers_);
|
||||
|
||||
switch (start)
|
||||
{
|
||||
case 1:
|
||||
do
|
||||
{
|
||||
result = engine_.read(buffer, space_, ec);
|
||||
transport_.async(result, space_, ec, start, *this);
|
||||
return; default:;
|
||||
} while (result < 0);
|
||||
|
||||
handler_(engine_.map_error_code(ec),
|
||||
static_cast<const std::size_t>(result));
|
||||
}
|
||||
}
|
||||
|
||||
//private:
|
||||
detail::engine& engine_;
|
||||
detail::transport<Stream>& transport_;
|
||||
detail::buffer_space& space_;
|
||||
MutableBufferSequence buffers_;
|
||||
ReadHandler handler_;
|
||||
};
|
||||
|
||||
template <typename Stream, typename MutableBufferSequence, typename ReadHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
read_op<Stream, MutableBufferSequence, ReadHandler>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Stream, typename MutableBufferSequence, typename ReadHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
read_op<Stream, MutableBufferSequence, ReadHandler>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Stream,
|
||||
typename MutableBufferSequence, typename ReadHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
read_op<Stream, MutableBufferSequence, ReadHandler>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_READ_OP_HPP
|
104
asio/include/asio/ssl/detail/shutdown_op.hpp
Normal file
104
asio/include/asio/ssl/detail/shutdown_op.hpp
Normal file
@ -0,0 +1,104 @@
|
||||
//
|
||||
// ssl/detail/shutdown_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP
|
||||
#define ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/detail/handler_alloc_helpers.hpp"
|
||||
# include "asio/detail/handler_invoke_helpers.hpp"
|
||||
# include "asio/ssl/detail/buffer_space.hpp"
|
||||
# include "asio/ssl/detail/engine.hpp"
|
||||
# include "asio/ssl/detail/transport.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
template <typename Stream, typename ShutdownHandler>
|
||||
class shutdown_op
|
||||
{
|
||||
public:
|
||||
shutdown_op(detail::engine& engine, detail::transport<Stream>& transport,
|
||||
detail::buffer_space& space, ShutdownHandler& handler)
|
||||
: engine_(engine),
|
||||
transport_(transport),
|
||||
space_(space),
|
||||
handler_(ASIO_MOVE_CAST(ShutdownHandler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(asio::error_code ec, int result, int start = 0)
|
||||
{
|
||||
switch (start)
|
||||
{
|
||||
case 1:
|
||||
do
|
||||
{
|
||||
result = engine_.shutdown(space_, ec);
|
||||
transport_.async(result, space_, ec, start, *this);
|
||||
return; default:;
|
||||
} while (result < 0);
|
||||
|
||||
handler_(engine_.map_error_code(ec));
|
||||
}
|
||||
}
|
||||
|
||||
//private:
|
||||
detail::engine& engine_;
|
||||
detail::transport<Stream>& transport_;
|
||||
detail::buffer_space& space_;
|
||||
ShutdownHandler handler_;
|
||||
};
|
||||
|
||||
template <typename Stream, typename ShutdownHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
shutdown_op<Stream, ShutdownHandler>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Stream, typename ShutdownHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
shutdown_op<Stream, ShutdownHandler>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Stream, typename ShutdownHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
shutdown_op<Stream, ShutdownHandler>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP
|
125
asio/include/asio/ssl/detail/transport.hpp
Normal file
125
asio/include/asio/ssl/detail/transport.hpp
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// ssl/detail/transport.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_TRANSPORT_HPP
|
||||
#define ASIO_SSL_DETAIL_TRANSPORT_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/deadline_timer.hpp"
|
||||
# include "asio/ssl/detail/buffer_space.hpp"
|
||||
# include "asio/ssl/detail/transport_op.hpp"
|
||||
# include "asio/write.hpp"
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
template <typename Stream>
|
||||
class transport
|
||||
{
|
||||
public:
|
||||
// The type of the next layer.
|
||||
typedef typename boost::remove_reference<Stream>::type next_layer_type;
|
||||
|
||||
// The type of the lowest layer.
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
// Constructor initialises the underlying stream.
|
||||
template <typename Arg>
|
||||
explicit transport(Arg& arg)
|
||||
: next_layer_(arg),
|
||||
pending_read_(next_layer_.lowest_layer().get_io_service()),
|
||||
pending_write_(next_layer_.lowest_layer().get_io_service())
|
||||
{
|
||||
pending_read_.expires_at(boost::posix_time::neg_infin);
|
||||
pending_write_.expires_at(boost::posix_time::neg_infin);
|
||||
}
|
||||
|
||||
asio::io_service& get_io_service()
|
||||
{
|
||||
return next_layer_.lowest_layer().get_io_service();
|
||||
}
|
||||
|
||||
next_layer_type& next_layer()
|
||||
{
|
||||
return next_layer_;
|
||||
}
|
||||
|
||||
const next_layer_type& next_layer() const
|
||||
{
|
||||
return next_layer_;
|
||||
}
|
||||
|
||||
lowest_layer_type& lowest_layer()
|
||||
{
|
||||
return next_layer_.lowest_layer();
|
||||
}
|
||||
|
||||
const lowest_layer_type& lowest_layer() const
|
||||
{
|
||||
return next_layer_.lowest_layer();
|
||||
}
|
||||
|
||||
int sync(int result, buffer_space& space, asio::error_code& ec)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case detail::buffer_space::want_input:
|
||||
space.input = asio::buffer(space.input_buffer,
|
||||
next_layer_.read_some(asio::buffer(space.input_buffer), ec));
|
||||
break;
|
||||
default:
|
||||
if (ec || asio::buffer_size(space.output) == 0)
|
||||
break;
|
||||
case detail::buffer_space::want_output:
|
||||
space.output =
|
||||
space.output + asio::write(next_layer_,
|
||||
asio::buffer(space.output), ec);
|
||||
break;
|
||||
}
|
||||
return ec ? 0 : result;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void async(int result, buffer_space& space,
|
||||
const asio::error_code& ec, int start, Handler& handler)
|
||||
{
|
||||
transport_op<next_layer_type, Handler>(
|
||||
next_layer_, pending_read_, pending_write_, result, space, ec, handler)(
|
||||
asio::error_code(), 0, start ? -1 : 1);
|
||||
}
|
||||
|
||||
private:
|
||||
Stream next_layer_;
|
||||
asio::deadline_timer pending_read_;
|
||||
asio::deadline_timer pending_write_;
|
||||
};
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_TRANSPORT_HPP
|
207
asio/include/asio/ssl/detail/transport_op.hpp
Normal file
207
asio/include/asio/ssl/detail/transport_op.hpp
Normal file
@ -0,0 +1,207 @@
|
||||
//
|
||||
// ssl/detail/transport_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_TRANSPORT_OP_HPP
|
||||
#define ASIO_SSL_DETAIL_TRANSPORT_OP_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/deadline_timer.hpp"
|
||||
# include "asio/detail/handler_alloc_helpers.hpp"
|
||||
# include "asio/detail/handler_invoke_helpers.hpp"
|
||||
# include "asio/ssl/detail/buffer_space.hpp"
|
||||
# include "asio/ssl/detail/engine.hpp"
|
||||
# include "asio/ssl/detail/transport.hpp"
|
||||
# include "asio/write.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
template <typename Stream, typename Handler>
|
||||
class transport_op
|
||||
{
|
||||
public:
|
||||
transport_op(Stream& next_layer, asio::deadline_timer& pending_read,
|
||||
asio::deadline_timer& pending_write, int result,
|
||||
detail::buffer_space& space, const asio::error_code& ec,
|
||||
Handler& handler)
|
||||
: next_layer_(next_layer),
|
||||
pending_read_(pending_read),
|
||||
pending_write_(pending_write),
|
||||
result_(result),
|
||||
space_(space),
|
||||
ec_(ec),
|
||||
handler_(ASIO_MOVE_CAST(Handler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const asio::error_code& ec,
|
||||
std::size_t bytes_transferred = 0, int start = 0)
|
||||
{
|
||||
switch (start)
|
||||
{
|
||||
case -1: // Called from initiating function.
|
||||
case 1: // Called after at least one async operation.
|
||||
switch (result_)
|
||||
{
|
||||
case detail::buffer_space::want_input:
|
||||
// The engine wants more data to be read from input. However, we cannot
|
||||
// allow more than one read operation at a time on the underlying
|
||||
// transport. The pending_read_ timer's expiry is to pos_infin if a
|
||||
// read is in progress, and neg_infin otherwise.
|
||||
if (pending_read_.expires_at() == boost::posix_time::neg_infin)
|
||||
{
|
||||
// Start reading some data from the underlying transport.
|
||||
next_layer_.async_read_some(
|
||||
asio::buffer(space_.input_buffer), *this);
|
||||
|
||||
// Prevent other read operations from being started.
|
||||
pending_read_.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait until the current read operation completes.
|
||||
pending_read_.async_wait(*this);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// The SSL operation as done, but there might be some data to be
|
||||
// written to the output. If there isn't anything to write then we can
|
||||
// invoke the handler, but we have to keep in mind that this function
|
||||
// might be being called from the async operation's initiating
|
||||
// function. In this case we're not allowed to call the handler
|
||||
// directly. Instead, issue a zero-sized read so that the handler runs
|
||||
// "as-if" posted using io_service::post().
|
||||
if (ec_ || asio::buffer_size(space_.output) == 0)
|
||||
{
|
||||
if (start == -1)
|
||||
{
|
||||
next_layer_.async_read_some(
|
||||
asio::buffer(space_.input_buffer, 0), *this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Indicate that we should continue on to run handler directly.
|
||||
start = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Fall through to process the pending output.
|
||||
|
||||
case detail::buffer_space::want_output:
|
||||
// The engine wants some data to be written to the output. However, we
|
||||
// cannot allow more than one write operation at a time on the
|
||||
// underlying transport. The pending_write_ timer's expiry is to
|
||||
// pos_infin if a write is in progress, and neg_infin otherwise.
|
||||
if (pending_write_.expires_at() == boost::posix_time::neg_infin)
|
||||
{
|
||||
// Start writing all the data to the underlying transport.
|
||||
asio::async_write(next_layer_,
|
||||
asio::buffer(space_.output), *this);
|
||||
|
||||
// Prevent other write operations from being started.
|
||||
pending_write_.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
else if (result_ == detail::buffer_space::want_output)
|
||||
{
|
||||
// Wait until the current write operation completes.
|
||||
pending_write_.async_wait(*this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Yield control if an async operation was started.
|
||||
if (start) return; default:
|
||||
if (!ec_) ec_ = ec;
|
||||
|
||||
switch (result_)
|
||||
{
|
||||
case detail::buffer_space::want_input:
|
||||
// Add received data to the engine's pending input.
|
||||
space_.input = asio::buffer(space_.input_buffer, bytes_transferred);
|
||||
|
||||
// Release any waiting read operations.
|
||||
pending_read_.expires_at(boost::posix_time::neg_infin);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ec || bytes_transferred == 0)
|
||||
break;
|
||||
// Fall through to remove the pending output.
|
||||
|
||||
case detail::buffer_space::want_output:
|
||||
// Remove written data from the engine's pending output.
|
||||
space_.output = space_.output + bytes_transferred;
|
||||
|
||||
// Release any waiting write operations.
|
||||
pending_write_.expires_at(boost::posix_time::neg_infin);
|
||||
break;
|
||||
}
|
||||
|
||||
handler_(static_cast<const asio::error_code&>(ec_),
|
||||
static_cast<const int>(ec ? 0 : result_));
|
||||
}
|
||||
}
|
||||
|
||||
//private:
|
||||
Stream& next_layer_;
|
||||
asio::deadline_timer& pending_read_;
|
||||
asio::deadline_timer& pending_write_;
|
||||
int result_;
|
||||
detail::buffer_space& space_;
|
||||
asio::error_code ec_;
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
template <typename Stream, typename Handler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
transport_op<Stream, Handler>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Stream, typename Handler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
transport_op<Stream, Handler>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Stream, typename Handler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
transport_op<Stream, Handler>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_TRANSPORT_OP_HPP
|
114
asio/include/asio/ssl/detail/write_op.hpp
Normal file
114
asio/include/asio/ssl/detail/write_op.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
//
|
||||
// ssl/detail/write_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_DETAIL_WRITE_OP_HPP
|
||||
#define ASIO_SSL_DETAIL_WRITE_OP_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/detail/buffer_sequence_adapter.hpp"
|
||||
# include "asio/detail/handler_alloc_helpers.hpp"
|
||||
# include "asio/detail/handler_invoke_helpers.hpp"
|
||||
# include "asio/ssl/detail/buffer_space.hpp"
|
||||
# include "asio/ssl/detail/engine.hpp"
|
||||
# include "asio/ssl/detail/transport.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
template <typename Stream, typename ConstBufferSequence, typename WriteHandler>
|
||||
class write_op
|
||||
{
|
||||
public:
|
||||
write_op(detail::engine& engine, detail::transport<Stream>& transport,
|
||||
detail::buffer_space& space, const ConstBufferSequence& buffers,
|
||||
WriteHandler& handler)
|
||||
: engine_(engine),
|
||||
transport_(transport),
|
||||
space_(space),
|
||||
buffers_(buffers),
|
||||
handler_(ASIO_MOVE_CAST(WriteHandler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(asio::error_code ec, int result, int start = 0)
|
||||
{
|
||||
asio::const_buffer buffer =
|
||||
asio::detail::buffer_sequence_adapter<asio::const_buffer,
|
||||
ConstBufferSequence>::first(buffers_);
|
||||
|
||||
switch (start)
|
||||
{
|
||||
case 1:
|
||||
do
|
||||
{
|
||||
result = engine_.write(buffer, space_, ec);
|
||||
transport_.async(result, space_, ec, start, *this);
|
||||
return; default:;
|
||||
} while (result < 0);
|
||||
|
||||
handler_(engine_.map_error_code(ec),
|
||||
static_cast<const std::size_t>(result));
|
||||
}
|
||||
}
|
||||
|
||||
//private:
|
||||
detail::engine& engine_;
|
||||
detail::transport<Stream>& transport_;
|
||||
detail::buffer_space& space_;
|
||||
ConstBufferSequence buffers_;
|
||||
WriteHandler handler_;
|
||||
};
|
||||
|
||||
template <typename Stream, typename ConstBufferSequence, typename WriteHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
write_op<Stream, ConstBufferSequence, WriteHandler>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Stream, typename ConstBufferSequence, typename WriteHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
write_op<Stream, ConstBufferSequence, WriteHandler>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Stream,
|
||||
typename ConstBufferSequence, typename WriteHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
write_op<Stream, ConstBufferSequence, WriteHandler>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_DETAIL_WRITE_OP_HPP
|
55
asio/include/asio/ssl/impl/context.hpp
Normal file
55
asio/include/asio/ssl/impl/context.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
//
|
||||
// ssl/impl/context.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_IMPL_CONTEXT_HPP
|
||||
#define ASIO_SSL_IMPL_CONTEXT_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/detail/throw_error.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
template <typename PasswordCallback>
|
||||
void context::set_password_callback(PasswordCallback callback)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->set_password_callback(callback, ec);
|
||||
asio::detail::throw_error(ec, "set_password_callback");
|
||||
}
|
||||
|
||||
template <typename PasswordCallback>
|
||||
asio::error_code context::set_password_callback(
|
||||
PasswordCallback callback, asio::error_code& ec)
|
||||
{
|
||||
return do_set_password_callback(
|
||||
new detail::password_callback<PasswordCallback>(callback), ec);
|
||||
}
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_IMPL_CONTEXT_HPP
|
431
asio/include/asio/ssl/impl/context.ipp
Normal file
431
asio/include/asio/ssl/impl/context.ipp
Normal file
@ -0,0 +1,431 @@
|
||||
//
|
||||
// ssl/impl/context.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_SSL_IMPL_CONTEXT_IPP
|
||||
#define ASIO_SSL_IMPL_CONTEXT_IPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include <cstring>
|
||||
# include "asio/detail/throw_error.hpp"
|
||||
# include "asio/error.hpp"
|
||||
# include "asio/ssl/context.hpp"
|
||||
# include "asio/ssl/error.hpp"
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
#if !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
context::context(context::method m)
|
||||
: handle_(0)
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
case context::sslv2:
|
||||
handle_ = ::SSL_CTX_new(::SSLv2_method());
|
||||
break;
|
||||
case context::sslv2_client:
|
||||
handle_ = ::SSL_CTX_new(::SSLv2_client_method());
|
||||
break;
|
||||
case context::sslv2_server:
|
||||
handle_ = ::SSL_CTX_new(::SSLv2_server_method());
|
||||
break;
|
||||
case context::sslv3:
|
||||
handle_ = ::SSL_CTX_new(::SSLv3_method());
|
||||
break;
|
||||
case context::sslv3_client:
|
||||
handle_ = ::SSL_CTX_new(::SSLv3_client_method());
|
||||
break;
|
||||
case context::sslv3_server:
|
||||
handle_ = ::SSL_CTX_new(::SSLv3_server_method());
|
||||
break;
|
||||
case context::tlsv1:
|
||||
handle_ = ::SSL_CTX_new(::TLSv1_method());
|
||||
break;
|
||||
case context::tlsv1_client:
|
||||
handle_ = ::SSL_CTX_new(::TLSv1_client_method());
|
||||
break;
|
||||
case context::tlsv1_server:
|
||||
handle_ = ::SSL_CTX_new(::TLSv1_server_method());
|
||||
break;
|
||||
case context::sslv23:
|
||||
handle_ = ::SSL_CTX_new(::SSLv23_method());
|
||||
break;
|
||||
case context::sslv23_client:
|
||||
handle_ = ::SSL_CTX_new(::SSLv23_client_method());
|
||||
break;
|
||||
case context::sslv23_server:
|
||||
handle_ = ::SSL_CTX_new(::SSLv23_server_method());
|
||||
break;
|
||||
default:
|
||||
handle_ = ::SSL_CTX_new(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (handle_ == 0)
|
||||
{
|
||||
asio::error_code ec(::ERR_get_error(),
|
||||
asio::error::get_ssl_category());
|
||||
asio::detail::throw_error(ec, "context");
|
||||
}
|
||||
}
|
||||
|
||||
context::context(asio::io_service&, context::method m)
|
||||
: handle_(0)
|
||||
{
|
||||
context tmp(m);
|
||||
handle_ = tmp.handle_;
|
||||
tmp.handle_ = 0;
|
||||
}
|
||||
|
||||
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
context::context(context&& other)
|
||||
{
|
||||
handle_ = other.handle_;
|
||||
other.handle_ = 0;
|
||||
}
|
||||
|
||||
context& context::operator=(context&& other)
|
||||
{
|
||||
context tmp(ASIO_MOVE_CAST(context)(*this));
|
||||
handle_ = other.handle_;
|
||||
other.handle_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
context::~context()
|
||||
{
|
||||
if (handle_)
|
||||
{
|
||||
/*if (handle_->default_passwd_callback_userdata)
|
||||
{
|
||||
password_callback_type* callback =
|
||||
static_cast<password_callback_type*>(
|
||||
handle_->default_passwd_callback_userdata);
|
||||
delete callback;
|
||||
handle_->default_passwd_callback_userdata = 0;
|
||||
}*/
|
||||
|
||||
::SSL_CTX_free(handle_);
|
||||
}
|
||||
}
|
||||
|
||||
context::native_handle_type context::native_handle()
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
void context::set_options(context::options o)
|
||||
{
|
||||
asio::error_code ec;
|
||||
set_options(o, ec);
|
||||
asio::detail::throw_error(ec, "set_options");
|
||||
}
|
||||
|
||||
asio::error_code context::set_options(
|
||||
context::options o, asio::error_code& ec)
|
||||
{
|
||||
::SSL_CTX_set_options(handle_, o);
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
void context::set_verify_mode(context::verify_mode v)
|
||||
{
|
||||
asio::error_code ec;
|
||||
set_verify_mode(v, ec);
|
||||
asio::detail::throw_error(ec, "set_verify_mode");
|
||||
}
|
||||
|
||||
asio::error_code context::set_verify_mode(
|
||||
context::verify_mode v, asio::error_code& ec)
|
||||
{
|
||||
::SSL_CTX_set_verify(handle_, v, 0);
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
void context::load_verify_file(const std::string& filename)
|
||||
{
|
||||
asio::error_code ec;
|
||||
load_verify_file(filename, ec);
|
||||
asio::detail::throw_error(ec, "load_verify_file");
|
||||
}
|
||||
|
||||
asio::error_code context::load_verify_file(
|
||||
const std::string& filename, asio::error_code& ec)
|
||||
{
|
||||
if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1)
|
||||
{
|
||||
ec = asio::error_code(::ERR_get_error(),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
void context::add_verify_path(const std::string& path)
|
||||
{
|
||||
asio::error_code ec;
|
||||
add_verify_path(path, ec);
|
||||
asio::detail::throw_error(ec, "add_verify_path");
|
||||
}
|
||||
|
||||
asio::error_code context::add_verify_path(
|
||||
const std::string& path, asio::error_code& ec)
|
||||
{
|
||||
if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1)
|
||||
{
|
||||
ec = asio::error_code(::ERR_get_error(),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
void context::use_certificate_file(
|
||||
const std::string& filename, file_format format)
|
||||
{
|
||||
asio::error_code ec;
|
||||
use_certificate_file(filename, format, ec);
|
||||
asio::detail::throw_error(ec, "use_certificate_file");
|
||||
}
|
||||
|
||||
asio::error_code context::use_certificate_file(
|
||||
const std::string& filename, file_format format,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
int file_type;
|
||||
switch (format)
|
||||
{
|
||||
case context_base::asn1:
|
||||
file_type = SSL_FILETYPE_ASN1;
|
||||
break;
|
||||
case context_base::pem:
|
||||
file_type = SSL_FILETYPE_PEM;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ec = asio::error::invalid_argument;
|
||||
return ec;
|
||||
}
|
||||
}
|
||||
|
||||
if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1)
|
||||
{
|
||||
ec = asio::error_code(::ERR_get_error(),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
void context::use_certificate_chain_file(const std::string& filename)
|
||||
{
|
||||
asio::error_code ec;
|
||||
use_certificate_chain_file(filename, ec);
|
||||
asio::detail::throw_error(ec, "use_certificate_chain_file");
|
||||
}
|
||||
|
||||
asio::error_code context::use_certificate_chain_file(
|
||||
const std::string& filename, asio::error_code& ec)
|
||||
{
|
||||
if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1)
|
||||
{
|
||||
ec = asio::error_code(::ERR_get_error(),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
void context::use_private_key_file(
|
||||
const std::string& filename, context::file_format format)
|
||||
{
|
||||
asio::error_code ec;
|
||||
use_private_key_file(filename, format, ec);
|
||||
asio::detail::throw_error(ec, "use_private_key_file");
|
||||
}
|
||||
|
||||
asio::error_code context::use_private_key_file(
|
||||
const std::string& filename, context::file_format format,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
int file_type;
|
||||
switch (format)
|
||||
{
|
||||
case context_base::asn1:
|
||||
file_type = SSL_FILETYPE_ASN1;
|
||||
break;
|
||||
case context_base::pem:
|
||||
file_type = SSL_FILETYPE_PEM;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ec = asio::error::invalid_argument;
|
||||
return ec;
|
||||
}
|
||||
}
|
||||
|
||||
if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1)
|
||||
{
|
||||
ec = asio::error_code(::ERR_get_error(),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
void context::use_rsa_private_key_file(
|
||||
const std::string& filename, context::file_format format)
|
||||
{
|
||||
asio::error_code ec;
|
||||
use_rsa_private_key_file(filename, format, ec);
|
||||
asio::detail::throw_error(ec, "use_rsa_private_key_file");
|
||||
}
|
||||
|
||||
asio::error_code context::use_rsa_private_key_file(
|
||||
const std::string& filename, context::file_format format,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
int file_type;
|
||||
switch (format)
|
||||
{
|
||||
case context_base::asn1:
|
||||
file_type = SSL_FILETYPE_ASN1;
|
||||
break;
|
||||
case context_base::pem:
|
||||
file_type = SSL_FILETYPE_PEM;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ec = asio::error::invalid_argument;
|
||||
return ec;
|
||||
}
|
||||
}
|
||||
|
||||
if (::SSL_CTX_use_RSAPrivateKey_file(
|
||||
handle_, filename.c_str(), file_type) != 1)
|
||||
{
|
||||
ec = asio::error_code(::ERR_get_error(),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
void context::use_tmp_dh_file(const std::string& filename)
|
||||
{
|
||||
asio::error_code ec;
|
||||
use_tmp_dh_file(filename, ec);
|
||||
asio::detail::throw_error(ec, "use_tmp_dh_file");
|
||||
}
|
||||
|
||||
asio::error_code context::use_tmp_dh_file(
|
||||
const std::string& filename, asio::error_code& ec)
|
||||
{
|
||||
::BIO* bio = ::BIO_new_file(filename.c_str(), "r");
|
||||
if (!bio)
|
||||
{
|
||||
ec = asio::error::invalid_argument;
|
||||
return ec;
|
||||
}
|
||||
|
||||
::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0);
|
||||
if (!dh)
|
||||
{
|
||||
::BIO_free(bio);
|
||||
ec = asio::error::invalid_argument;
|
||||
return ec;
|
||||
}
|
||||
|
||||
::BIO_free(bio);
|
||||
int result = ::SSL_CTX_set_tmp_dh(handle_, dh);
|
||||
::DH_free(dh);
|
||||
if (result != 1)
|
||||
{
|
||||
ec = asio::error_code(::ERR_get_error(),
|
||||
asio::error::get_ssl_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
asio::error_code context::do_set_password_callback(
|
||||
detail::password_callback_base* callback, asio::error_code& ec)
|
||||
{
|
||||
if (handle_->default_passwd_callback_userdata)
|
||||
delete static_cast<detail::password_callback_base*>(
|
||||
handle_->default_passwd_callback_userdata);
|
||||
|
||||
handle_->default_passwd_callback_userdata = callback;
|
||||
|
||||
SSL_CTX_set_default_passwd_cb(handle_, &context::password_callback_function);
|
||||
|
||||
ec = asio::error_code();
|
||||
return ec;
|
||||
}
|
||||
|
||||
int context::password_callback_function(
|
||||
char* buf, int size, int purpose, void* data)
|
||||
{
|
||||
using namespace std; // For strncat and strlen.
|
||||
|
||||
if (data)
|
||||
{
|
||||
detail::password_callback_base* callback =
|
||||
static_cast<detail::password_callback_base*>(data);
|
||||
|
||||
std::string passwd = callback->call(static_cast<std::size_t>(size),
|
||||
purpose ? context_base::for_writing : context_base::for_reading);
|
||||
|
||||
*buf = '\0';
|
||||
strncat(buf, passwd.c_str(), size);
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // !defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SSL_IMPL_CONTEXT_IPP
|
@ -19,6 +19,8 @@
|
||||
# error Do not compile Asio library source with ASIO_HEADER_ONLY defined
|
||||
#endif
|
||||
|
||||
#include "asio/ssl/impl/context.ipp"
|
||||
#include "asio/ssl/impl/error.ipp"
|
||||
#include "asio/ssl/detail/impl/engine.ipp"
|
||||
|
||||
#endif // ASIO_IMPL_SRC_HPP
|
||||
|
@ -2,8 +2,7 @@
|
||||
// ssl/stream.hpp
|
||||
// ~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -18,15 +17,473 @@
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#include "asio/ssl/old/stream.hpp"
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/ssl/old/stream.hpp"
|
||||
#else // defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/detail/buffer_sequence_adapter.hpp"
|
||||
# include "asio/ssl/context.hpp"
|
||||
# include "asio/ssl/detail/buffer_space.hpp"
|
||||
# include "asio/ssl/detail/engine.hpp"
|
||||
# include "asio/ssl/detail/handshake_op.hpp"
|
||||
# include "asio/ssl/detail/read_op.hpp"
|
||||
# include "asio/ssl/detail/shutdown_op.hpp"
|
||||
# include "asio/ssl/detail/transport.hpp"
|
||||
# include "asio/ssl/detail/write_op.hpp"
|
||||
# include "asio/ssl/stream_base.hpp"
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
using asio::ssl::old::stream;
|
||||
|
||||
#else // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
/// Provides stream-oriented functionality using SSL.
|
||||
/**
|
||||
* The stream class template provides asynchronous and blocking stream-oriented
|
||||
* functionality using SSL.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe. The application must also ensure that all
|
||||
* asynchronous operations are performed within the same implicit or explicit
|
||||
* strand.
|
||||
*
|
||||
* @par Example
|
||||
* To use the SSL stream template with an ip::tcp::socket, you would write:
|
||||
* @code
|
||||
* asio::io_service io_service;
|
||||
* asio::ssl::context context(io_service, asio::ssl::context::sslv23);
|
||||
* asio::ssl::stream<asio::ip::tcp::socket> sock(io_service, context);
|
||||
* @endcode
|
||||
*
|
||||
* @par Concepts:
|
||||
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||
*/
|
||||
template <typename Stream>
|
||||
class stream : public stream_base
|
||||
{
|
||||
public:
|
||||
/// The native handle type of the SSL stream.
|
||||
typedef SSL* native_handle_type;
|
||||
|
||||
/// The type of the next layer.
|
||||
typedef typename boost::remove_reference<Stream>::type next_layer_type;
|
||||
|
||||
/// The type of the lowest layer.
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
/// Construct a stream.
|
||||
/**
|
||||
* This constructor creates a stream and initialises the underlying stream
|
||||
* object.
|
||||
*
|
||||
* @param arg The argument to be passed to initialise the underlying stream.
|
||||
*
|
||||
* @param context The SSL context to be used for the stream.
|
||||
*/
|
||||
template <typename Arg>
|
||||
stream(Arg& arg, context& ctx)
|
||||
: engine_(ctx.native_handle()),
|
||||
transport_(arg)
|
||||
{
|
||||
}
|
||||
|
||||
/// Destructor.
|
||||
~stream()
|
||||
{
|
||||
}
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
/**
|
||||
* This function may be used to obtain the io_service object that the stream
|
||||
* uses to dispatch handlers for asynchronous operations.
|
||||
*
|
||||
* @return A reference to the io_service object that stream will use to
|
||||
* dispatch handlers. Ownership is not transferred to the caller.
|
||||
*/
|
||||
asio::io_service& get_io_service()
|
||||
{
|
||||
return transport_.get_io_service();
|
||||
}
|
||||
|
||||
/// Get the underlying implementation in the native type.
|
||||
/**
|
||||
* This function may be used to obtain the underlying implementation of the
|
||||
* context. This is intended to allow access to context functionality that is
|
||||
* not otherwise provided.
|
||||
*/
|
||||
native_handle_type native_handle()
|
||||
{
|
||||
return engine_.native_handle();
|
||||
}
|
||||
|
||||
/// Get a reference to the next layer.
|
||||
/**
|
||||
* This function returns a reference to the next layer in a stack of stream
|
||||
* layers.
|
||||
*
|
||||
* @return A reference to the next layer in the stack of stream layers.
|
||||
* Ownership is not transferred to the caller.
|
||||
*/
|
||||
const next_layer_type& next_layer() const
|
||||
{
|
||||
return transport_.next_layer();
|
||||
}
|
||||
|
||||
/// Get a reference to the next layer.
|
||||
/**
|
||||
* This function returns a reference to the next layer in a stack of stream
|
||||
* layers.
|
||||
*
|
||||
* @return A reference to the next layer in the stack of stream layers.
|
||||
* Ownership is not transferred to the caller.
|
||||
*/
|
||||
next_layer_type& next_layer()
|
||||
{
|
||||
return transport_.next_layer();
|
||||
}
|
||||
|
||||
/// Get a reference to the lowest layer.
|
||||
/**
|
||||
* This function returns a reference to the lowest layer in a stack of
|
||||
* stream layers.
|
||||
*
|
||||
* @return A reference to the lowest layer in the stack of stream layers.
|
||||
* Ownership is not transferred to the caller.
|
||||
*/
|
||||
lowest_layer_type& lowest_layer()
|
||||
{
|
||||
return transport_.lowest_layer();
|
||||
}
|
||||
|
||||
/// Get a reference to the lowest layer.
|
||||
/**
|
||||
* This function returns a reference to the lowest layer in a stack of
|
||||
* stream layers.
|
||||
*
|
||||
* @return A reference to the lowest layer in the stack of stream layers.
|
||||
* Ownership is not transferred to the caller.
|
||||
*/
|
||||
const lowest_layer_type& lowest_layer() const
|
||||
{
|
||||
return transport_.lowest_layer();
|
||||
}
|
||||
|
||||
/// Perform SSL handshaking.
|
||||
/**
|
||||
* This function is used to perform SSL handshaking on the stream. The
|
||||
* function call will block until handshaking is complete or an error occurs.
|
||||
*
|
||||
* @param type The type of handshaking to be performed, i.e. as a client or as
|
||||
* a server.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void handshake(handshake_type type)
|
||||
{
|
||||
asio::error_code ec;
|
||||
handshake(type, ec);
|
||||
asio::detail::throw_error(ec, "handshake");
|
||||
}
|
||||
|
||||
/// Perform SSL handshaking.
|
||||
/**
|
||||
* This function is used to perform SSL handshaking on the stream. The
|
||||
* function call will block until handshaking is complete or an error occurs.
|
||||
*
|
||||
* @param type The type of handshaking to be performed, i.e. as a client or as
|
||||
* a server.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
asio::error_code handshake(handshake_type type,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int result = engine_.handshake(type, space_, ec);
|
||||
result = transport_.sync(result, space_, ec);
|
||||
if (result >= 0)
|
||||
return engine_.map_error_code(ec);
|
||||
}
|
||||
}
|
||||
|
||||
/// Start an asynchronous SSL handshake.
|
||||
/**
|
||||
* This function is used to asynchronously perform an SSL handshake on the
|
||||
* stream. This function call always returns immediately.
|
||||
*
|
||||
* @param type The type of handshaking to be performed, i.e. as a client or as
|
||||
* a server.
|
||||
*
|
||||
* @param handler The handler to be called when the handshake operation
|
||||
* completes. Copies will be made of the handler as required. The equivalent
|
||||
* function signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
*/
|
||||
template <typename HandshakeHandler>
|
||||
void async_handshake(handshake_type type,
|
||||
HandshakeHandler handler)
|
||||
{
|
||||
detail::handshake_op<Stream, HandshakeHandler>(
|
||||
engine_, transport_, space_, type, handler)(
|
||||
asio::error_code(), 0, 1);
|
||||
}
|
||||
|
||||
/// Shut down SSL on the stream.
|
||||
/**
|
||||
* This function is used to shut down SSL on the stream. The function call
|
||||
* will block until SSL has been shut down or an error occurs.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void shutdown()
|
||||
{
|
||||
asio::error_code ec;
|
||||
shutdown(ec);
|
||||
asio::detail::throw_error(ec, "shutdown");
|
||||
}
|
||||
|
||||
/// Shut down SSL on the stream.
|
||||
/**
|
||||
* This function is used to shut down SSL on the stream. The function call
|
||||
* will block until SSL has been shut down or an error occurs.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
asio::error_code shutdown(asio::error_code& ec)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int result = engine_.shutdown(space_, ec);
|
||||
result = transport_.sync(result, space_, ec);
|
||||
if (result >= 0)
|
||||
return engine_.map_error_code(ec);
|
||||
}
|
||||
}
|
||||
|
||||
/// Asynchronously shut down SSL on the stream.
|
||||
/**
|
||||
* This function is used to asynchronously shut down SSL on the stream. This
|
||||
* function call always returns immediately.
|
||||
*
|
||||
* @param handler The handler to be called when the handshake operation
|
||||
* completes. Copies will be made of the handler as required. The equivalent
|
||||
* function signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
*/
|
||||
template <typename ShutdownHandler>
|
||||
void async_shutdown(ShutdownHandler handler)
|
||||
{
|
||||
detail::shutdown_op<Stream, ShutdownHandler>(
|
||||
engine_, transport_, space_, handler)(
|
||||
asio::error_code(), 0, 1);
|
||||
}
|
||||
|
||||
/// Write some data to the stream.
|
||||
/**
|
||||
* This function is used to write data on the stream. The function call will
|
||||
* block until one or more bytes of data has been written successfully, or
|
||||
* until an error occurs.
|
||||
*
|
||||
* @param buffers The data to be written.
|
||||
*
|
||||
* @returns The number of bytes written.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note The write_some operation may not transmit all of the data to the
|
||||
* peer. Consider using the @ref write function if you need to ensure that all
|
||||
* data is written before the blocking operation completes.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t n = write_some(buffers, ec);
|
||||
asio::detail::throw_error(ec, "write_some");
|
||||
return n;
|
||||
}
|
||||
|
||||
/// Write some data to the stream.
|
||||
/**
|
||||
* This function is used to write data on the stream. The function call will
|
||||
* block until one or more bytes of data has been written successfully, or
|
||||
* until an error occurs.
|
||||
*
|
||||
* @param buffers The data to be written to the stream.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes written. Returns 0 if an error occurred.
|
||||
*
|
||||
* @note The write_some operation may not transmit all of the data to the
|
||||
* peer. Consider using the @ref write function if you need to ensure that all
|
||||
* data is written before the blocking operation completes.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
asio::const_buffer buffer =
|
||||
asio::detail::buffer_sequence_adapter<asio::const_buffer,
|
||||
ConstBufferSequence>::first(buffers);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int result = engine_.write(buffer, space_, ec);
|
||||
result = transport_.sync(result, space_, ec);
|
||||
if (result >= 0)
|
||||
{
|
||||
engine_.map_error_code(ec);
|
||||
return static_cast<std::size_t>(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Start an asynchronous write.
|
||||
/**
|
||||
* This function is used to asynchronously write one or more bytes of data to
|
||||
* the stream. The function call always returns immediately.
|
||||
*
|
||||
* @param buffers The data to be written to the stream. Although the buffers
|
||||
* object may be copied as necessary, ownership of the underlying buffers is
|
||||
* retained by the caller, which must guarantee that they remain valid until
|
||||
* the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the write operation completes.
|
||||
* Copies will be made of the handler as required. The equivalent function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes written.
|
||||
* ); @endcode
|
||||
*
|
||||
* @note The async_write_some operation may not transmit all of the data to
|
||||
* the peer. Consider using the @ref async_write function if you need to
|
||||
* ensure that all data is written before the blocking operation completes.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some(const ConstBufferSequence& buffers,
|
||||
WriteHandler handler)
|
||||
{
|
||||
detail::write_op<Stream, ConstBufferSequence, WriteHandler>(
|
||||
engine_, transport_, space_, buffers, handler)(
|
||||
asio::error_code(), 0, 1);
|
||||
}
|
||||
|
||||
/// Read some data from the stream.
|
||||
/**
|
||||
* This function is used to read data from the stream. The function call will
|
||||
* block until one or more bytes of data has been read successfully, or until
|
||||
* an error occurs.
|
||||
*
|
||||
* @param buffers The buffers into which the data will be read.
|
||||
*
|
||||
* @returns The number of bytes read.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note The read_some operation may not read all of the requested number of
|
||||
* bytes. Consider using the @ref read function if you need to ensure that the
|
||||
* requested amount of data is read before the blocking operation completes.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t n = read_some(buffers, ec);
|
||||
asio::detail::throw_error(ec, "read_some");
|
||||
return n;
|
||||
}
|
||||
|
||||
/// Read some data from the stream.
|
||||
/**
|
||||
* This function is used to read data from the stream. The function call will
|
||||
* block until one or more bytes of data has been read successfully, or until
|
||||
* an error occurs.
|
||||
*
|
||||
* @param buffers The buffers into which the data will be read.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes read. Returns 0 if an error occurred.
|
||||
*
|
||||
* @note The read_some operation may not read all of the requested number of
|
||||
* bytes. Consider using the @ref read function if you need to ensure that the
|
||||
* requested amount of data is read before the blocking operation completes.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
asio::mutable_buffer buffer =
|
||||
asio::detail::buffer_sequence_adapter<asio::mutable_buffer,
|
||||
MutableBufferSequence>::first(buffers);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int result = engine_.read(buffer, space_, ec);
|
||||
result = transport_.sync(result, space_, ec);
|
||||
if (result >= 0)
|
||||
{
|
||||
engine_.map_error_code(ec);
|
||||
return static_cast<std::size_t>(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Start an asynchronous read.
|
||||
/**
|
||||
* This function is used to asynchronously read one or more bytes of data from
|
||||
* the stream. The function call always returns immediately.
|
||||
*
|
||||
* @param buffers The buffers into which the data will be read. Although the
|
||||
* buffers object may be copied as necessary, ownership of the underlying
|
||||
* buffers is retained by the caller, which must guarantee that they remain
|
||||
* valid until the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the read operation completes.
|
||||
* Copies will be made of the handler as required. The equivalent function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes read.
|
||||
* ); @endcode
|
||||
*
|
||||
* @note The async_read_some operation may not read all of the requested
|
||||
* number of bytes. Consider using the @ref async_read function if you need to
|
||||
* ensure that the requested amount of data is read before the asynchronous
|
||||
* operation completes.
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some(const MutableBufferSequence& buffers,
|
||||
ReadHandler handler)
|
||||
{
|
||||
detail::read_op<Stream, MutableBufferSequence, ReadHandler>(
|
||||
engine_, transport_, space_, buffers, handler)(
|
||||
asio::error_code(), 0, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
detail::engine engine_;
|
||||
detail::transport<Stream> transport_;
|
||||
detail::buffer_space space_;
|
||||
};
|
||||
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ssl/stream_base.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
@ -2,8 +2,7 @@
|
||||
// ssl/stream_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -18,15 +17,21 @@
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
||||
#include "asio/ssl/old/stream_service.hpp"
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
# include "asio/ssl/old/stream_service.hpp"
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
using asio::ssl::old::stream_service;
|
||||
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
|
||||
|
@ -106,6 +106,7 @@ void test()
|
||||
|
||||
stream1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
|
||||
|
||||
#if defined(ASIO_ENABLE_OLD_SSL)
|
||||
stream1.peek(buffer(mutable_char_buffer));
|
||||
stream1.peek(buffer(mutable_char_buffer), ec);
|
||||
|
||||
@ -113,6 +114,7 @@ void test()
|
||||
(void)in_avail1;
|
||||
std::size_t in_avail2 = stream1.in_avail(ec);
|
||||
(void)in_avail2;
|
||||
#endif // defined(ASIO_ENABLE_OLD_SSL)
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user