Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r70096 - in trunk: boost/asio/detail boost/asio/ssl boost/asio/ssl/detail boost/asio/ssl/detail/impl boost/asio/ssl/impl boost/asio/ssl/old boost/asio/ssl/old/detail libs/asio/doc libs/asio/doc/requirements libs/asio/example/ssl libs/asio/test libs/asio/test/ssl
From: chris_at_[hidden]
Date: 2011-03-17 20:26:00


Author: chris_kohlhoff
Date: 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
New Revision: 70096
URL: http://svn.boost.org/trac/boost/changeset/70096

Log:
New SSL implementation.

Added:
   trunk/boost/asio/ssl/detail/engine.hpp (contents, props changed)
   trunk/boost/asio/ssl/detail/handshake_op.hpp (contents, props changed)
   trunk/boost/asio/ssl/detail/impl/
   trunk/boost/asio/ssl/detail/impl/engine.ipp (contents, props changed)
   trunk/boost/asio/ssl/detail/impl/openssl_init.ipp (contents, props changed)
   trunk/boost/asio/ssl/detail/io.hpp (contents, props changed)
   trunk/boost/asio/ssl/detail/password_callback.hpp (contents, props changed)
   trunk/boost/asio/ssl/detail/read_op.hpp (contents, props changed)
   trunk/boost/asio/ssl/detail/shutdown_op.hpp (contents, props changed)
   trunk/boost/asio/ssl/detail/stream_core.hpp (contents, props changed)
   trunk/boost/asio/ssl/detail/write_op.hpp (contents, props changed)
   trunk/boost/asio/ssl/impl/context.hpp (contents, props changed)
   trunk/boost/asio/ssl/impl/context.ipp (contents, props changed)
   trunk/boost/asio/ssl/old/
   trunk/boost/asio/ssl/old/basic_context.hpp (contents, props changed)
   trunk/boost/asio/ssl/old/context_service.hpp (contents, props changed)
   trunk/boost/asio/ssl/old/detail/
   trunk/boost/asio/ssl/old/detail/openssl_context_service.hpp (contents, props changed)
   trunk/boost/asio/ssl/old/detail/openssl_operation.hpp (contents, props changed)
   trunk/boost/asio/ssl/old/detail/openssl_stream_service.hpp (contents, props changed)
   trunk/boost/asio/ssl/old/stream.hpp (contents, props changed)
   trunk/boost/asio/ssl/old/stream_service.hpp (contents, props changed)
   trunk/libs/asio/doc/requirements/HandshakeHandler.qbk (contents, props changed)
   trunk/libs/asio/doc/requirements/ShutdownHandler.qbk (contents, props changed)
Removed:
   trunk/boost/asio/ssl/detail/openssl_context_service.hpp
   trunk/boost/asio/ssl/detail/openssl_operation.hpp
   trunk/boost/asio/ssl/detail/openssl_stream_service.hpp
Text files modified:
   trunk/boost/asio/detail/handler_type_requirements.hpp | 44 ++++
   trunk/boost/asio/ssl/basic_context.hpp | 412 ---------------------------------------
   trunk/boost/asio/ssl/context.hpp | 373 +++++++++++++++++++++++++++++++++++
   trunk/boost/asio/ssl/context_base.hpp | 2
   trunk/boost/asio/ssl/context_service.hpp | 152 -------------
   trunk/boost/asio/ssl/detail/openssl_init.hpp | 116 ++--------
   trunk/boost/asio/ssl/detail/openssl_types.hpp | 2
   trunk/boost/asio/ssl/impl/src.hpp | 3
   trunk/boost/asio/ssl/stream.hpp | 255 ++++++++++-------------
   trunk/boost/asio/ssl/stream_base.hpp | 2
   trunk/boost/asio/ssl/stream_service.hpp | 162 --------------
   trunk/libs/asio/doc/quickref.xml | 7
   trunk/libs/asio/doc/reference.xsl | 8
   trunk/libs/asio/example/ssl/client.cpp | 5
   trunk/libs/asio/example/ssl/server.cpp | 5
   trunk/libs/asio/test/buffer.cpp | 13 +
   trunk/libs/asio/test/ssl/stream.cpp | 2
   17 files changed, 613 insertions(+), 950 deletions(-)

Modified: trunk/boost/asio/detail/handler_type_requirements.hpp
==============================================================================
--- trunk/boost/asio/detail/handler_type_requirements.hpp (original)
+++ trunk/boost/asio/detail/handler_type_requirements.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -265,6 +265,42 @@
           boost::asio::detail::lvref<const int>()), \
         char(0))>
 
+#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ static_cast<handler_type*>(0), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "HandshakeHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ handler_type( \
+ static_cast<const handler_type&>(handler))) + \
+ sizeof( \
+ handler( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))>
+
+#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ static_cast<handler_type*>(0), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "ShutdownHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ handler_type( \
+ static_cast<const handler_type&>(handler))) + \
+ sizeof( \
+ handler( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))>
+
 #else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
 
 #define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \
@@ -303,6 +339,14 @@
     handler_type, handler) \
   typedef int
 
+#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int
+
+#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int
+
 #endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
 
 } // namespace detail

Modified: trunk/boost/asio/ssl/basic_context.hpp
==============================================================================
--- trunk/boost/asio/ssl/basic_context.hpp (original)
+++ trunk/boost/asio/ssl/basic_context.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -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)
@@ -17,12 +16,10 @@
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
 #include <boost/asio/detail/config.hpp>
-#include <string>
-#include <boost/noncopyable.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/ssl/context_base.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/old/basic_context.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
 #include <boost/asio/detail/push_options.hpp>
 
@@ -30,400 +27,11 @@
 namespace asio {
 namespace ssl {
 
-/// SSL context.
-template <typename Service>
-class basic_context
- : public context_base,
- private boost::noncopyable
-{
-public:
- /// The type of the service that will be used to provide context operations.
- typedef Service service_type;
-
- /// The native implementation type of the locking dispatcher.
- typedef typename service_type::impl_type impl_type;
-
- /// Constructor.
- basic_context(boost::asio::io_service& io_service, method m)
- : service_(boost::asio::use_service<Service>(io_service)),
- impl_(service_.null())
- {
- service_.create(impl_, m);
- }
-
- /// Destructor.
- ~basic_context()
- {
- service_.destroy(impl_);
- }
-
- /// 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.
- */
- impl_type impl()
- {
- return impl_;
- }
-
- /// 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 boost::system::system_error Thrown on failure.
- */
- void set_options(options o)
- {
- boost::system::error_code ec;
- service_.set_options(impl_, o, ec);
- boost::asio::detail::throw_error(ec);
- }
-
- /// 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.
- */
- boost::system::error_code set_options(options o,
- boost::system::error_code& ec)
- {
- return service_.set_options(impl_, o, 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 boost::system::system_error Thrown on failure.
- */
- void set_verify_mode(verify_mode v)
- {
- boost::system::error_code ec;
- service_.set_verify_mode(impl_, v, ec);
- boost::asio::detail::throw_error(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.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- boost::system::error_code set_verify_mode(verify_mode v,
- boost::system::error_code& ec)
- {
- return service_.set_verify_mode(impl_, v, 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 boost::system::system_error Thrown on failure.
- */
- void load_verify_file(const std::string& filename)
- {
- boost::system::error_code ec;
- service_.load_verify_file(impl_, filename, ec);
- boost::asio::detail::throw_error(ec);
- }
-
- /// 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.
- */
- boost::system::error_code load_verify_file(const std::string& filename,
- boost::system::error_code& ec)
- {
- return service_.load_verify_file(impl_, filename, 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 boost::system::system_error Thrown on failure.
- */
- void add_verify_path(const std::string& path)
- {
- boost::system::error_code ec;
- service_.add_verify_path(impl_, path, ec);
- boost::asio::detail::throw_error(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.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- boost::system::error_code add_verify_path(const std::string& path,
- boost::system::error_code& ec)
- {
- return service_.add_verify_path(impl_, path, 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 boost::system::system_error Thrown on failure.
- */
- void use_certificate_file(const std::string& filename, file_format format)
- {
- boost::system::error_code ec;
- service_.use_certificate_file(impl_, filename, format, ec);
- boost::asio::detail::throw_error(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).
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- boost::system::error_code use_certificate_file(const std::string& filename,
- file_format format, boost::system::error_code& ec)
- {
- return service_.use_certificate_file(impl_, filename, format, 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 boost::system::system_error Thrown on failure.
- */
- void use_certificate_chain_file(const std::string& filename)
- {
- boost::system::error_code ec;
- service_.use_certificate_chain_file(impl_, filename, ec);
- boost::asio::detail::throw_error(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.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- boost::system::error_code use_certificate_chain_file(
- const std::string& filename, boost::system::error_code& ec)
- {
- return service_.use_certificate_chain_file(impl_, filename, 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 boost::system::system_error Thrown on failure.
- */
- void use_private_key_file(const std::string& filename, file_format format)
- {
- boost::system::error_code ec;
- service_.use_private_key_file(impl_, filename, format, ec);
- boost::asio::detail::throw_error(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).
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- boost::system::error_code use_private_key_file(const std::string& filename,
- file_format format, boost::system::error_code& ec)
- {
- return service_.use_private_key_file(impl_, filename, format, 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 boost::system::system_error Thrown on failure.
- */
- void use_rsa_private_key_file(const std::string& filename, file_format format)
- {
- boost::system::error_code ec;
- service_.use_rsa_private_key_file(impl_, filename, format, ec);
- boost::asio::detail::throw_error(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).
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- boost::system::error_code use_rsa_private_key_file(
- const std::string& filename, file_format format,
- boost::system::error_code& ec)
- {
- return service_.use_rsa_private_key_file(impl_, filename, format, 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 boost::system::system_error Thrown on failure.
- */
- void use_tmp_dh_file(const std::string& filename)
- {
- boost::system::error_code ec;
- service_.use_tmp_dh_file(impl_, filename, ec);
- boost::asio::detail::throw_error(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.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- boost::system::error_code use_tmp_dh_file(const std::string& filename,
- boost::system::error_code& ec)
- {
- return service_.use_tmp_dh_file(impl_, filename, 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 boost::system::system_error Thrown on failure.
- */
- template <typename PasswordCallback>
- void set_password_callback(PasswordCallback callback)
- {
- boost::system::error_code ec;
- service_.set_password_callback(impl_, callback, ec);
- boost::asio::detail::throw_error(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.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- template <typename PasswordCallback>
- boost::system::error_code set_password_callback(PasswordCallback callback,
- boost::system::error_code& ec)
- {
- return service_.set_password_callback(impl_, callback, ec);
- }
-
-private:
- /// The backend service implementation.
- service_type& service_;
-
- /// The underlying native implementation.
- impl_type impl_;
-};
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+using boost::asio::ssl::old::basic_context;
+
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
 } // namespace ssl
 } // namespace asio

Modified: trunk/boost/asio/ssl/context.hpp
==============================================================================
--- trunk/boost/asio/ssl/context.hpp (original)
+++ trunk/boost/asio/ssl/context.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -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,18 +16,384 @@
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
 #include <boost/asio/detail/config.hpp>
-#include <boost/asio/ssl/basic_context.hpp>
-#include <boost/asio/ssl/context_service.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/basic_context.hpp>
+# include <boost/asio/ssl/context_service.hpp>
+#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <string>
+# include <boost/asio/io_service.hpp>
+# include <boost/asio/ssl/context_base.hpp>
+# include <boost/asio/ssl/detail/openssl_types.hpp>
+# include <boost/asio/ssl/detail/openssl_init.hpp>
+# include <boost/asio/ssl/detail/password_callback.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
 namespace boost {
 namespace asio {
 namespace ssl {
 
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
 /// Typedef for the typical usage of context.
 typedef basic_context<context_service> context;
 
+#else // defined(BOOST_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.
+ BOOST_ASIO_DECL explicit context(method m);
+
+ /// Deprecated constructor taking a reference to an io_service object.
+ BOOST_ASIO_DECL context(boost::asio::io_service&, method m);
+
+#if defined(BOOST_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.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL context& operator=(context&& other);
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Destructor.
+ BOOST_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.
+ */
+ BOOST_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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code set_options(options o,
+ boost::system::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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code set_verify_mode(
+ verify_mode v, boost::system::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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code load_verify_file(
+ const std::string& filename, boost::system::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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code add_verify_path(
+ const std::string& path, boost::system::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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code use_certificate_file(
+ const std::string& filename, file_format format,
+ boost::system::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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code use_certificate_chain_file(
+ const std::string& filename, boost::system::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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code use_private_key_file(
+ const std::string& filename, file_format format,
+ boost::system::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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code use_rsa_private_key_file(
+ const std::string& filename, file_format format,
+ boost::system::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 boost::system::system_error Thrown on failure.
+ */
+ BOOST_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.
+ */
+ BOOST_ASIO_DECL boost::system::error_code use_tmp_dh_file(
+ const std::string& filename, boost::system::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 boost::system::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>
+ boost::system::error_code set_password_callback(PasswordCallback callback,
+ boost::system::error_code& ec);
+
+private:
+ // Helper function used to set a password callback.
+ BOOST_ASIO_DECL boost::system::error_code do_set_password_callback(
+ detail::password_callback_base* callback, boost::system::error_code& ec);
+
+ // Callback used when the SSL implementation wants a password.
+ BOOST_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.
+ boost::asio::ssl::detail::openssl_init<> init_;
+};
+
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
 } // namespace ssl
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/ssl/impl/context.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/ssl/impl/context.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_SSL_CONTEXT_HPP

Modified: trunk/boost/asio/ssl/context_base.hpp
==============================================================================
--- trunk/boost/asio/ssl/context_base.hpp (original)
+++ trunk/boost/asio/ssl/context_base.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -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)

Modified: trunk/boost/asio/ssl/context_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/context_service.hpp (original)
+++ trunk/boost/asio/ssl/context_service.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -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)
@@ -17,12 +16,10 @@
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
 #include <boost/asio/detail/config.hpp>
-#include <string>
-#include <boost/noncopyable.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/ssl/context_base.hpp>
-#include <boost/asio/ssl/detail/openssl_context_service.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/old/context_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
 #include <boost/asio/detail/push_options.hpp>
 
@@ -30,140 +27,11 @@
 namespace asio {
 namespace ssl {
 
-/// Default service implementation for a context.
-class context_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_service::service
-#else
- : public boost::asio::detail::service_base<context_service>
-#endif
-{
-private:
- // The type of the platform-specific implementation.
- typedef detail::openssl_context_service service_impl_type;
-
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_service::id id;
-#endif
-
- /// The type of the context.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined impl_type;
-#else
- typedef service_impl_type::impl_type impl_type;
-#endif
-
- /// Constructor.
- explicit context_service(boost::asio::io_service& io_service)
- : boost::asio::detail::service_base<context_service>(io_service),
- service_impl_(boost::asio::use_service<service_impl_type>(io_service))
- {
- }
-
- /// Return a null context implementation.
- impl_type null() const
- {
- return service_impl_.null();
- }
-
- /// Create a new context implementation.
- void create(impl_type& impl, context_base::method m)
- {
- service_impl_.create(impl, m);
- }
-
- /// Destroy a context implementation.
- void destroy(impl_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Set options on the context.
- boost::system::error_code set_options(impl_type& impl,
- context_base::options o, boost::system::error_code& ec)
- {
- return service_impl_.set_options(impl, o, ec);
- }
-
- /// Set peer verification mode.
- boost::system::error_code set_verify_mode(impl_type& impl,
- context_base::verify_mode v, boost::system::error_code& ec)
- {
- return service_impl_.set_verify_mode(impl, v, ec);
- }
-
- /// Load a certification authority file for performing verification.
- boost::system::error_code load_verify_file(impl_type& impl,
- const std::string& filename, boost::system::error_code& ec)
- {
- return service_impl_.load_verify_file(impl, filename, ec);
- }
-
- /// Add a directory containing certification authority files to be used for
- /// performing verification.
- boost::system::error_code add_verify_path(impl_type& impl,
- const std::string& path, boost::system::error_code& ec)
- {
- return service_impl_.add_verify_path(impl, path, ec);
- }
-
- /// Use a certificate from a file.
- boost::system::error_code use_certificate_file(impl_type& impl,
- const std::string& filename, context_base::file_format format,
- boost::system::error_code& ec)
- {
- return service_impl_.use_certificate_file(impl, filename, format, ec);
- }
-
- /// Use a certificate chain from a file.
- boost::system::error_code use_certificate_chain_file(impl_type& impl,
- const std::string& filename, boost::system::error_code& ec)
- {
- return service_impl_.use_certificate_chain_file(impl, filename, ec);
- }
-
- /// Use a private key from a file.
- boost::system::error_code use_private_key_file(impl_type& impl,
- const std::string& filename, context_base::file_format format,
- boost::system::error_code& ec)
- {
- return service_impl_.use_private_key_file(impl, filename, format, ec);
- }
-
- /// Use an RSA private key from a file.
- boost::system::error_code use_rsa_private_key_file(impl_type& impl,
- const std::string& filename, context_base::file_format format,
- boost::system::error_code& ec)
- {
- return service_impl_.use_rsa_private_key_file(impl, filename, format, ec);
- }
-
- /// Use the specified file to obtain the temporary Diffie-Hellman parameters.
- boost::system::error_code use_tmp_dh_file(impl_type& impl,
- const std::string& filename, boost::system::error_code& ec)
- {
- return service_impl_.use_tmp_dh_file(impl, filename, ec);
- }
-
- /// Set the password callback.
- template <typename PasswordCallback>
- boost::system::error_code set_password_callback(impl_type& impl,
- PasswordCallback callback, boost::system::error_code& ec)
- {
- return service_impl_.set_password_callback(impl, callback, ec);
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- }
-
- // The service that provides the platform-specific implementation.
- service_impl_type& service_impl_;
-};
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+using boost::asio::ssl::old::context_service;
+
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
 } // namespace ssl
 } // namespace asio

Added: trunk/boost/asio/ssl/detail/engine.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/engine.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,148 @@
+//
+// 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 BOOST_ASIO_SSL_DETAIL_ENGINE_HPP
+#define BOOST_ASIO_SSL_DETAIL_ENGINE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/buffer.hpp>
+# include <boost/asio/detail/static_mutex.hpp>
+# include <boost/asio/ssl/detail/openssl_types.hpp>
+# include <boost/asio/ssl/stream_base.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+class engine
+{
+public:
+ enum want
+ {
+ // Returned by functions to indicate that the engine wants input. The input
+ // buffer should be updated to point to the data. The engine then needs to
+ // be called again to retry the operation.
+ want_input_and_retry = -2,
+
+ // Returned by functions to indicate that the engine wants to write output.
+ // The output buffer points to the data to be written. The engine then
+ // needs to be called again to retry the operation.
+ want_output_and_retry = -1,
+
+ // Returned by functions to indicate that the engine doesn't need input or
+ // output.
+ want_nothing = 0,
+
+ // Returned by functions to indicate that the engine wants to write output.
+ // The output buffer points to the data to be written. After that the
+ // operation is complete, and the engine does not need to be called again.
+ want_output = 1
+ };
+
+ // Construct a new engine for the specified context.
+ BOOST_ASIO_DECL explicit engine(SSL_CTX* context);
+
+ // Destructor.
+ BOOST_ASIO_DECL ~engine();
+
+ // Get the underlying implementation in the native type.
+ BOOST_ASIO_DECL SSL* native_handle();
+
+ // Perform an SSL handshake using either SSL_connect (client-side) or
+ // SSL_accept (server-side).
+ BOOST_ASIO_DECL want handshake(
+ stream_base::handshake_type type, boost::system::error_code& ec);
+
+ // Perform a graceful shutdown of the SSL session.
+ BOOST_ASIO_DECL want shutdown(boost::system::error_code& ec);
+
+ // Write bytes to the SSL session.
+ BOOST_ASIO_DECL want write(const boost::asio::const_buffer& data,
+ boost::system::error_code& ec, std::size_t& bytes_transferred);
+
+ // Read bytes from the SSL session.
+ BOOST_ASIO_DECL want read(const boost::asio::mutable_buffer& data,
+ boost::system::error_code& ec, std::size_t& bytes_transferred);
+
+ // Get output data to be written to the transport.
+ BOOST_ASIO_DECL boost::asio::mutable_buffers_1 get_output(
+ const boost::asio::mutable_buffer& data);
+
+ // Put input data that was read from the transport.
+ BOOST_ASIO_DECL boost::asio::const_buffer put_input(
+ const boost::asio::const_buffer& data);
+
+ // 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.
+ BOOST_ASIO_DECL const boost::system::error_code& map_error_code(
+ boost::system::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.
+ BOOST_ASIO_DECL static boost::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.
+ BOOST_ASIO_DECL want perform(int (engine::* op)(void*, std::size_t),
+ void* data, std::size_t length, boost::system::error_code& ec,
+ std::size_t* bytes_transferred);
+
+ // Adapt the SSL_accept function to the signature needed for perform().
+ BOOST_ASIO_DECL int do_accept(void*, std::size_t);
+
+ // Adapt the SSL_connect function to the signature needed for perform().
+ BOOST_ASIO_DECL int do_connect(void*, std::size_t);
+
+ // Adapt the SSL_shutdown function to the signature needed for perform().
+ BOOST_ASIO_DECL int do_shutdown(void*, std::size_t);
+
+ // Adapt the SSL_read function to the signature needed for perform().
+ BOOST_ASIO_DECL int do_read(void* data, std::size_t length);
+
+ // Adapt the SSL_write function to the signature needed for perform().
+ BOOST_ASIO_DECL int do_write(void* data, std::size_t length);
+
+ SSL* ssl_;
+ BIO* ext_bio_;
+};
+
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/ssl/detail/impl/engine.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // BOOST_ASIO_SSL_DETAIL_ENGINE_HPP

Added: trunk/boost/asio/ssl/detail/handshake_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/handshake_op.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,70 @@
+//
+// 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 BOOST_ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP
+#define BOOST_ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/detail/engine.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+class handshake_op
+{
+public:
+ handshake_op(stream_base::handshake_type type)
+ : type_(type)
+ {
+ }
+
+ engine::want operator()(engine& eng,
+ boost::system::error_code& ec,
+ std::size_t& bytes_transferred) const
+ {
+ bytes_transferred = 0;
+ return eng.handshake(type_, ec);
+ }
+
+ template <typename Handler>
+ void call_handler(Handler& handler,
+ const boost::system::error_code& ec,
+ const std::size_t&) const
+ {
+ handler(ec);
+ }
+
+private:
+ stream_base::handshake_type type_;
+};
+
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP

Added: trunk/boost/asio/ssl/detail/impl/engine.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/impl/engine.ipp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,232 @@
+//
+// 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 BOOST_ASIO_SSL_DETAIL_IMPL_ENGINE_IPP
+#define BOOST_ASIO_SSL_DETAIL_IMPL_ENGINE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/detail/engine.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_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_;
+}
+
+engine::want engine::handshake(
+ stream_base::handshake_type type, boost::system::error_code& ec)
+{
+ return perform((type == boost::asio::ssl::stream_base::client)
+ ? &engine::do_connect : &engine::do_accept, 0, 0, ec, 0);
+}
+
+engine::want engine::shutdown(boost::system::error_code& ec)
+{
+ return perform(&engine::do_shutdown, 0, 0, ec, 0);
+}
+
+engine::want engine::write(const boost::asio::const_buffer& data,
+ boost::system::error_code& ec, std::size_t& bytes_transferred)
+{
+ return perform(&engine::do_write,
+ const_cast<void*>(boost::asio::buffer_cast<const void*>(data)),
+ boost::asio::buffer_size(data), ec, &bytes_transferred);
+}
+
+engine::want engine::read(const boost::asio::mutable_buffer& data,
+ boost::system::error_code& ec, std::size_t& bytes_transferred)
+{
+ return perform(&engine::do_read,
+ boost::asio::buffer_cast<void*>(data),
+ boost::asio::buffer_size(data), ec, &bytes_transferred);
+}
+
+boost::asio::mutable_buffers_1 engine::get_output(
+ const boost::asio::mutable_buffer& data)
+{
+ int length = ::BIO_read(ext_bio_,
+ boost::asio::buffer_cast<void*>(data),
+ boost::asio::buffer_size(data));
+
+ return boost::asio::buffer(data,
+ length > 0 ? static_cast<std::size_t>(length) : 0);
+}
+
+boost::asio::const_buffer engine::put_input(
+ const boost::asio::const_buffer& data)
+{
+ int length = ::BIO_write(ext_bio_,
+ boost::asio::buffer_cast<const void*>(data),
+ boost::asio::buffer_size(data));
+
+ return boost::asio::buffer(data +
+ (length > 0 ? static_cast<std::size_t>(length) : 0));
+}
+
+const boost::system::error_code& engine::map_error_code(
+ boost::system::error_code& ec) const
+{
+ // We only want to map the error::eof code.
+ if (ec != boost::asio::error::eof)
+ return ec;
+
+ // If there's data yet to be read, it's an error.
+ if (BIO_wpending(ext_bio_))
+ {
+ ec = boost::system::error_code(
+ ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ),
+ boost::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 = boost::system::error_code(
+ ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ),
+ boost::asio::error::get_ssl_category());
+ return ec;
+}
+
+boost::asio::detail::static_mutex& engine::accept_mutex()
+{
+ static boost::asio::detail::static_mutex mutex = BOOST_ASIO_STATIC_MUTEX_INIT;
+ return mutex;
+}
+
+engine::want engine::perform(int (engine::* op)(void*, std::size_t),
+ void* data, std::size_t length, boost::system::error_code& ec,
+ std::size_t* bytes_transferred)
+{
+ 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 = boost::system::error_code(sys_error,
+ boost::asio::error::get_ssl_category());
+ return want_nothing;
+ }
+
+ if (ssl_error == SSL_ERROR_SYSCALL)
+ {
+ ec = boost::system::error_code(sys_error,
+ boost::asio::error::get_system_category());
+ return want_nothing;
+ }
+
+ if (result > 0 && bytes_transferred)
+ *bytes_transferred = static_cast<std::size_t>(result);
+
+ if (ssl_error == SSL_ERROR_WANT_WRITE)
+ {
+ ec = boost::system::error_code();
+ return want_output_and_retry;
+ }
+ else if (pending_output_after > pending_output_before)
+ {
+ ec = boost::system::error_code();
+ return result > 0 ? want_output : want_output_and_retry;
+ }
+ else if (ssl_error == SSL_ERROR_WANT_READ)
+ {
+ ec = boost::system::error_code();
+ return want_input_and_retry;
+ }
+ else if (::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN)
+ {
+ ec = boost::asio::error::eof;
+ return want_nothing;
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ return want_nothing;
+ }
+}
+
+int engine::do_accept(void*, std::size_t)
+{
+ boost::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(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_IMPL_ENGINE_IPP

Added: trunk/boost/asio/ssl/detail/impl/openssl_init.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/impl/openssl_init.ipp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,109 @@
+//
+// ssl/detail/impl/openssl_init.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 BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP
+#define BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <vector>
+#include <boost/assert.hpp>
+#include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/tss_ptr.hpp>
+#include <boost/asio/ssl/detail/openssl_init.hpp>
+#include <boost/asio/ssl/detail/openssl_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+class openssl_init_base::do_init
+{
+public:
+ do_init()
+ {
+ ::SSL_library_init();
+ ::SSL_load_error_strings();
+ ::OpenSSL_add_ssl_algorithms();
+
+ mutexes_.resize(::CRYPTO_num_locks());
+ for (size_t i = 0; i < mutexes_.size(); ++i)
+ mutexes_[i].reset(new boost::asio::detail::mutex);
+ ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func);
+ ::CRYPTO_set_id_callback(&do_init::openssl_id_func);
+ }
+
+ ~do_init()
+ {
+ ::CRYPTO_set_id_callback(0);
+ ::CRYPTO_set_locking_callback(0);
+ ::ERR_free_strings();
+ ::ERR_remove_state(0);
+ ::EVP_cleanup();
+ ::CRYPTO_cleanup_all_ex_data();
+ ::CONF_modules_unload(1);
+ ::ENGINE_cleanup();
+ }
+
+private:
+ static unsigned long openssl_id_func()
+ {
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ return ::GetCurrentThreadId();
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ void* id = instance()->thread_id_;
+ if (id == 0)
+ instance()->thread_id_ = id = &id; // Ugh.
+ BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*));
+ return reinterpret_cast<unsigned long>(id);
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ }
+
+ static void openssl_locking_func(int mode, int n,
+ const char* /*file*/, int /*line*/)
+ {
+ if (mode & CRYPTO_LOCK)
+ instance()->mutexes_[n]->lock();
+ else
+ instance()->mutexes_[n]->unlock();
+ }
+
+ // Mutexes to be used in locking callbacks.
+ std::vector<boost::asio::detail::shared_ptr<
+ boost::asio::detail::mutex> > mutexes_;
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+ // The thread identifiers to be used by openssl.
+ boost::asio::detail::tss_ptr<void> thread_id_;
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+};
+
+boost::asio::detail::shared_ptr<openssl_init_base::do_init>
+openssl_init_base::instance()
+{
+ static boost::asio::detail::shared_ptr<do_init> init(new do_init);
+ return init;
+}
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP

Added: trunk/boost/asio/ssl/detail/io.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/io.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,300 @@
+//
+// ssl/detail/io.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 BOOST_ASIO_SSL_DETAIL_IO_HPP
+#define BOOST_ASIO_SSL_DETAIL_IO_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/detail/engine.hpp>
+# include <boost/asio/ssl/detail/stream_core.hpp>
+# include <boost/asio/write.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+template <typename Stream, typename Operation>
+std::size_t io(Stream& next_layer, stream_core& core,
+ const Operation& op, boost::system::error_code& ec)
+{
+ std::size_t bytes_transferred = 0;
+ do switch (op(core.engine_, ec, bytes_transferred))
+ {
+ case engine::want_input_and_retry:
+
+ // If the input buffer is empty then we need to read some more data from
+ // the underlying transport.
+ if (boost::asio::buffer_size(core.input_) == 0)
+ core.input_ = boost::asio::buffer(core.input_buffer_,
+ next_layer.read_some(core.input_buffer_, ec));
+
+ // Pass the new input data to the engine.
+ core.input_ = core.engine_.put_input(core.input_);
+
+ // Try the operation again.
+ continue;
+
+ case engine::want_output_and_retry:
+
+ // Get output data from the engine and write it to the underlying
+ // transport.
+ boost::asio::write(next_layer,
+ core.engine_.get_output(core.output_buffer_), ec);
+
+ // Try the operation again.
+ continue;
+
+ case engine::want_output:
+
+ // Get output data from the engine and write it to the underlying
+ // transport.
+ boost::asio::write(next_layer,
+ core.engine_.get_output(core.output_buffer_), ec);
+
+ // Operation is complete. Return result to caller.
+ core.engine_.map_error_code(ec);
+ return bytes_transferred;
+
+ default:
+
+ // Operation is complete. Return result to caller.
+ core.engine_.map_error_code(ec);
+ return bytes_transferred;
+
+ } while (!ec);
+
+ // Operation failed. Return result to caller.
+ core.engine_.map_error_code(ec);
+ return 0;
+}
+
+template <typename Stream, typename Operation, typename Handler>
+class io_op
+{
+public:
+ io_op(Stream& next_layer, stream_core& core,
+ const Operation& op, Handler& handler)
+ : next_layer_(next_layer),
+ core_(core),
+ op_(op),
+ bytes_transferred_(0),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ {
+ }
+
+ void operator()(boost::system::error_code ec,
+ std::size_t bytes_transferred = ~std::size_t(0), int start = 0)
+ {
+ switch (start)
+ {
+ case 1: // Called after at least one async operation.
+ do
+ {
+ switch (want_ = op_(core_.engine_, ec_, bytes_transferred_))
+ {
+ case engine::want_input_and_retry:
+
+ // If the input buffer already has data in it we can pass it to the
+ // engine and then retry the operation immediately.
+ if (boost::asio::buffer_size(core_.input_) != 0)
+ {
+ core_.input_ = core_.engine_.put_input(core_.input_);
+ continue;
+ }
+
+ // 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 set to
+ // pos_infin if a read is in progress, and neg_infin otherwise.
+ if (core_.pending_read_.expires_at() == boost::posix_time::neg_infin)
+ {
+ // Prevent other read operations from being started.
+ core_.pending_read_.expires_at(boost::posix_time::pos_infin);
+
+ // Start reading some data from the underlying transport.
+ next_layer_.async_read_some(
+ boost::asio::buffer(core_.input_buffer_), *this);
+ }
+ else
+ {
+ // Wait until the current read operation completes.
+ core_.pending_read_.async_wait(*this);
+ }
+
+ // Yield control until asynchronous operation completes. Control
+ // resumes at the "default:" label below.
+ return;
+
+ case engine::want_output_and_retry:
+ case engine::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 set to
+ // pos_infin if a write is in progress, and neg_infin otherwise.
+ if (core_.pending_write_.expires_at() == boost::posix_time::neg_infin)
+ {
+ // Prevent other write operations from being started.
+ core_.pending_write_.expires_at(boost::posix_time::pos_infin);
+
+ // Start writing all the data to the underlying transport.
+ boost::asio::async_write(next_layer_,
+ core_.engine_.get_output(core_.output_buffer_), *this);
+ }
+ else
+ {
+ // Wait until the current write operation completes.
+ core_.pending_write_.async_wait(*this);
+ }
+
+ // Yield control until asynchronous operation completes. Control
+ // resumes at the "default:" label below.
+ return;
+
+ default:
+
+ // The SSL operation is done and 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 the handler runs "as-if" posted using io_service::post().
+ if (start)
+ {
+ next_layer_.async_read_some(
+ boost::asio::buffer(core_.input_buffer_, 0), *this);
+
+ // Yield control until asynchronous operation completes. Control
+ // resumes at the "default:" label below.
+ return;
+ }
+ else
+ {
+ // Continue on to run handler directly.
+ break;
+ }
+ }
+
+ default:
+ if (bytes_transferred != ~std::size_t(0) && !ec_)
+ ec_ = ec;
+
+ switch (want_)
+ {
+ case engine::want_input_and_retry:
+
+ // Add received data to the engine's input.
+ core_.input_ = boost::asio::buffer(
+ core_.input_buffer_, bytes_transferred);
+ core_.input_ = core_.engine_.put_input(core_.input_);
+
+ // Release any waiting read operations.
+ core_.pending_read_.expires_at(boost::posix_time::neg_infin);
+
+ // Try the operation again.
+ continue;
+
+ case engine::want_output_and_retry:
+
+ // Release any waiting write operations.
+ core_.pending_write_.expires_at(boost::posix_time::neg_infin);
+
+ // Try the operation again.
+ continue;
+
+ case engine::want_output:
+
+ // Release any waiting write operations.
+ core_.pending_write_.expires_at(boost::posix_time::neg_infin);
+
+ // Fall through to call handler.
+
+ default:
+
+ // Pass the result to the handler.
+ op_.call_handler(handler_,
+ core_.engine_.map_error_code(ec_),
+ ec_ ? 0 : bytes_transferred_);
+
+ // Our work here is done.
+ return;
+ }
+ } while (!ec_);
+
+ // Operation failed. Pass the result to the handler.
+ op_.call_handler(handler_, core_.engine_.map_error_code(ec_), 0);
+ }
+ }
+
+//private:
+ Stream& next_layer_;
+ stream_core& core_;
+ Operation op_;
+ engine::want want_;
+ boost::system::error_code ec_;
+ std::size_t bytes_transferred_;
+ Handler handler_;
+};
+
+template <typename Stream, typename Operation, typename Handler>
+inline void* asio_handler_allocate(std::size_t size,
+ io_op<Stream, Operation, Handler>* this_handler)
+{
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+}
+
+template <typename Stream, typename Operation, typename Handler>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ io_op<Stream, Operation, Handler>* this_handler)
+{
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+}
+
+template <typename Function, typename Stream,
+ typename Operation, typename Handler>
+inline void asio_handler_invoke(const Function& function,
+ io_op<Stream, Operation, Handler>* this_handler)
+{
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+}
+
+template <typename Stream, typename Operation, typename Handler>
+inline void async_io(Stream& next_layer, stream_core& core,
+ const Operation& op, Handler& handler)
+{
+ io_op<Stream, Operation, Handler>(
+ next_layer, core, op, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_IO_HPP

Deleted: trunk/boost/asio/ssl/detail/openssl_context_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_context_service.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
+++ (empty file)
@@ -1,377 +0,0 @@
-//
-// ssl/detail/openssl_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)
-//
-// 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 BOOST_ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP
-#define BOOST_ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/config.hpp>
-#include <cstring>
-#include <string>
-#include <boost/function.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/ssl/context_base.hpp>
-#include <boost/asio/ssl/detail/openssl_init.hpp>
-#include <boost/asio/ssl/detail/openssl_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace ssl {
-namespace detail {
-
-class openssl_context_service
- : public boost::asio::detail::service_base<openssl_context_service>
-{
-public:
- // The native type of the context.
- typedef ::SSL_CTX* impl_type;
-
- // The type for the password callback function object.
- typedef boost::function<std::string(std::size_t,
- context_base::password_purpose)> password_callback_type;
-
- // Constructor.
- openssl_context_service(boost::asio::io_service& io_service)
- : boost::asio::detail::service_base<openssl_context_service>(io_service)
- {
- }
-
- // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- }
-
- // Return a null context implementation.
- static impl_type null()
- {
- return 0;
- }
-
- // Create a new context implementation.
- void create(impl_type& impl, context_base::method m)
- {
- switch (m)
- {
- case context_base::sslv2:
- impl = ::SSL_CTX_new(::SSLv2_method());
- break;
- case context_base::sslv2_client:
- impl = ::SSL_CTX_new(::SSLv2_client_method());
- break;
- case context_base::sslv2_server:
- impl = ::SSL_CTX_new(::SSLv2_server_method());
- break;
- case context_base::sslv3:
- impl = ::SSL_CTX_new(::SSLv3_method());
- break;
- case context_base::sslv3_client:
- impl = ::SSL_CTX_new(::SSLv3_client_method());
- break;
- case context_base::sslv3_server:
- impl = ::SSL_CTX_new(::SSLv3_server_method());
- break;
- case context_base::tlsv1:
- impl = ::SSL_CTX_new(::TLSv1_method());
- break;
- case context_base::tlsv1_client:
- impl = ::SSL_CTX_new(::TLSv1_client_method());
- break;
- case context_base::tlsv1_server:
- impl = ::SSL_CTX_new(::TLSv1_server_method());
- break;
- case context_base::sslv23:
- impl = ::SSL_CTX_new(::SSLv23_method());
- break;
- case context_base::sslv23_client:
- impl = ::SSL_CTX_new(::SSLv23_client_method());
- break;
- case context_base::sslv23_server:
- impl = ::SSL_CTX_new(::SSLv23_server_method());
- break;
- default:
- impl = ::SSL_CTX_new(0);
- break;
- }
- }
-
- // Destroy a context implementation.
- void destroy(impl_type& impl)
- {
- if (impl != null())
- {
- if (impl->default_passwd_callback_userdata)
- {
- password_callback_type* callback =
- static_cast<password_callback_type*>(
- impl->default_passwd_callback_userdata);
- delete callback;
- impl->default_passwd_callback_userdata = 0;
- }
-
- ::SSL_CTX_free(impl);
- impl = null();
- }
- }
-
- // Set options on the context.
- boost::system::error_code set_options(impl_type& impl,
- context_base::options o, boost::system::error_code& ec)
- {
- ::SSL_CTX_set_options(impl, o);
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Set peer verification mode.
- boost::system::error_code set_verify_mode(impl_type& impl,
- context_base::verify_mode v, boost::system::error_code& ec)
- {
- ::SSL_CTX_set_verify(impl, v, 0);
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Load a certification authority file for performing verification.
- boost::system::error_code load_verify_file(impl_type& impl,
- const std::string& filename, boost::system::error_code& ec)
- {
- if (::SSL_CTX_load_verify_locations(impl, filename.c_str(), 0) != 1)
- {
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Add a directory containing certification authority files to be used for
- // performing verification.
- boost::system::error_code add_verify_path(impl_type& impl,
- const std::string& path, boost::system::error_code& ec)
- {
- if (::SSL_CTX_load_verify_locations(impl, 0, path.c_str()) != 1)
- {
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Use a certificate from a file.
- boost::system::error_code use_certificate_file(impl_type& impl,
- const std::string& filename, context_base::file_format format,
- boost::system::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 = boost::asio::error::invalid_argument;
- return ec;
- }
- }
-
- if (::SSL_CTX_use_certificate_file(impl, filename.c_str(), file_type) != 1)
- {
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Use a certificate chain from a file.
- boost::system::error_code use_certificate_chain_file(impl_type& impl,
- const std::string& filename, boost::system::error_code& ec)
- {
- if (::SSL_CTX_use_certificate_chain_file(impl, filename.c_str()) != 1)
- {
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Use a private key from a file.
- boost::system::error_code use_private_key_file(impl_type& impl,
- const std::string& filename, context_base::file_format format,
- boost::system::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 = boost::asio::error::invalid_argument;
- return ec;
- }
- }
-
- if (::SSL_CTX_use_PrivateKey_file(impl, filename.c_str(), file_type) != 1)
- {
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Use an RSA private key from a file.
- boost::system::error_code use_rsa_private_key_file(impl_type& impl,
- const std::string& filename, context_base::file_format format,
- boost::system::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 = boost::asio::error::invalid_argument;
- return ec;
- }
- }
-
- if (::SSL_CTX_use_RSAPrivateKey_file(
- impl, filename.c_str(), file_type) != 1)
- {
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Use the specified file to obtain the temporary Diffie-Hellman parameters.
- boost::system::error_code use_tmp_dh_file(impl_type& impl,
- const std::string& filename, boost::system::error_code& ec)
- {
- ::BIO* bio = ::BIO_new_file(filename.c_str(), "r");
- if (!bio)
- {
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0);
- if (!dh)
- {
- ::BIO_free(bio);
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ::BIO_free(bio);
- int result = ::SSL_CTX_set_tmp_dh(impl, dh);
- ::DH_free(dh);
- if (result != 1)
- {
- ec = boost::asio::error::invalid_argument;
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- static int password_callback(char* buf, int size, int purpose, void* data)
- {
- using namespace std; // For strncat and strlen.
-
- if (data)
- {
- password_callback_type* callback =
- static_cast<password_callback_type*>(data);
- std::string passwd = (*callback)(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;
- }
-
- // Set the password callback.
- template <typename Password_Callback>
- boost::system::error_code set_password_callback(impl_type& impl,
- Password_Callback callback, boost::system::error_code& ec)
- {
- // Allocate callback function object if not already present.
- if (impl->default_passwd_callback_userdata)
- {
- password_callback_type* callback_function =
- static_cast<password_callback_type*>(
- impl->default_passwd_callback_userdata);
- *callback_function = callback;
- }
- else
- {
- password_callback_type* callback_function =
- new password_callback_type(callback);
- impl->default_passwd_callback_userdata = callback_function;
- }
-
- // Set the password callback.
- SSL_CTX_set_default_passwd_cb(impl,
- &openssl_context_service::password_callback);
-
- ec = boost::system::error_code();
- return ec;
- }
-
-private:
- // Ensure openssl is initialised.
- openssl_init<> init_;
-};
-
-} // namespace detail
-} // namespace ssl
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP

Modified: trunk/boost/asio/ssl/detail/openssl_init.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_init.hpp (original)
+++ trunk/boost/asio/ssl/detail/openssl_init.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -2,8 +2,7 @@
 // ssl/detail/openssl_init.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,12 +17,8 @@
 
 #include <boost/asio/detail/config.hpp>
 #include <cstring>
-#include <vector>
-#include <boost/assert.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/asio/detail/mutex.hpp>
-#include <boost/asio/detail/tss_ptr.hpp>
-#include <boost/asio/ssl/detail/openssl_types.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/shared_ptr.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
 
@@ -32,93 +27,28 @@
 namespace ssl {
 namespace detail {
 
-template <bool Do_Init = true>
-class openssl_init
- : private boost::noncopyable
+class openssl_init_base
+ : private noncopyable
 {
-private:
- // Structure to perform the actual initialisation.
- class do_init
- {
- public:
- do_init()
- {
- if (Do_Init)
- {
- ::SSL_library_init();
- ::SSL_load_error_strings();
- ::OpenSSL_add_ssl_algorithms();
-
- mutexes_.resize(::CRYPTO_num_locks());
- for (size_t i = 0; i < mutexes_.size(); ++i)
- mutexes_[i].reset(new boost::asio::detail::mutex);
- ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func);
- ::CRYPTO_set_id_callback(&do_init::openssl_id_func);
- }
- }
-
- ~do_init()
- {
- if (Do_Init)
- {
- ::CRYPTO_set_id_callback(0);
- ::CRYPTO_set_locking_callback(0);
- ::ERR_free_strings();
- ::ERR_remove_state(0);
- ::EVP_cleanup();
- ::CRYPTO_cleanup_all_ex_data();
- ::CONF_modules_unload(1);
- ::ENGINE_cleanup();
- }
- }
-
- // Helper function to manage a do_init singleton. The static instance of the
- // openssl_init object ensures that this function is always called before
- // main, and therefore before any other threads can get started. The do_init
- // instance must be static in this function to ensure that it gets
- // initialised before any other global objects try to use it.
- static boost::shared_ptr<do_init> instance()
- {
- static boost::shared_ptr<do_init> init(new do_init);
- return init;
- }
-
- private:
- static unsigned long openssl_id_func()
- {
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- return ::GetCurrentThreadId();
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- void* id = instance()->thread_id_;
- if (id == 0)
- instance()->thread_id_ = id = &id; // Ugh.
- BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*));
- return reinterpret_cast<unsigned long>(id);
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- }
-
- static void openssl_locking_func(int mode, int n,
- const char* /*file*/, int /*line*/)
- {
- if (mode & CRYPTO_LOCK)
- instance()->mutexes_[n]->lock();
- else
- instance()->mutexes_[n]->unlock();
- }
-
- // Mutexes to be used in locking callbacks.
- std::vector<boost::shared_ptr<boost::asio::detail::mutex> > mutexes_;
-
-#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
- // The thread identifiers to be used by openssl.
- boost::asio::detail::tss_ptr<void> thread_id_;
-#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
- };
+protected:
+ // Class that performs the actual initialisation.
+ class do_init;
+
+ // Helper function to manage a do_init singleton. The static instance of the
+ // openssl_init object ensures that this function is always called before
+ // main, and therefore before any other threads can get started. The do_init
+ // instance must be static in this function to ensure that it gets
+ // initialised before any other global objects try to use it.
+ BOOST_ASIO_DECL static boost::asio::detail::shared_ptr<do_init> instance();
+};
 
+template <bool Do_Init = true>
+class openssl_init : private openssl_init_base
+{
 public:
   // Constructor.
   openssl_init()
- : ref_(do_init::instance())
+ : ref_(instance())
   {
     using namespace std; // For memmove.
 
@@ -138,7 +68,7 @@
 
   // Reference to singleton do_init object to ensure that openssl does not get
   // cleaned up until the last user has finished with it.
- boost::shared_ptr<do_init> ref_;
+ boost::asio::detail::shared_ptr<do_init> ref_;
 };
 
 template <bool Do_Init>
@@ -151,4 +81,8 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/ssl/detail/impl/openssl_init.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP

Deleted: trunk/boost/asio/ssl/detail/openssl_operation.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_operation.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
+++ (empty file)
@@ -1,524 +0,0 @@
-//
-// ssl/detail/openssl_operation.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster 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 BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP
-#define BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/config.hpp>
-#include <boost/function.hpp>
-#include <boost/assert.hpp>
-#include <boost/bind.hpp>
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/placeholders.hpp>
-#include <boost/asio/ssl/detail/openssl_types.hpp>
-#include <boost/asio/ssl/error.hpp>
-#include <boost/asio/strand.hpp>
-#include <boost/system/system_error.hpp>
-#include <boost/asio/write.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace ssl {
-namespace detail {
-
-typedef boost::function<int (::SSL*)> ssl_primitive_func;
-typedef boost::function<void (const boost::system::error_code&, int)>
- user_handler_func;
-
-// Network send_/recv buffer implementation
-//
-//
-class net_buffer
-{
- static const int NET_BUF_SIZE = 16*1024 + 256; // SSL record size + spare
-
- unsigned char buf_[NET_BUF_SIZE];
- unsigned char* data_start_;
- unsigned char* data_end_;
-
-public:
- net_buffer()
- {
- data_start_ = data_end_ = buf_;
- }
- unsigned char* get_unused_start() { return data_end_; }
- unsigned char* get_data_start() { return data_start_; }
- size_t get_unused_len() { return (NET_BUF_SIZE - (data_end_ - buf_)); }
- size_t get_data_len() { return (data_end_ - data_start_); }
- void data_added(size_t count)
- {
- data_end_ += count;
- data_end_ = data_end_ > (buf_ + NET_BUF_SIZE)?
- (buf_ + NET_BUF_SIZE):
- data_end_;
- }
- void data_removed(size_t count)
- {
- data_start_ += count;
- if (data_start_ >= data_end_) reset();
- }
- void reset() { data_start_ = buf_; data_end_ = buf_; }
- bool has_data() { return (data_start_ < data_end_); }
-}; // class net_buffer
-
-//
-// Operation class
-//
-//
-template <typename Stream>
-class openssl_operation
-{
-public:
-
- // Constructor for asynchronous operations
- openssl_operation(ssl_primitive_func primitive,
- Stream& socket,
- net_buffer& recv_buf,
- SSL* session,
- BIO* ssl_bio,
- user_handler_func handler,
- boost::asio::io_service::strand& strand
- )
- : primitive_(primitive)
- , user_handler_(handler)
- , strand_(&strand)
- , recv_buf_(recv_buf)
- , socket_(socket)
- , ssl_bio_(ssl_bio)
- , session_(session)
- {
- write_ = boost::bind(
- &openssl_operation::do_async_write,
- this, boost::arg<1>(), boost::arg<2>()
- );
- read_ = boost::bind(
- &openssl_operation::do_async_read,
- this
- );
- handler_= boost::bind(
- &openssl_operation::async_user_handler,
- this, boost::arg<1>(), boost::arg<2>()
- );
- }
-
- // Constructor for synchronous operations
- openssl_operation(ssl_primitive_func primitive,
- Stream& socket,
- net_buffer& recv_buf,
- SSL* session,
- BIO* ssl_bio)
- : primitive_(primitive)
- , strand_(0)
- , recv_buf_(recv_buf)
- , socket_(socket)
- , ssl_bio_(ssl_bio)
- , session_(session)
- {
- write_ = boost::bind(
- &openssl_operation::do_sync_write,
- this, boost::arg<1>(), boost::arg<2>()
- );
- read_ = boost::bind(
- &openssl_operation::do_sync_read,
- this
- );
- handler_ = boost::bind(
- &openssl_operation::sync_user_handler,
- this, boost::arg<1>(), boost::arg<2>()
- );
- }
-
- // Start operation
- // In case of asynchronous it returns 0, in sync mode returns success code
- // or throws an error...
- int start()
- {
- int rc = primitive_( session_ );
-
- bool is_operation_done = (rc > 0);
- // For connect/accept/shutdown, the operation
- // is done, when return code is 1
- // for write, it is done, when is retcode > 0
- // for read, is is done when retcode > 0
-
- int error_code = !is_operation_done ?
- ::SSL_get_error( session_, rc ) :
- 0;
- int sys_error_code = ERR_get_error();
-
- if (error_code == SSL_ERROR_SSL)
- return handler_(boost::system::error_code(
- sys_error_code, boost::asio::error::get_ssl_category()), rc);
-
- bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
- bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
- ::BIO_ctrl_pending( ssl_bio_ ));
- bool is_shut_down_received =
- ((::SSL_get_shutdown( session_ ) & SSL_RECEIVED_SHUTDOWN) ==
- SSL_RECEIVED_SHUTDOWN);
- bool is_shut_down_sent =
- ((::SSL_get_shutdown( session_ ) & SSL_SENT_SHUTDOWN) ==
- SSL_SENT_SHUTDOWN);
-
- if (is_shut_down_sent && is_shut_down_received
- && is_operation_done && !is_write_needed)
- // SSL connection is shut down cleanly
- return handler_(boost::system::error_code(), 1);
-
- if (is_shut_down_received && !is_operation_done)
- // Shutdown has been requested, while we were reading or writing...
- // abort our action...
- return handler_(boost::asio::error::shut_down, 0);
-
- if (!is_operation_done && !is_read_needed && !is_write_needed
- && !is_shut_down_sent)
- {
- // The operation has failed... It is not completed and does
- // not want network communication nor does want to send shutdown out...
- if (error_code == SSL_ERROR_SYSCALL)
- {
- return handler_(boost::system::error_code(
- sys_error_code, boost::asio::error::system_category), rc);
- }
- else
- {
- return handler_(boost::system::error_code(
- sys_error_code, boost::asio::error::get_ssl_category()), rc);
- }
- }
-
- if (!is_operation_done && !is_write_needed)
- {
- // We may have left over data that we can pass to SSL immediately
- if (recv_buf_.get_data_len() > 0)
- {
- // Pass the buffered data to SSL
- int written = ::BIO_write
- (
- ssl_bio_,
- recv_buf_.get_data_start(),
- recv_buf_.get_data_len()
- );
-
- if (written > 0)
- {
- recv_buf_.data_removed(written);
- }
- else if (written < 0)
- {
- if (!BIO_should_retry(ssl_bio_))
- {
- // Some serios error with BIO....
- return handler_(boost::asio::error::no_recovery, 0);
- }
- }
-
- return start();
- }
- else if (is_read_needed || (is_shut_down_sent && !is_shut_down_received))
- {
- return read_();
- }
- }
-
- // Continue with operation, flush any SSL data out to network...
- return write_(is_operation_done, rc);
- }
-
-// Private implementation
-private:
- typedef boost::function<int (const boost::system::error_code&, int)>
- int_handler_func;
- typedef boost::function<int (bool, int)> write_func;
- typedef boost::function<int ()> read_func;
-
- ssl_primitive_func primitive_;
- user_handler_func user_handler_;
- boost::asio::io_service::strand* strand_;
- write_func write_;
- read_func read_;
- int_handler_func handler_;
-
- net_buffer send_buf_; // buffers for network IO
-
- // The recv buffer is owned by the stream, not the operation, since there can
- // be left over bytes after passing the data up to the application, and these
- // bytes need to be kept around for the next read operation issued by the
- // application.
- net_buffer& recv_buf_;
-
- Stream& socket_;
- BIO* ssl_bio_;
- SSL* session_;
-
- //
- int sync_user_handler(const boost::system::error_code& error, int rc)
- {
- if (!error)
- return rc;
-
- throw boost::system::system_error(error);
- }
-
- int async_user_handler(boost::system::error_code error, int rc)
- {
- if (rc < 0)
- {
- if (!error)
- error = boost::asio::error::no_recovery;
- rc = 0;
- }
-
- user_handler_(error, rc);
- return 0;
- }
-
- // Writes bytes asynchronously from SSL to NET
- int do_async_write(bool is_operation_done, int rc)
- {
- int len = ::BIO_ctrl_pending( ssl_bio_ );
- if ( len )
- {
- // There is something to write into net, do it...
- len = (int)send_buf_.get_unused_len() > len?
- len:
- send_buf_.get_unused_len();
-
- if (len == 0)
- {
- // In case our send buffer is full, we have just to wait until
- // previous send to complete...
- return 0;
- }
-
- // Read outgoing data from bio
- len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len);
-
- if (len > 0)
- {
- unsigned char *data_start = send_buf_.get_unused_start();
- send_buf_.data_added(len);
-
- BOOST_ASSERT(strand_);
- boost::asio::async_write
- (
- socket_,
- boost::asio::buffer(data_start, len),
- strand_->wrap
- (
- boost::bind
- (
- &openssl_operation::async_write_handler,
- this,
- is_operation_done,
- rc,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred
- )
- )
- );
-
- return 0;
- }
- else if (!BIO_should_retry(ssl_bio_))
- {
- // Seems like fatal error
- // reading from SSL BIO has failed...
- handler_(boost::asio::error::no_recovery, 0);
- return 0;
- }
- }
-
- if (is_operation_done)
- {
- // Finish the operation, with success
- handler_(boost::system::error_code(), rc);
- return 0;
- }
-
- // OPeration is not done and writing to net has been made...
- // start operation again
- start();
-
- return 0;
- }
-
- void async_write_handler(bool is_operation_done, int rc,
- const boost::system::error_code& error, size_t bytes_sent)
- {
- if (!error)
- {
- // Remove data from send buffer
- send_buf_.data_removed(bytes_sent);
-
- if (is_operation_done)
- handler_(boost::system::error_code(), rc);
- else
- // Since the operation was not completed, try it again...
- start();
- }
- else
- handler_(error, rc);
- }
-
- int do_async_read()
- {
- // Wait for new data
- BOOST_ASSERT(strand_);
- socket_.async_read_some
- (
- boost::asio::buffer(recv_buf_.get_unused_start(),
- recv_buf_.get_unused_len()),
- strand_->wrap
- (
- boost::bind
- (
- &openssl_operation::async_read_handler,
- this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred
- )
- )
- );
- return 0;
- }
-
- void async_read_handler(const boost::system::error_code& error,
- size_t bytes_recvd)
- {
- if (!error)
- {
- recv_buf_.data_added(bytes_recvd);
-
- // Pass the received data to SSL
- int written = ::BIO_write
- (
- ssl_bio_,
- recv_buf_.get_data_start(),
- recv_buf_.get_data_len()
- );
-
- if (written > 0)
- {
- recv_buf_.data_removed(written);
- }
- else if (written < 0)
- {
- if (!BIO_should_retry(ssl_bio_))
- {
- // Some serios error with BIO....
- handler_(boost::asio::error::no_recovery, 0);
- return;
- }
- }
-
- // and try the SSL primitive again
- start();
- }
- else
- {
- // Error in network level...
- // SSL can't continue either...
- handler_(error, 0);
- }
- }
-
- // Syncronous functions...
- int do_sync_write(bool is_operation_done, int rc)
- {
- int len = ::BIO_ctrl_pending( ssl_bio_ );
- if ( len )
- {
- // There is something to write into net, do it...
- len = (int)send_buf_.get_unused_len() > len?
- len:
- send_buf_.get_unused_len();
-
- // Read outgoing data from bio
- len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len);
-
- if (len > 0)
- {
- size_t sent_len = boost::asio::write(
- socket_,
- boost::asio::buffer(send_buf_.get_unused_start(), len)
- );
-
- send_buf_.data_added(len);
- send_buf_.data_removed(sent_len);
- }
- else if (!BIO_should_retry(ssl_bio_))
- {
- // Seems like fatal error
- // reading from SSL BIO has failed...
- throw boost::system::system_error(boost::asio::error::no_recovery);
- }
- }
-
- if (is_operation_done)
- // Finish the operation, with success
- return rc;
-
- // Operation is not finished, start again.
- return start();
- }
-
- int do_sync_read()
- {
- size_t len = socket_.read_some
- (
- boost::asio::buffer(recv_buf_.get_unused_start(),
- recv_buf_.get_unused_len())
- );
-
- // Write data to ssl
- recv_buf_.data_added(len);
-
- // Pass the received data to SSL
- int written = ::BIO_write
- (
- ssl_bio_,
- recv_buf_.get_data_start(),
- recv_buf_.get_data_len()
- );
-
- if (written > 0)
- {
- recv_buf_.data_removed(written);
- }
- else if (written < 0)
- {
- if (!BIO_should_retry(ssl_bio_))
- {
- // Some serios error with BIO....
- throw boost::system::system_error(boost::asio::error::no_recovery);
- }
- }
-
- // Try the operation again
- return start();
- }
-}; // class openssl_operation
-
-} // namespace detail
-} // namespace ssl
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP

Deleted: trunk/boost/asio/ssl/detail/openssl_stream_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_stream_service.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
+++ (empty file)
@@ -1,571 +0,0 @@
-//
-// ssl/detail/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)
-//
-// 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 BOOST_ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP
-#define BOOST_ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <climits>
-#include <memory>
-#include <boost/config.hpp>
-#include <boost/noncopyable.hpp>
-#include <boost/function.hpp>
-#include <boost/bind.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/ssl/basic_context.hpp>
-#include <boost/asio/ssl/stream_base.hpp>
-#include <boost/asio/ssl/detail/openssl_operation.hpp>
-#include <boost/asio/ssl/detail/openssl_types.hpp>
-#include <boost/asio/strand.hpp>
-#include <boost/system/system_error.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace ssl {
-namespace detail {
-
-class openssl_stream_service
- : public boost::asio::detail::service_base<openssl_stream_service>
-{
-private:
- enum { max_buffer_size = INT_MAX };
-
- //Base handler for asyncrhonous operations
- template <typename Stream>
- class base_handler
- {
- public:
- typedef boost::function<
- void (const boost::system::error_code&, size_t)> func_t;
-
- base_handler(boost::asio::io_service& io_service)
- : op_(NULL)
- , io_service_(io_service)
- , work_(io_service)
- {}
-
- void do_func(const boost::system::error_code& error, size_t size)
- {
- func_(error, size);
- }
-
- void set_operation(openssl_operation<Stream>* op) { op_ = op; }
- void set_func(func_t func) { func_ = func; }
-
- ~base_handler()
- {
- delete op_;
- }
-
- private:
- func_t func_;
- openssl_operation<Stream>* op_;
- boost::asio::io_service& io_service_;
- boost::asio::io_service::work work_;
- }; // class base_handler
-
- // Handler for asynchronous IO (write/read) operations
- template<typename Stream, typename Handler>
- class io_handler
- : public base_handler<Stream>
- {
- public:
- io_handler(Handler handler, boost::asio::io_service& io_service)
- : base_handler<Stream>(io_service)
- , handler_(handler)
- {
- this->set_func(boost::bind(
- &io_handler<Stream, Handler>::handler_impl,
- this, boost::arg<1>(), boost::arg<2>() ));
- }
-
- private:
- Handler handler_;
- void handler_impl(const boost::system::error_code& error, size_t size)
- {
- std::auto_ptr<io_handler<Stream, Handler> > this_ptr(this);
- handler_(error, size);
- }
- }; // class io_handler
-
- // Handler for asyncrhonous handshake (connect, accept) functions
- template <typename Stream, typename Handler>
- class handshake_handler
- : public base_handler<Stream>
- {
- public:
- handshake_handler(Handler handler, boost::asio::io_service& io_service)
- : base_handler<Stream>(io_service)
- , handler_(handler)
- {
- this->set_func(boost::bind(
- &handshake_handler<Stream, Handler>::handler_impl,
- this, boost::arg<1>(), boost::arg<2>() ));
- }
-
- private:
- Handler handler_;
- void handler_impl(const boost::system::error_code& error, size_t)
- {
- std::auto_ptr<handshake_handler<Stream, Handler> > this_ptr(this);
- handler_(error);
- }
-
- }; // class handshake_handler
-
- // Handler for asyncrhonous shutdown
- template <typename Stream, typename Handler>
- class shutdown_handler
- : public base_handler<Stream>
- {
- public:
- shutdown_handler(Handler handler, boost::asio::io_service& io_service)
- : base_handler<Stream>(io_service),
- handler_(handler)
- {
- this->set_func(boost::bind(
- &shutdown_handler<Stream, Handler>::handler_impl,
- this, boost::arg<1>(), boost::arg<2>() ));
- }
-
- private:
- Handler handler_;
- void handler_impl(const boost::system::error_code& error, size_t)
- {
- std::auto_ptr<shutdown_handler<Stream, Handler> > this_ptr(this);
- handler_(error);
- }
- }; // class shutdown_handler
-
-public:
- // The implementation type.
- typedef struct impl_struct
- {
- ::SSL* ssl;
- ::BIO* ext_bio;
- net_buffer recv_buf;
- } * impl_type;
-
- // Construct a new stream socket service for the specified io_service.
- explicit openssl_stream_service(boost::asio::io_service& io_service)
- : boost::asio::detail::service_base<openssl_stream_service>(io_service),
- strand_(io_service)
- {
- }
-
- // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- }
-
- // Return a null stream implementation.
- impl_type null() const
- {
- return 0;
- }
-
- // Create a new stream implementation.
- template <typename Stream, typename Context_Service>
- void create(impl_type& impl, Stream& /*next_layer*/,
- basic_context<Context_Service>& context)
- {
- impl = new impl_struct;
- impl->ssl = ::SSL_new(context.impl());
- ::SSL_set_mode(impl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
- ::SSL_set_mode(impl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
- ::BIO* int_bio = 0;
- impl->ext_bio = 0;
- ::BIO_new_bio_pair(&int_bio, 8192, &impl->ext_bio, 8192);
- ::SSL_set_bio(impl->ssl, int_bio, int_bio);
- }
-
- // Destroy a stream implementation.
- template <typename Stream>
- void destroy(impl_type& impl, Stream& /*next_layer*/)
- {
- if (impl != 0)
- {
- ::BIO_free(impl->ext_bio);
- ::SSL_free(impl->ssl);
- delete impl;
- impl = 0;
- }
- }
-
- // Perform SSL handshaking.
- template <typename Stream>
- boost::system::error_code handshake(impl_type& impl, Stream& next_layer,
- stream_base::handshake_type type, boost::system::error_code& ec)
- {
- try
- {
- openssl_operation<Stream> op(
- type == stream_base::client ?
- &ssl_wrap<mutex_type>::SSL_connect:
- &ssl_wrap<mutex_type>::SSL_accept,
- next_layer,
- impl->recv_buf,
- impl->ssl,
- impl->ext_bio);
- op.start();
- }
- catch (boost::system::system_error& e)
- {
- ec = e.code();
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Start an asynchronous SSL handshake.
- template <typename Stream, typename Handler>
- void async_handshake(impl_type& impl, Stream& next_layer,
- stream_base::handshake_type type, Handler handler)
- {
- typedef handshake_handler<Stream, Handler> connect_handler;
-
- connect_handler* local_handler =
- new connect_handler(handler, get_io_service());
-
- openssl_operation<Stream>* op = new openssl_operation<Stream>
- (
- type == stream_base::client ?
- &ssl_wrap<mutex_type>::SSL_connect:
- &ssl_wrap<mutex_type>::SSL_accept,
- next_layer,
- impl->recv_buf,
- impl->ssl,
- impl->ext_bio,
- boost::bind
- (
- &base_handler<Stream>::do_func,
- local_handler,
- boost::arg<1>(),
- boost::arg<2>()
- ),
- strand_
- );
- local_handler->set_operation(op);
-
- strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
- }
-
- // Shut down SSL on the stream.
- template <typename Stream>
- boost::system::error_code shutdown(impl_type& impl, Stream& next_layer,
- boost::system::error_code& ec)
- {
- try
- {
- openssl_operation<Stream> op(
- &ssl_wrap<mutex_type>::SSL_shutdown,
- next_layer,
- impl->recv_buf,
- impl->ssl,
- impl->ext_bio);
- op.start();
- }
- catch (boost::system::system_error& e)
- {
- ec = e.code();
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
-
- // Asynchronously shut down SSL on the stream.
- template <typename Stream, typename Handler>
- void async_shutdown(impl_type& impl, Stream& next_layer, Handler handler)
- {
- typedef shutdown_handler<Stream, Handler> disconnect_handler;
-
- disconnect_handler* local_handler =
- new disconnect_handler(handler, get_io_service());
-
- openssl_operation<Stream>* op = new openssl_operation<Stream>
- (
- &ssl_wrap<mutex_type>::SSL_shutdown,
- next_layer,
- impl->recv_buf,
- impl->ssl,
- impl->ext_bio,
- boost::bind
- (
- &base_handler<Stream>::do_func,
- local_handler,
- boost::arg<1>(),
- boost::arg<2>()
- ),
- strand_
- );
- local_handler->set_operation(op);
-
- strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
- }
-
- // Write some data to the stream.
- template <typename Stream, typename Const_Buffers>
- std::size_t write_some(impl_type& impl, Stream& next_layer,
- const Const_Buffers& buffers, boost::system::error_code& ec)
- {
- size_t bytes_transferred = 0;
- try
- {
- boost::asio::const_buffer buffer =
- boost::asio::detail::buffer_sequence_adapter<
- boost::asio::const_buffer, Const_Buffers>::first(buffers);
-
- std::size_t buffer_size = boost::asio::buffer_size(buffer);
- if (buffer_size > max_buffer_size)
- buffer_size = max_buffer_size;
- else if (buffer_size == 0)
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- boost::function<int (SSL*)> send_func =
- boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
- boost::asio::buffer_cast<const void*>(buffer),
- static_cast<int>(buffer_size));
- openssl_operation<Stream> op(
- send_func,
- next_layer,
- impl->recv_buf,
- impl->ssl,
- impl->ext_bio
- );
- bytes_transferred = static_cast<size_t>(op.start());
- }
- catch (boost::system::system_error& e)
- {
- ec = e.code();
- return 0;
- }
-
- ec = boost::system::error_code();
- return bytes_transferred;
- }
-
- // Start an asynchronous write.
- template <typename Stream, typename Const_Buffers, typename Handler>
- void async_write_some(impl_type& impl, Stream& next_layer,
- const Const_Buffers& buffers, Handler handler)
- {
- typedef io_handler<Stream, Handler> send_handler;
-
- boost::asio::const_buffer buffer =
- boost::asio::detail::buffer_sequence_adapter<
- boost::asio::const_buffer, Const_Buffers>::first(buffers);
-
- std::size_t buffer_size = boost::asio::buffer_size(buffer);
- if (buffer_size > max_buffer_size)
- buffer_size = max_buffer_size;
- else if (buffer_size == 0)
- {
- get_io_service().post(boost::asio::detail::bind_handler(
- handler, boost::system::error_code(), 0));
- return;
- }
-
- send_handler* local_handler = new send_handler(handler, get_io_service());
-
- boost::function<int (SSL*)> send_func =
- boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
- boost::asio::buffer_cast<const void*>(buffer),
- static_cast<int>(buffer_size));
-
- openssl_operation<Stream>* op = new openssl_operation<Stream>
- (
- send_func,
- next_layer,
- impl->recv_buf,
- impl->ssl,
- impl->ext_bio,
- boost::bind
- (
- &base_handler<Stream>::do_func,
- local_handler,
- boost::arg<1>(),
- boost::arg<2>()
- ),
- strand_
- );
- local_handler->set_operation(op);
-
- strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
- }
-
- // Read some data from the stream.
- template <typename Stream, typename Mutable_Buffers>
- std::size_t read_some(impl_type& impl, Stream& next_layer,
- const Mutable_Buffers& buffers, boost::system::error_code& ec)
- {
- size_t bytes_transferred = 0;
- try
- {
- boost::asio::mutable_buffer buffer =
- boost::asio::detail::buffer_sequence_adapter<
- boost::asio::mutable_buffer, Mutable_Buffers>::first(buffers);
-
- std::size_t buffer_size = boost::asio::buffer_size(buffer);
- if (buffer_size > max_buffer_size)
- buffer_size = max_buffer_size;
- else if (buffer_size == 0)
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- boost::function<int (SSL*)> recv_func =
- boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
- boost::asio::buffer_cast<void*>(buffer),
- static_cast<int>(buffer_size));
- openssl_operation<Stream> op(recv_func,
- next_layer,
- impl->recv_buf,
- impl->ssl,
- impl->ext_bio
- );
-
- bytes_transferred = static_cast<size_t>(op.start());
- }
- catch (boost::system::system_error& e)
- {
- ec = e.code();
- return 0;
- }
-
- ec = boost::system::error_code();
- return bytes_transferred;
- }
-
- // Start an asynchronous read.
- template <typename Stream, typename Mutable_Buffers, typename Handler>
- void async_read_some(impl_type& impl, Stream& next_layer,
- const Mutable_Buffers& buffers, Handler handler)
- {
- typedef io_handler<Stream, Handler> recv_handler;
-
- boost::asio::mutable_buffer buffer =
- boost::asio::detail::buffer_sequence_adapter<
- boost::asio::mutable_buffer, Mutable_Buffers>::first(buffers);
-
- std::size_t buffer_size = boost::asio::buffer_size(buffer);
- if (buffer_size > max_buffer_size)
- buffer_size = max_buffer_size;
- else if (buffer_size == 0)
- {
- get_io_service().post(boost::asio::detail::bind_handler(
- handler, boost::system::error_code(), 0));
- return;
- }
-
- recv_handler* local_handler = new recv_handler(handler, get_io_service());
-
- boost::function<int (SSL*)> recv_func =
- boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
- boost::asio::buffer_cast<void*>(buffer),
- static_cast<int>(buffer_size));
-
- openssl_operation<Stream>* op = new openssl_operation<Stream>
- (
- recv_func,
- next_layer,
- impl->recv_buf,
- impl->ssl,
- impl->ext_bio,
- boost::bind
- (
- &base_handler<Stream>::do_func,
- local_handler,
- boost::arg<1>(),
- boost::arg<2>()
- ),
- strand_
- );
- local_handler->set_operation(op);
-
- strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
- }
-
- // Peek at the incoming data on the stream.
- template <typename Stream, typename Mutable_Buffers>
- std::size_t peek(impl_type& /*impl*/, Stream& /*next_layer*/,
- const Mutable_Buffers& /*buffers*/, boost::system::error_code& ec)
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- // Determine the amount of data that may be read without blocking.
- template <typename Stream>
- std::size_t in_avail(impl_type& /*impl*/, Stream& /*next_layer*/,
- boost::system::error_code& ec)
- {
- ec = boost::system::error_code();
- return 0;
- }
-
-private:
- boost::asio::io_service::strand strand_;
-
- typedef boost::asio::detail::mutex mutex_type;
-
- template<typename Mutex>
- struct ssl_wrap
- {
- static Mutex ssl_mutex_;
-
- static int SSL_accept(SSL *ssl)
- {
- typename Mutex::scoped_lock lock(ssl_mutex_);
- return ::SSL_accept(ssl);
- }
-
- static int SSL_connect(SSL *ssl)
- {
- typename Mutex::scoped_lock lock(ssl_mutex_);
- return ::SSL_connect(ssl);
- }
-
- static int SSL_shutdown(SSL *ssl)
- {
- typename Mutex::scoped_lock lock(ssl_mutex_);
- return ::SSL_shutdown(ssl);
- }
- };
-};
-
-template<typename Mutex>
-Mutex openssl_stream_service::ssl_wrap<Mutex>::ssl_mutex_;
-
-} // namespace detail
-} // namespace ssl
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP

Modified: trunk/boost/asio/ssl/detail/openssl_types.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_types.hpp (original)
+++ trunk/boost/asio/ssl/detail/openssl_types.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -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)

Added: trunk/boost/asio/ssl/detail/password_callback.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/password_callback.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,74 @@
+//
+// 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 BOOST_ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP
+#define BOOST_ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <cstddef>
+# include <string>
+# include <boost/asio/ssl/context_base.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_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(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP

Added: trunk/boost/asio/ssl/detail/read_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/read_op.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,75 @@
+//
+// 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 BOOST_ASIO_SSL_DETAIL_READ_OP_HPP
+#define BOOST_ASIO_SSL_DETAIL_READ_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/detail/buffer_sequence_adapter.hpp>
+# include <boost/asio/ssl/detail/engine.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+template <typename MutableBufferSequence>
+class read_op
+{
+public:
+ read_op(const MutableBufferSequence& buffers)
+ : buffers_(buffers)
+ {
+ }
+
+ engine::want operator()(engine& eng,
+ boost::system::error_code& ec,
+ std::size_t& bytes_transferred) const
+ {
+ boost::asio::mutable_buffer buffer =
+ boost::asio::detail::buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence>::first(buffers_);
+
+ return eng.read(buffer, ec, bytes_transferred);
+ }
+
+ template <typename Handler>
+ void call_handler(Handler& handler,
+ const boost::system::error_code& ec,
+ const std::size_t& bytes_transferred) const
+ {
+ handler(ec, bytes_transferred);
+ }
+
+private:
+ MutableBufferSequence buffers_;
+};
+
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_READ_OP_HPP

Added: trunk/boost/asio/ssl/detail/shutdown_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/shutdown_op.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,62 @@
+//
+// 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 BOOST_ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP
+#define BOOST_ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/detail/engine.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+class shutdown_op
+{
+public:
+ engine::want operator()(engine& eng,
+ boost::system::error_code& ec,
+ std::size_t& bytes_transferred) const
+ {
+ bytes_transferred = 0;
+ return eng.shutdown(ec);
+ }
+
+ template <typename Handler>
+ void call_handler(Handler& handler,
+ const boost::system::error_code& ec,
+ const std::size_t&) const
+ {
+ handler(ec);
+ }
+};
+
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP

Added: trunk/boost/asio/ssl/detail/stream_core.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/stream_core.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,88 @@
+//
+// ssl/detail/stream_core.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 BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP
+#define BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/deadline_timer.hpp>
+# include <boost/asio/ssl/detail/engine.hpp>
+# include <boost/asio/buffer.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+struct stream_core
+{
+ stream_core(SSL_CTX* context, boost::asio::io_service& io_service)
+ : engine_(context),
+ pending_read_(io_service),
+ pending_write_(io_service),
+ output_buffer_space_(16384),
+ output_buffer_(boost::asio::buffer(output_buffer_space_)),
+ input_buffer_space_(16384),
+ input_buffer_(boost::asio::buffer(input_buffer_space_))
+ {
+ pending_read_.expires_at(boost::posix_time::neg_infin);
+ pending_write_.expires_at(boost::posix_time::neg_infin);
+ }
+
+ ~stream_core()
+ {
+ }
+
+ // The SSL engine.
+ engine engine_;
+
+ // Timer used for storing queued read operations.
+ boost::asio::deadline_timer pending_read_;
+
+ // Timer used for storing queued write operations.
+ boost::asio::deadline_timer pending_write_;
+
+ // Buffer space used to prepare output intended for the transport.
+ std::vector<unsigned char> output_buffer_space_;
+
+ // A buffer that may be used to prepare output intended for the transport.
+ const boost::asio::mutable_buffers_1 output_buffer_;
+
+ // Buffer space used to read input intended for the engine.
+ std::vector<unsigned char> input_buffer_space_;
+
+ // A buffer that may be used to read input intended for the engine.
+ const boost::asio::mutable_buffers_1 input_buffer_;
+
+ // The buffer pointing to the engine's unconsumed input.
+ boost::asio::const_buffer input_;
+};
+
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP

Added: trunk/boost/asio/ssl/detail/write_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/detail/write_op.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,75 @@
+//
+// 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 BOOST_ASIO_SSL_DETAIL_WRITE_OP_HPP
+#define BOOST_ASIO_SSL_DETAIL_WRITE_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/detail/buffer_sequence_adapter.hpp>
+# include <boost/asio/ssl/detail/engine.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace detail {
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+template <typename ConstBufferSequence>
+class write_op
+{
+public:
+ write_op(const ConstBufferSequence& buffers)
+ : buffers_(buffers)
+ {
+ }
+
+ engine::want operator()(engine& eng,
+ boost::system::error_code& ec,
+ std::size_t& bytes_transferred) const
+ {
+ boost::asio::const_buffer buffer =
+ boost::asio::detail::buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence>::first(buffers_);
+
+ return eng.write(buffer, ec, bytes_transferred);
+ }
+
+ template <typename Handler>
+ void call_handler(Handler& handler,
+ const boost::system::error_code& ec,
+ const std::size_t& bytes_transferred) const
+ {
+ handler(ec, bytes_transferred);
+ }
+
+private:
+ ConstBufferSequence buffers_;
+};
+
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace detail
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_DETAIL_WRITE_OP_HPP

Added: trunk/boost/asio/ssl/impl/context.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/impl/context.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,57 @@
+//
+// 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 BOOST_ASIO_SSL_IMPL_CONTEXT_HPP
+#define BOOST_ASIO_SSL_IMPL_CONTEXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/detail/throw_error.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+template <typename PasswordCallback>
+void context::set_password_callback(PasswordCallback callback)
+{
+ boost::system::error_code ec;
+ this->set_password_callback(callback, ec);
+ boost::asio::detail::throw_error(ec, "set_password_callback");
+}
+
+template <typename PasswordCallback>
+boost::system::error_code context::set_password_callback(
+ PasswordCallback callback, boost::system::error_code& ec)
+{
+ return do_set_password_callback(
+ new detail::password_callback<PasswordCallback>(callback), ec);
+}
+
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_IMPL_CONTEXT_HPP

Added: trunk/boost/asio/ssl/impl/context.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/impl/context.ipp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,433 @@
+//
+// 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 BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
+#define BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <cstring>
+# include <boost/asio/detail/throw_error.hpp>
+# include <boost/asio/error.hpp>
+# include <boost/asio/ssl/context.hpp>
+# include <boost/asio/ssl/error.hpp>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+
+#if !defined(BOOST_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)
+ {
+ boost::system::error_code ec(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ boost::asio::detail::throw_error(ec, "context");
+ }
+}
+
+context::context(boost::asio::io_service&, context::method m)
+ : handle_(0)
+{
+ context tmp(m);
+ handle_ = tmp.handle_;
+ tmp.handle_ = 0;
+}
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+context::context(context&& other)
+{
+ handle_ = other.handle_;
+ other.handle_ = 0;
+}
+
+context& context::operator=(context&& other)
+{
+ context tmp(BOOST_ASIO_MOVE_CAST(context)(*this));
+ handle_ = other.handle_;
+ other.handle_ = 0;
+ return *this;
+}
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+context::~context()
+{
+ if (handle_)
+ {
+ if (handle_->default_passwd_callback_userdata)
+ {
+ detail::password_callback_base* callback =
+ static_cast<detail::password_callback_base*>(
+ 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)
+{
+ boost::system::error_code ec;
+ set_options(o, ec);
+ boost::asio::detail::throw_error(ec, "set_options");
+}
+
+boost::system::error_code context::set_options(
+ context::options o, boost::system::error_code& ec)
+{
+ ::SSL_CTX_set_options(handle_, o);
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void context::set_verify_mode(context::verify_mode v)
+{
+ boost::system::error_code ec;
+ set_verify_mode(v, ec);
+ boost::asio::detail::throw_error(ec, "set_verify_mode");
+}
+
+boost::system::error_code context::set_verify_mode(
+ context::verify_mode v, boost::system::error_code& ec)
+{
+ ::SSL_CTX_set_verify(handle_, v, 0);
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void context::load_verify_file(const std::string& filename)
+{
+ boost::system::error_code ec;
+ load_verify_file(filename, ec);
+ boost::asio::detail::throw_error(ec, "load_verify_file");
+}
+
+boost::system::error_code context::load_verify_file(
+ const std::string& filename, boost::system::error_code& ec)
+{
+ if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1)
+ {
+ ec = boost::system::error_code(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void context::add_verify_path(const std::string& path)
+{
+ boost::system::error_code ec;
+ add_verify_path(path, ec);
+ boost::asio::detail::throw_error(ec, "add_verify_path");
+}
+
+boost::system::error_code context::add_verify_path(
+ const std::string& path, boost::system::error_code& ec)
+{
+ if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1)
+ {
+ ec = boost::system::error_code(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void context::use_certificate_file(
+ const std::string& filename, file_format format)
+{
+ boost::system::error_code ec;
+ use_certificate_file(filename, format, ec);
+ boost::asio::detail::throw_error(ec, "use_certificate_file");
+}
+
+boost::system::error_code context::use_certificate_file(
+ const std::string& filename, file_format format,
+ boost::system::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 = boost::asio::error::invalid_argument;
+ return ec;
+ }
+ }
+
+ if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1)
+ {
+ ec = boost::system::error_code(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void context::use_certificate_chain_file(const std::string& filename)
+{
+ boost::system::error_code ec;
+ use_certificate_chain_file(filename, ec);
+ boost::asio::detail::throw_error(ec, "use_certificate_chain_file");
+}
+
+boost::system::error_code context::use_certificate_chain_file(
+ const std::string& filename, boost::system::error_code& ec)
+{
+ if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1)
+ {
+ ec = boost::system::error_code(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void context::use_private_key_file(
+ const std::string& filename, context::file_format format)
+{
+ boost::system::error_code ec;
+ use_private_key_file(filename, format, ec);
+ boost::asio::detail::throw_error(ec, "use_private_key_file");
+}
+
+boost::system::error_code context::use_private_key_file(
+ const std::string& filename, context::file_format format,
+ boost::system::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 = boost::asio::error::invalid_argument;
+ return ec;
+ }
+ }
+
+ if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1)
+ {
+ ec = boost::system::error_code(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void context::use_rsa_private_key_file(
+ const std::string& filename, context::file_format format)
+{
+ boost::system::error_code ec;
+ use_rsa_private_key_file(filename, format, ec);
+ boost::asio::detail::throw_error(ec, "use_rsa_private_key_file");
+}
+
+boost::system::error_code context::use_rsa_private_key_file(
+ const std::string& filename, context::file_format format,
+ boost::system::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 = boost::asio::error::invalid_argument;
+ return ec;
+ }
+ }
+
+ if (::SSL_CTX_use_RSAPrivateKey_file(
+ handle_, filename.c_str(), file_type) != 1)
+ {
+ ec = boost::system::error_code(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void context::use_tmp_dh_file(const std::string& filename)
+{
+ boost::system::error_code ec;
+ use_tmp_dh_file(filename, ec);
+ boost::asio::detail::throw_error(ec, "use_tmp_dh_file");
+}
+
+boost::system::error_code context::use_tmp_dh_file(
+ const std::string& filename, boost::system::error_code& ec)
+{
+ ::BIO* bio = ::BIO_new_file(filename.c_str(), "r");
+ if (!bio)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0);
+ if (!dh)
+ {
+ ::BIO_free(bio);
+ ec = boost::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 = boost::system::error_code(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code context::do_set_password_callback(
+ detail::password_callback_base* callback, boost::system::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 = boost::system::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(BOOST_ASIO_ENABLE_OLD_SSL)
+
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_IMPL_CONTEXT_IPP

Modified: trunk/boost/asio/ssl/impl/src.hpp
==============================================================================
--- trunk/boost/asio/ssl/impl/src.hpp (original)
+++ trunk/boost/asio/ssl/impl/src.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -19,6 +19,9 @@
 # error Do not compile Asio library source with BOOST_ASIO_HEADER_ONLY defined
 #endif
 
+#include <boost/asio/ssl/impl/context.ipp>
 #include <boost/asio/ssl/impl/error.ipp>
+#include <boost/asio/ssl/detail/impl/engine.ipp>
+#include <boost/asio/ssl/detail/impl/openssl_init.ipp>
 
 #endif // BOOST_ASIO_IMPL_SRC_HPP

Added: trunk/boost/asio/ssl/old/basic_context.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/old/basic_context.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,436 @@
+//
+// ssl/old/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)
+//
+// 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 BOOST_ASIO_SSL_OLD_BASIC_CONTEXT_HPP
+#define BOOST_ASIO_SSL_OLD_BASIC_CONTEXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <string>
+#include <boost/noncopyable.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ssl/context_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace old {
+
+/// SSL context.
+template <typename Service>
+class basic_context
+ : public context_base,
+ private boost::noncopyable
+{
+public:
+ /// The type of the service that will be used to provide context operations.
+ typedef Service service_type;
+
+ /// The native implementation type of the locking dispatcher.
+ typedef typename service_type::impl_type impl_type;
+
+ /// Constructor.
+ basic_context(boost::asio::io_service& io_service, method m)
+ : service_(boost::asio::use_service<Service>(io_service)),
+ impl_(service_.null())
+ {
+ service_.create(impl_, m);
+ }
+
+ /// Destructor.
+ ~basic_context()
+ {
+ service_.destroy(impl_);
+ }
+
+ /// 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.
+ */
+ impl_type impl()
+ {
+ return impl_;
+ }
+
+ /// 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 boost::system::system_error Thrown on failure.
+ */
+ void set_options(options o)
+ {
+ boost::system::error_code ec;
+ service_.set_options(impl_, o, ec);
+ boost::asio::detail::throw_error(ec);
+ }
+
+ /// 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.
+ */
+ boost::system::error_code set_options(options o,
+ boost::system::error_code& ec)
+ {
+ return service_.set_options(impl_, o, 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 boost::system::system_error Thrown on failure.
+ */
+ void set_verify_mode(verify_mode v)
+ {
+ boost::system::error_code ec;
+ service_.set_verify_mode(impl_, v, ec);
+ boost::asio::detail::throw_error(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.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code set_verify_mode(verify_mode v,
+ boost::system::error_code& ec)
+ {
+ return service_.set_verify_mode(impl_, v, 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 boost::system::system_error Thrown on failure.
+ */
+ void load_verify_file(const std::string& filename)
+ {
+ boost::system::error_code ec;
+ service_.load_verify_file(impl_, filename, ec);
+ boost::asio::detail::throw_error(ec);
+ }
+
+ /// 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.
+ */
+ boost::system::error_code load_verify_file(const std::string& filename,
+ boost::system::error_code& ec)
+ {
+ return service_.load_verify_file(impl_, filename, 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 boost::system::system_error Thrown on failure.
+ */
+ void add_verify_path(const std::string& path)
+ {
+ boost::system::error_code ec;
+ service_.add_verify_path(impl_, path, ec);
+ boost::asio::detail::throw_error(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.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code add_verify_path(const std::string& path,
+ boost::system::error_code& ec)
+ {
+ return service_.add_verify_path(impl_, path, 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 boost::system::system_error Thrown on failure.
+ */
+ void use_certificate_file(const std::string& filename, file_format format)
+ {
+ boost::system::error_code ec;
+ service_.use_certificate_file(impl_, filename, format, ec);
+ boost::asio::detail::throw_error(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).
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code use_certificate_file(const std::string& filename,
+ file_format format, boost::system::error_code& ec)
+ {
+ return service_.use_certificate_file(impl_, filename, format, 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 boost::system::system_error Thrown on failure.
+ */
+ void use_certificate_chain_file(const std::string& filename)
+ {
+ boost::system::error_code ec;
+ service_.use_certificate_chain_file(impl_, filename, ec);
+ boost::asio::detail::throw_error(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.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code use_certificate_chain_file(
+ const std::string& filename, boost::system::error_code& ec)
+ {
+ return service_.use_certificate_chain_file(impl_, filename, 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 boost::system::system_error Thrown on failure.
+ */
+ void use_private_key_file(const std::string& filename, file_format format)
+ {
+ boost::system::error_code ec;
+ service_.use_private_key_file(impl_, filename, format, ec);
+ boost::asio::detail::throw_error(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).
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code use_private_key_file(const std::string& filename,
+ file_format format, boost::system::error_code& ec)
+ {
+ return service_.use_private_key_file(impl_, filename, format, 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 boost::system::system_error Thrown on failure.
+ */
+ void use_rsa_private_key_file(const std::string& filename, file_format format)
+ {
+ boost::system::error_code ec;
+ service_.use_rsa_private_key_file(impl_, filename, format, ec);
+ boost::asio::detail::throw_error(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).
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code use_rsa_private_key_file(
+ const std::string& filename, file_format format,
+ boost::system::error_code& ec)
+ {
+ return service_.use_rsa_private_key_file(impl_, filename, format, 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 boost::system::system_error Thrown on failure.
+ */
+ void use_tmp_dh_file(const std::string& filename)
+ {
+ boost::system::error_code ec;
+ service_.use_tmp_dh_file(impl_, filename, ec);
+ boost::asio::detail::throw_error(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.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code use_tmp_dh_file(const std::string& filename,
+ boost::system::error_code& ec)
+ {
+ return service_.use_tmp_dh_file(impl_, filename, 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 boost::system::system_error Thrown on failure.
+ */
+ template <typename PasswordCallback>
+ void set_password_callback(PasswordCallback callback)
+ {
+ boost::system::error_code ec;
+ service_.set_password_callback(impl_, callback, ec);
+ boost::asio::detail::throw_error(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.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ template <typename PasswordCallback>
+ boost::system::error_code set_password_callback(PasswordCallback callback,
+ boost::system::error_code& ec)
+ {
+ return service_.set_password_callback(impl_, callback, ec);
+ }
+
+private:
+ /// The backend service implementation.
+ service_type& service_;
+
+ /// The underlying native implementation.
+ impl_type impl_;
+};
+
+} // namespace old
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_OLD_BASIC_CONTEXT_HPP

Added: trunk/boost/asio/ssl/old/context_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/old/context_service.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,176 @@
+//
+// ssl/old/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)
+//
+// 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 BOOST_ASIO_SSL_OLD_CONTEXT_SERVICE_HPP
+#define BOOST_ASIO_SSL_OLD_CONTEXT_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <string>
+#include <boost/noncopyable.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ssl/context_base.hpp>
+#include <boost/asio/ssl/old/detail/openssl_context_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace old {
+
+/// Default service implementation for a context.
+class context_service
+#if defined(GENERATING_DOCUMENTATION)
+ : public boost::asio::io_service::service
+#else
+ : public boost::asio::detail::service_base<context_service>
+#endif
+{
+private:
+ // The type of the platform-specific implementation.
+ typedef old::detail::openssl_context_service service_impl_type;
+
+public:
+#if defined(GENERATING_DOCUMENTATION)
+ /// The unique service identifier.
+ static boost::asio::io_service::id id;
+#endif
+
+ /// The type of the context.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined impl_type;
+#else
+ typedef service_impl_type::impl_type impl_type;
+#endif
+
+ /// Constructor.
+ explicit context_service(boost::asio::io_service& io_service)
+ : boost::asio::detail::service_base<context_service>(io_service),
+ service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+ {
+ }
+
+ /// Return a null context implementation.
+ impl_type null() const
+ {
+ return service_impl_.null();
+ }
+
+ /// Create a new context implementation.
+ void create(impl_type& impl, context_base::method m)
+ {
+ service_impl_.create(impl, m);
+ }
+
+ /// Destroy a context implementation.
+ void destroy(impl_type& impl)
+ {
+ service_impl_.destroy(impl);
+ }
+
+ /// Set options on the context.
+ boost::system::error_code set_options(impl_type& impl,
+ context_base::options o, boost::system::error_code& ec)
+ {
+ return service_impl_.set_options(impl, o, ec);
+ }
+
+ /// Set peer verification mode.
+ boost::system::error_code set_verify_mode(impl_type& impl,
+ context_base::verify_mode v, boost::system::error_code& ec)
+ {
+ return service_impl_.set_verify_mode(impl, v, ec);
+ }
+
+ /// Load a certification authority file for performing verification.
+ boost::system::error_code load_verify_file(impl_type& impl,
+ const std::string& filename, boost::system::error_code& ec)
+ {
+ return service_impl_.load_verify_file(impl, filename, ec);
+ }
+
+ /// Add a directory containing certification authority files to be used for
+ /// performing verification.
+ boost::system::error_code add_verify_path(impl_type& impl,
+ const std::string& path, boost::system::error_code& ec)
+ {
+ return service_impl_.add_verify_path(impl, path, ec);
+ }
+
+ /// Use a certificate from a file.
+ boost::system::error_code use_certificate_file(impl_type& impl,
+ const std::string& filename, context_base::file_format format,
+ boost::system::error_code& ec)
+ {
+ return service_impl_.use_certificate_file(impl, filename, format, ec);
+ }
+
+ /// Use a certificate chain from a file.
+ boost::system::error_code use_certificate_chain_file(impl_type& impl,
+ const std::string& filename, boost::system::error_code& ec)
+ {
+ return service_impl_.use_certificate_chain_file(impl, filename, ec);
+ }
+
+ /// Use a private key from a file.
+ boost::system::error_code use_private_key_file(impl_type& impl,
+ const std::string& filename, context_base::file_format format,
+ boost::system::error_code& ec)
+ {
+ return service_impl_.use_private_key_file(impl, filename, format, ec);
+ }
+
+ /// Use an RSA private key from a file.
+ boost::system::error_code use_rsa_private_key_file(impl_type& impl,
+ const std::string& filename, context_base::file_format format,
+ boost::system::error_code& ec)
+ {
+ return service_impl_.use_rsa_private_key_file(impl, filename, format, ec);
+ }
+
+ /// Use the specified file to obtain the temporary Diffie-Hellman parameters.
+ boost::system::error_code use_tmp_dh_file(impl_type& impl,
+ const std::string& filename, boost::system::error_code& ec)
+ {
+ return service_impl_.use_tmp_dh_file(impl, filename, ec);
+ }
+
+ /// Set the password callback.
+ template <typename PasswordCallback>
+ boost::system::error_code set_password_callback(impl_type& impl,
+ PasswordCallback callback, boost::system::error_code& ec)
+ {
+ return service_impl_.set_password_callback(impl, callback, ec);
+ }
+
+private:
+ // Destroy all user-defined handler objects owned by the service.
+ void shutdown_service()
+ {
+ }
+
+ // The service that provides the platform-specific implementation.
+ service_impl_type& service_impl_;
+};
+
+} // namespace old
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_OLD_CONTEXT_SERVICE_HPP

Added: trunk/boost/asio/ssl/old/detail/openssl_context_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/old/detail/openssl_context_service.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,379 @@
+//
+// ssl/old/detail/openssl_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)
+//
+// 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 BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP
+#define BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstring>
+#include <string>
+#include <boost/function.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ssl/context_base.hpp>
+#include <boost/asio/ssl/detail/openssl_init.hpp>
+#include <boost/asio/ssl/detail/openssl_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace old {
+namespace detail {
+
+class openssl_context_service
+ : public boost::asio::detail::service_base<openssl_context_service>
+{
+public:
+ // The native type of the context.
+ typedef ::SSL_CTX* impl_type;
+
+ // The type for the password callback function object.
+ typedef boost::function<std::string(std::size_t,
+ context_base::password_purpose)> password_callback_type;
+
+ // Constructor.
+ openssl_context_service(boost::asio::io_service& io_service)
+ : boost::asio::detail::service_base<openssl_context_service>(io_service)
+ {
+ }
+
+ // Destroy all user-defined handler objects owned by the service.
+ void shutdown_service()
+ {
+ }
+
+ // Return a null context implementation.
+ static impl_type null()
+ {
+ return 0;
+ }
+
+ // Create a new context implementation.
+ void create(impl_type& impl, context_base::method m)
+ {
+ switch (m)
+ {
+ case context_base::sslv2:
+ impl = ::SSL_CTX_new(::SSLv2_method());
+ break;
+ case context_base::sslv2_client:
+ impl = ::SSL_CTX_new(::SSLv2_client_method());
+ break;
+ case context_base::sslv2_server:
+ impl = ::SSL_CTX_new(::SSLv2_server_method());
+ break;
+ case context_base::sslv3:
+ impl = ::SSL_CTX_new(::SSLv3_method());
+ break;
+ case context_base::sslv3_client:
+ impl = ::SSL_CTX_new(::SSLv3_client_method());
+ break;
+ case context_base::sslv3_server:
+ impl = ::SSL_CTX_new(::SSLv3_server_method());
+ break;
+ case context_base::tlsv1:
+ impl = ::SSL_CTX_new(::TLSv1_method());
+ break;
+ case context_base::tlsv1_client:
+ impl = ::SSL_CTX_new(::TLSv1_client_method());
+ break;
+ case context_base::tlsv1_server:
+ impl = ::SSL_CTX_new(::TLSv1_server_method());
+ break;
+ case context_base::sslv23:
+ impl = ::SSL_CTX_new(::SSLv23_method());
+ break;
+ case context_base::sslv23_client:
+ impl = ::SSL_CTX_new(::SSLv23_client_method());
+ break;
+ case context_base::sslv23_server:
+ impl = ::SSL_CTX_new(::SSLv23_server_method());
+ break;
+ default:
+ impl = ::SSL_CTX_new(0);
+ break;
+ }
+ }
+
+ // Destroy a context implementation.
+ void destroy(impl_type& impl)
+ {
+ if (impl != null())
+ {
+ if (impl->default_passwd_callback_userdata)
+ {
+ password_callback_type* callback =
+ static_cast<password_callback_type*>(
+ impl->default_passwd_callback_userdata);
+ delete callback;
+ impl->default_passwd_callback_userdata = 0;
+ }
+
+ ::SSL_CTX_free(impl);
+ impl = null();
+ }
+ }
+
+ // Set options on the context.
+ boost::system::error_code set_options(impl_type& impl,
+ context_base::options o, boost::system::error_code& ec)
+ {
+ ::SSL_CTX_set_options(impl, o);
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Set peer verification mode.
+ boost::system::error_code set_verify_mode(impl_type& impl,
+ context_base::verify_mode v, boost::system::error_code& ec)
+ {
+ ::SSL_CTX_set_verify(impl, v, 0);
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Load a certification authority file for performing verification.
+ boost::system::error_code load_verify_file(impl_type& impl,
+ const std::string& filename, boost::system::error_code& ec)
+ {
+ if (::SSL_CTX_load_verify_locations(impl, filename.c_str(), 0) != 1)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Add a directory containing certification authority files to be used for
+ // performing verification.
+ boost::system::error_code add_verify_path(impl_type& impl,
+ const std::string& path, boost::system::error_code& ec)
+ {
+ if (::SSL_CTX_load_verify_locations(impl, 0, path.c_str()) != 1)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Use a certificate from a file.
+ boost::system::error_code use_certificate_file(impl_type& impl,
+ const std::string& filename, context_base::file_format format,
+ boost::system::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 = boost::asio::error::invalid_argument;
+ return ec;
+ }
+ }
+
+ if (::SSL_CTX_use_certificate_file(impl, filename.c_str(), file_type) != 1)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Use a certificate chain from a file.
+ boost::system::error_code use_certificate_chain_file(impl_type& impl,
+ const std::string& filename, boost::system::error_code& ec)
+ {
+ if (::SSL_CTX_use_certificate_chain_file(impl, filename.c_str()) != 1)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Use a private key from a file.
+ boost::system::error_code use_private_key_file(impl_type& impl,
+ const std::string& filename, context_base::file_format format,
+ boost::system::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 = boost::asio::error::invalid_argument;
+ return ec;
+ }
+ }
+
+ if (::SSL_CTX_use_PrivateKey_file(impl, filename.c_str(), file_type) != 1)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Use an RSA private key from a file.
+ boost::system::error_code use_rsa_private_key_file(impl_type& impl,
+ const std::string& filename, context_base::file_format format,
+ boost::system::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 = boost::asio::error::invalid_argument;
+ return ec;
+ }
+ }
+
+ if (::SSL_CTX_use_RSAPrivateKey_file(
+ impl, filename.c_str(), file_type) != 1)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Use the specified file to obtain the temporary Diffie-Hellman parameters.
+ boost::system::error_code use_tmp_dh_file(impl_type& impl,
+ const std::string& filename, boost::system::error_code& ec)
+ {
+ ::BIO* bio = ::BIO_new_file(filename.c_str(), "r");
+ if (!bio)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0);
+ if (!dh)
+ {
+ ::BIO_free(bio);
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ::BIO_free(bio);
+ int result = ::SSL_CTX_set_tmp_dh(impl, dh);
+ ::DH_free(dh);
+ if (result != 1)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ static int password_callback(char* buf, int size, int purpose, void* data)
+ {
+ using namespace std; // For strncat and strlen.
+
+ if (data)
+ {
+ password_callback_type* callback =
+ static_cast<password_callback_type*>(data);
+ std::string passwd = (*callback)(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;
+ }
+
+ // Set the password callback.
+ template <typename Password_Callback>
+ boost::system::error_code set_password_callback(impl_type& impl,
+ Password_Callback callback, boost::system::error_code& ec)
+ {
+ // Allocate callback function object if not already present.
+ if (impl->default_passwd_callback_userdata)
+ {
+ password_callback_type* callback_function =
+ static_cast<password_callback_type*>(
+ impl->default_passwd_callback_userdata);
+ *callback_function = callback;
+ }
+ else
+ {
+ password_callback_type* callback_function =
+ new password_callback_type(callback);
+ impl->default_passwd_callback_userdata = callback_function;
+ }
+
+ // Set the password callback.
+ SSL_CTX_set_default_passwd_cb(impl,
+ &openssl_context_service::password_callback);
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+private:
+ // Ensure openssl is initialised.
+ boost::asio::ssl::detail::openssl_init<> init_;
+};
+
+} // namespace detail
+} // namespace old
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP

Added: trunk/boost/asio/ssl/old/detail/openssl_operation.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/old/detail/openssl_operation.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,526 @@
+//
+// ssl/old/detail/openssl_operation.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster 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 BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP
+#define BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/function.hpp>
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/placeholders.hpp>
+#include <boost/asio/ssl/detail/openssl_types.hpp>
+#include <boost/asio/ssl/error.hpp>
+#include <boost/asio/strand.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/asio/write.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace old {
+namespace detail {
+
+typedef boost::function<int (::SSL*)> ssl_primitive_func;
+typedef boost::function<void (const boost::system::error_code&, int)>
+ user_handler_func;
+
+// Network send_/recv buffer implementation
+//
+//
+class net_buffer
+{
+ static const int NET_BUF_SIZE = 16*1024 + 256; // SSL record size + spare
+
+ unsigned char buf_[NET_BUF_SIZE];
+ unsigned char* data_start_;
+ unsigned char* data_end_;
+
+public:
+ net_buffer()
+ {
+ data_start_ = data_end_ = buf_;
+ }
+ unsigned char* get_unused_start() { return data_end_; }
+ unsigned char* get_data_start() { return data_start_; }
+ size_t get_unused_len() { return (NET_BUF_SIZE - (data_end_ - buf_)); }
+ size_t get_data_len() { return (data_end_ - data_start_); }
+ void data_added(size_t count)
+ {
+ data_end_ += count;
+ data_end_ = data_end_ > (buf_ + NET_BUF_SIZE)?
+ (buf_ + NET_BUF_SIZE):
+ data_end_;
+ }
+ void data_removed(size_t count)
+ {
+ data_start_ += count;
+ if (data_start_ >= data_end_) reset();
+ }
+ void reset() { data_start_ = buf_; data_end_ = buf_; }
+ bool has_data() { return (data_start_ < data_end_); }
+}; // class net_buffer
+
+//
+// Operation class
+//
+//
+template <typename Stream>
+class openssl_operation
+{
+public:
+
+ // Constructor for asynchronous operations
+ openssl_operation(ssl_primitive_func primitive,
+ Stream& socket,
+ net_buffer& recv_buf,
+ SSL* session,
+ BIO* ssl_bio,
+ user_handler_func handler,
+ boost::asio::io_service::strand& strand
+ )
+ : primitive_(primitive)
+ , user_handler_(handler)
+ , strand_(&strand)
+ , recv_buf_(recv_buf)
+ , socket_(socket)
+ , ssl_bio_(ssl_bio)
+ , session_(session)
+ {
+ write_ = boost::bind(
+ &openssl_operation::do_async_write,
+ this, boost::arg<1>(), boost::arg<2>()
+ );
+ read_ = boost::bind(
+ &openssl_operation::do_async_read,
+ this
+ );
+ handler_= boost::bind(
+ &openssl_operation::async_user_handler,
+ this, boost::arg<1>(), boost::arg<2>()
+ );
+ }
+
+ // Constructor for synchronous operations
+ openssl_operation(ssl_primitive_func primitive,
+ Stream& socket,
+ net_buffer& recv_buf,
+ SSL* session,
+ BIO* ssl_bio)
+ : primitive_(primitive)
+ , strand_(0)
+ , recv_buf_(recv_buf)
+ , socket_(socket)
+ , ssl_bio_(ssl_bio)
+ , session_(session)
+ {
+ write_ = boost::bind(
+ &openssl_operation::do_sync_write,
+ this, boost::arg<1>(), boost::arg<2>()
+ );
+ read_ = boost::bind(
+ &openssl_operation::do_sync_read,
+ this
+ );
+ handler_ = boost::bind(
+ &openssl_operation::sync_user_handler,
+ this, boost::arg<1>(), boost::arg<2>()
+ );
+ }
+
+ // Start operation
+ // In case of asynchronous it returns 0, in sync mode returns success code
+ // or throws an error...
+ int start()
+ {
+ int rc = primitive_( session_ );
+
+ bool is_operation_done = (rc > 0);
+ // For connect/accept/shutdown, the operation
+ // is done, when return code is 1
+ // for write, it is done, when is retcode > 0
+ // for read, is is done when retcode > 0
+
+ int error_code = !is_operation_done ?
+ ::SSL_get_error( session_, rc ) :
+ 0;
+ int sys_error_code = ERR_get_error();
+
+ if (error_code == SSL_ERROR_SSL)
+ return handler_(boost::system::error_code(
+ sys_error_code, boost::asio::error::get_ssl_category()), rc);
+
+ bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
+ bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
+ ::BIO_ctrl_pending( ssl_bio_ ));
+ bool is_shut_down_received =
+ ((::SSL_get_shutdown( session_ ) & SSL_RECEIVED_SHUTDOWN) ==
+ SSL_RECEIVED_SHUTDOWN);
+ bool is_shut_down_sent =
+ ((::SSL_get_shutdown( session_ ) & SSL_SENT_SHUTDOWN) ==
+ SSL_SENT_SHUTDOWN);
+
+ if (is_shut_down_sent && is_shut_down_received
+ && is_operation_done && !is_write_needed)
+ // SSL connection is shut down cleanly
+ return handler_(boost::system::error_code(), 1);
+
+ if (is_shut_down_received && !is_operation_done)
+ // Shutdown has been requested, while we were reading or writing...
+ // abort our action...
+ return handler_(boost::asio::error::shut_down, 0);
+
+ if (!is_operation_done && !is_read_needed && !is_write_needed
+ && !is_shut_down_sent)
+ {
+ // The operation has failed... It is not completed and does
+ // not want network communication nor does want to send shutdown out...
+ if (error_code == SSL_ERROR_SYSCALL)
+ {
+ return handler_(boost::system::error_code(
+ sys_error_code, boost::asio::error::system_category), rc);
+ }
+ else
+ {
+ return handler_(boost::system::error_code(
+ sys_error_code, boost::asio::error::get_ssl_category()), rc);
+ }
+ }
+
+ if (!is_operation_done && !is_write_needed)
+ {
+ // We may have left over data that we can pass to SSL immediately
+ if (recv_buf_.get_data_len() > 0)
+ {
+ // Pass the buffered data to SSL
+ int written = ::BIO_write
+ (
+ ssl_bio_,
+ recv_buf_.get_data_start(),
+ recv_buf_.get_data_len()
+ );
+
+ if (written > 0)
+ {
+ recv_buf_.data_removed(written);
+ }
+ else if (written < 0)
+ {
+ if (!BIO_should_retry(ssl_bio_))
+ {
+ // Some serios error with BIO....
+ return handler_(boost::asio::error::no_recovery, 0);
+ }
+ }
+
+ return start();
+ }
+ else if (is_read_needed || (is_shut_down_sent && !is_shut_down_received))
+ {
+ return read_();
+ }
+ }
+
+ // Continue with operation, flush any SSL data out to network...
+ return write_(is_operation_done, rc);
+ }
+
+// Private implementation
+private:
+ typedef boost::function<int (const boost::system::error_code&, int)>
+ int_handler_func;
+ typedef boost::function<int (bool, int)> write_func;
+ typedef boost::function<int ()> read_func;
+
+ ssl_primitive_func primitive_;
+ user_handler_func user_handler_;
+ boost::asio::io_service::strand* strand_;
+ write_func write_;
+ read_func read_;
+ int_handler_func handler_;
+
+ net_buffer send_buf_; // buffers for network IO
+
+ // The recv buffer is owned by the stream, not the operation, since there can
+ // be left over bytes after passing the data up to the application, and these
+ // bytes need to be kept around for the next read operation issued by the
+ // application.
+ net_buffer& recv_buf_;
+
+ Stream& socket_;
+ BIO* ssl_bio_;
+ SSL* session_;
+
+ //
+ int sync_user_handler(const boost::system::error_code& error, int rc)
+ {
+ if (!error)
+ return rc;
+
+ throw boost::system::system_error(error);
+ }
+
+ int async_user_handler(boost::system::error_code error, int rc)
+ {
+ if (rc < 0)
+ {
+ if (!error)
+ error = boost::asio::error::no_recovery;
+ rc = 0;
+ }
+
+ user_handler_(error, rc);
+ return 0;
+ }
+
+ // Writes bytes asynchronously from SSL to NET
+ int do_async_write(bool is_operation_done, int rc)
+ {
+ int len = ::BIO_ctrl_pending( ssl_bio_ );
+ if ( len )
+ {
+ // There is something to write into net, do it...
+ len = (int)send_buf_.get_unused_len() > len?
+ len:
+ send_buf_.get_unused_len();
+
+ if (len == 0)
+ {
+ // In case our send buffer is full, we have just to wait until
+ // previous send to complete...
+ return 0;
+ }
+
+ // Read outgoing data from bio
+ len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len);
+
+ if (len > 0)
+ {
+ unsigned char *data_start = send_buf_.get_unused_start();
+ send_buf_.data_added(len);
+
+ BOOST_ASSERT(strand_);
+ boost::asio::async_write
+ (
+ socket_,
+ boost::asio::buffer(data_start, len),
+ strand_->wrap
+ (
+ boost::bind
+ (
+ &openssl_operation::async_write_handler,
+ this,
+ is_operation_done,
+ rc,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred
+ )
+ )
+ );
+
+ return 0;
+ }
+ else if (!BIO_should_retry(ssl_bio_))
+ {
+ // Seems like fatal error
+ // reading from SSL BIO has failed...
+ handler_(boost::asio::error::no_recovery, 0);
+ return 0;
+ }
+ }
+
+ if (is_operation_done)
+ {
+ // Finish the operation, with success
+ handler_(boost::system::error_code(), rc);
+ return 0;
+ }
+
+ // OPeration is not done and writing to net has been made...
+ // start operation again
+ start();
+
+ return 0;
+ }
+
+ void async_write_handler(bool is_operation_done, int rc,
+ const boost::system::error_code& error, size_t bytes_sent)
+ {
+ if (!error)
+ {
+ // Remove data from send buffer
+ send_buf_.data_removed(bytes_sent);
+
+ if (is_operation_done)
+ handler_(boost::system::error_code(), rc);
+ else
+ // Since the operation was not completed, try it again...
+ start();
+ }
+ else
+ handler_(error, rc);
+ }
+
+ int do_async_read()
+ {
+ // Wait for new data
+ BOOST_ASSERT(strand_);
+ socket_.async_read_some
+ (
+ boost::asio::buffer(recv_buf_.get_unused_start(),
+ recv_buf_.get_unused_len()),
+ strand_->wrap
+ (
+ boost::bind
+ (
+ &openssl_operation::async_read_handler,
+ this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred
+ )
+ )
+ );
+ return 0;
+ }
+
+ void async_read_handler(const boost::system::error_code& error,
+ size_t bytes_recvd)
+ {
+ if (!error)
+ {
+ recv_buf_.data_added(bytes_recvd);
+
+ // Pass the received data to SSL
+ int written = ::BIO_write
+ (
+ ssl_bio_,
+ recv_buf_.get_data_start(),
+ recv_buf_.get_data_len()
+ );
+
+ if (written > 0)
+ {
+ recv_buf_.data_removed(written);
+ }
+ else if (written < 0)
+ {
+ if (!BIO_should_retry(ssl_bio_))
+ {
+ // Some serios error with BIO....
+ handler_(boost::asio::error::no_recovery, 0);
+ return;
+ }
+ }
+
+ // and try the SSL primitive again
+ start();
+ }
+ else
+ {
+ // Error in network level...
+ // SSL can't continue either...
+ handler_(error, 0);
+ }
+ }
+
+ // Syncronous functions...
+ int do_sync_write(bool is_operation_done, int rc)
+ {
+ int len = ::BIO_ctrl_pending( ssl_bio_ );
+ if ( len )
+ {
+ // There is something to write into net, do it...
+ len = (int)send_buf_.get_unused_len() > len?
+ len:
+ send_buf_.get_unused_len();
+
+ // Read outgoing data from bio
+ len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len);
+
+ if (len > 0)
+ {
+ size_t sent_len = boost::asio::write(
+ socket_,
+ boost::asio::buffer(send_buf_.get_unused_start(), len)
+ );
+
+ send_buf_.data_added(len);
+ send_buf_.data_removed(sent_len);
+ }
+ else if (!BIO_should_retry(ssl_bio_))
+ {
+ // Seems like fatal error
+ // reading from SSL BIO has failed...
+ throw boost::system::system_error(boost::asio::error::no_recovery);
+ }
+ }
+
+ if (is_operation_done)
+ // Finish the operation, with success
+ return rc;
+
+ // Operation is not finished, start again.
+ return start();
+ }
+
+ int do_sync_read()
+ {
+ size_t len = socket_.read_some
+ (
+ boost::asio::buffer(recv_buf_.get_unused_start(),
+ recv_buf_.get_unused_len())
+ );
+
+ // Write data to ssl
+ recv_buf_.data_added(len);
+
+ // Pass the received data to SSL
+ int written = ::BIO_write
+ (
+ ssl_bio_,
+ recv_buf_.get_data_start(),
+ recv_buf_.get_data_len()
+ );
+
+ if (written > 0)
+ {
+ recv_buf_.data_removed(written);
+ }
+ else if (written < 0)
+ {
+ if (!BIO_should_retry(ssl_bio_))
+ {
+ // Some serios error with BIO....
+ throw boost::system::system_error(boost::asio::error::no_recovery);
+ }
+ }
+
+ // Try the operation again
+ return start();
+ }
+}; // class openssl_operation
+
+} // namespace detail
+} // namespace old
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP

Added: trunk/boost/asio/ssl/old/detail/openssl_stream_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/old/detail/openssl_stream_service.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,573 @@
+//
+// ssl/old/detail/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)
+//
+// 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 BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP
+#define BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <climits>
+#include <memory>
+#include <boost/config.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ssl/basic_context.hpp>
+#include <boost/asio/ssl/stream_base.hpp>
+#include <boost/asio/ssl/old/detail/openssl_operation.hpp>
+#include <boost/asio/ssl/detail/openssl_types.hpp>
+#include <boost/asio/strand.hpp>
+#include <boost/system/system_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace old {
+namespace detail {
+
+class openssl_stream_service
+ : public boost::asio::detail::service_base<openssl_stream_service>
+{
+private:
+ enum { max_buffer_size = INT_MAX };
+
+ //Base handler for asyncrhonous operations
+ template <typename Stream>
+ class base_handler
+ {
+ public:
+ typedef boost::function<
+ void (const boost::system::error_code&, size_t)> func_t;
+
+ base_handler(boost::asio::io_service& io_service)
+ : op_(NULL)
+ , io_service_(io_service)
+ , work_(io_service)
+ {}
+
+ void do_func(const boost::system::error_code& error, size_t size)
+ {
+ func_(error, size);
+ }
+
+ void set_operation(openssl_operation<Stream>* op) { op_ = op; }
+ void set_func(func_t func) { func_ = func; }
+
+ ~base_handler()
+ {
+ delete op_;
+ }
+
+ private:
+ func_t func_;
+ openssl_operation<Stream>* op_;
+ boost::asio::io_service& io_service_;
+ boost::asio::io_service::work work_;
+ }; // class base_handler
+
+ // Handler for asynchronous IO (write/read) operations
+ template<typename Stream, typename Handler>
+ class io_handler
+ : public base_handler<Stream>
+ {
+ public:
+ io_handler(Handler handler, boost::asio::io_service& io_service)
+ : base_handler<Stream>(io_service)
+ , handler_(handler)
+ {
+ this->set_func(boost::bind(
+ &io_handler<Stream, Handler>::handler_impl,
+ this, boost::arg<1>(), boost::arg<2>() ));
+ }
+
+ private:
+ Handler handler_;
+ void handler_impl(const boost::system::error_code& error, size_t size)
+ {
+ std::auto_ptr<io_handler<Stream, Handler> > this_ptr(this);
+ handler_(error, size);
+ }
+ }; // class io_handler
+
+ // Handler for asyncrhonous handshake (connect, accept) functions
+ template <typename Stream, typename Handler>
+ class handshake_handler
+ : public base_handler<Stream>
+ {
+ public:
+ handshake_handler(Handler handler, boost::asio::io_service& io_service)
+ : base_handler<Stream>(io_service)
+ , handler_(handler)
+ {
+ this->set_func(boost::bind(
+ &handshake_handler<Stream, Handler>::handler_impl,
+ this, boost::arg<1>(), boost::arg<2>() ));
+ }
+
+ private:
+ Handler handler_;
+ void handler_impl(const boost::system::error_code& error, size_t)
+ {
+ std::auto_ptr<handshake_handler<Stream, Handler> > this_ptr(this);
+ handler_(error);
+ }
+
+ }; // class handshake_handler
+
+ // Handler for asyncrhonous shutdown
+ template <typename Stream, typename Handler>
+ class shutdown_handler
+ : public base_handler<Stream>
+ {
+ public:
+ shutdown_handler(Handler handler, boost::asio::io_service& io_service)
+ : base_handler<Stream>(io_service),
+ handler_(handler)
+ {
+ this->set_func(boost::bind(
+ &shutdown_handler<Stream, Handler>::handler_impl,
+ this, boost::arg<1>(), boost::arg<2>() ));
+ }
+
+ private:
+ Handler handler_;
+ void handler_impl(const boost::system::error_code& error, size_t)
+ {
+ std::auto_ptr<shutdown_handler<Stream, Handler> > this_ptr(this);
+ handler_(error);
+ }
+ }; // class shutdown_handler
+
+public:
+ // The implementation type.
+ typedef struct impl_struct
+ {
+ ::SSL* ssl;
+ ::BIO* ext_bio;
+ net_buffer recv_buf;
+ } * impl_type;
+
+ // Construct a new stream socket service for the specified io_service.
+ explicit openssl_stream_service(boost::asio::io_service& io_service)
+ : boost::asio::detail::service_base<openssl_stream_service>(io_service),
+ strand_(io_service)
+ {
+ }
+
+ // Destroy all user-defined handler objects owned by the service.
+ void shutdown_service()
+ {
+ }
+
+ // Return a null stream implementation.
+ impl_type null() const
+ {
+ return 0;
+ }
+
+ // Create a new stream implementation.
+ template <typename Stream, typename Context_Service>
+ void create(impl_type& impl, Stream& /*next_layer*/,
+ basic_context<Context_Service>& context)
+ {
+ impl = new impl_struct;
+ impl->ssl = ::SSL_new(context.impl());
+ ::SSL_set_mode(impl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
+ ::SSL_set_mode(impl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+ ::BIO* int_bio = 0;
+ impl->ext_bio = 0;
+ ::BIO_new_bio_pair(&int_bio, 8192, &impl->ext_bio, 8192);
+ ::SSL_set_bio(impl->ssl, int_bio, int_bio);
+ }
+
+ // Destroy a stream implementation.
+ template <typename Stream>
+ void destroy(impl_type& impl, Stream& /*next_layer*/)
+ {
+ if (impl != 0)
+ {
+ ::BIO_free(impl->ext_bio);
+ ::SSL_free(impl->ssl);
+ delete impl;
+ impl = 0;
+ }
+ }
+
+ // Perform SSL handshaking.
+ template <typename Stream>
+ boost::system::error_code handshake(impl_type& impl, Stream& next_layer,
+ stream_base::handshake_type type, boost::system::error_code& ec)
+ {
+ try
+ {
+ openssl_operation<Stream> op(
+ type == stream_base::client ?
+ &ssl_wrap<mutex_type>::SSL_connect:
+ &ssl_wrap<mutex_type>::SSL_accept,
+ next_layer,
+ impl->recv_buf,
+ impl->ssl,
+ impl->ext_bio);
+ op.start();
+ }
+ catch (boost::system::system_error& e)
+ {
+ ec = e.code();
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Start an asynchronous SSL handshake.
+ template <typename Stream, typename Handler>
+ void async_handshake(impl_type& impl, Stream& next_layer,
+ stream_base::handshake_type type, Handler handler)
+ {
+ typedef handshake_handler<Stream, Handler> connect_handler;
+
+ connect_handler* local_handler =
+ new connect_handler(handler, get_io_service());
+
+ openssl_operation<Stream>* op = new openssl_operation<Stream>
+ (
+ type == stream_base::client ?
+ &ssl_wrap<mutex_type>::SSL_connect:
+ &ssl_wrap<mutex_type>::SSL_accept,
+ next_layer,
+ impl->recv_buf,
+ impl->ssl,
+ impl->ext_bio,
+ boost::bind
+ (
+ &base_handler<Stream>::do_func,
+ local_handler,
+ boost::arg<1>(),
+ boost::arg<2>()
+ ),
+ strand_
+ );
+ local_handler->set_operation(op);
+
+ strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
+ }
+
+ // Shut down SSL on the stream.
+ template <typename Stream>
+ boost::system::error_code shutdown(impl_type& impl, Stream& next_layer,
+ boost::system::error_code& ec)
+ {
+ try
+ {
+ openssl_operation<Stream> op(
+ &ssl_wrap<mutex_type>::SSL_shutdown,
+ next_layer,
+ impl->recv_buf,
+ impl->ssl,
+ impl->ext_bio);
+ op.start();
+ }
+ catch (boost::system::system_error& e)
+ {
+ ec = e.code();
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+ }
+
+ // Asynchronously shut down SSL on the stream.
+ template <typename Stream, typename Handler>
+ void async_shutdown(impl_type& impl, Stream& next_layer, Handler handler)
+ {
+ typedef shutdown_handler<Stream, Handler> disconnect_handler;
+
+ disconnect_handler* local_handler =
+ new disconnect_handler(handler, get_io_service());
+
+ openssl_operation<Stream>* op = new openssl_operation<Stream>
+ (
+ &ssl_wrap<mutex_type>::SSL_shutdown,
+ next_layer,
+ impl->recv_buf,
+ impl->ssl,
+ impl->ext_bio,
+ boost::bind
+ (
+ &base_handler<Stream>::do_func,
+ local_handler,
+ boost::arg<1>(),
+ boost::arg<2>()
+ ),
+ strand_
+ );
+ local_handler->set_operation(op);
+
+ strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
+ }
+
+ // Write some data to the stream.
+ template <typename Stream, typename Const_Buffers>
+ std::size_t write_some(impl_type& impl, Stream& next_layer,
+ const Const_Buffers& buffers, boost::system::error_code& ec)
+ {
+ size_t bytes_transferred = 0;
+ try
+ {
+ boost::asio::const_buffer buffer =
+ boost::asio::detail::buffer_sequence_adapter<
+ boost::asio::const_buffer, Const_Buffers>::first(buffers);
+
+ std::size_t buffer_size = boost::asio::buffer_size(buffer);
+ if (buffer_size > max_buffer_size)
+ buffer_size = max_buffer_size;
+ else if (buffer_size == 0)
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ boost::function<int (SSL*)> send_func =
+ boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
+ boost::asio::buffer_cast<const void*>(buffer),
+ static_cast<int>(buffer_size));
+ openssl_operation<Stream> op(
+ send_func,
+ next_layer,
+ impl->recv_buf,
+ impl->ssl,
+ impl->ext_bio
+ );
+ bytes_transferred = static_cast<size_t>(op.start());
+ }
+ catch (boost::system::system_error& e)
+ {
+ ec = e.code();
+ return 0;
+ }
+
+ ec = boost::system::error_code();
+ return bytes_transferred;
+ }
+
+ // Start an asynchronous write.
+ template <typename Stream, typename Const_Buffers, typename Handler>
+ void async_write_some(impl_type& impl, Stream& next_layer,
+ const Const_Buffers& buffers, Handler handler)
+ {
+ typedef io_handler<Stream, Handler> send_handler;
+
+ boost::asio::const_buffer buffer =
+ boost::asio::detail::buffer_sequence_adapter<
+ boost::asio::const_buffer, Const_Buffers>::first(buffers);
+
+ std::size_t buffer_size = boost::asio::buffer_size(buffer);
+ if (buffer_size > max_buffer_size)
+ buffer_size = max_buffer_size;
+ else if (buffer_size == 0)
+ {
+ get_io_service().post(boost::asio::detail::bind_handler(
+ handler, boost::system::error_code(), 0));
+ return;
+ }
+
+ send_handler* local_handler = new send_handler(handler, get_io_service());
+
+ boost::function<int (SSL*)> send_func =
+ boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
+ boost::asio::buffer_cast<const void*>(buffer),
+ static_cast<int>(buffer_size));
+
+ openssl_operation<Stream>* op = new openssl_operation<Stream>
+ (
+ send_func,
+ next_layer,
+ impl->recv_buf,
+ impl->ssl,
+ impl->ext_bio,
+ boost::bind
+ (
+ &base_handler<Stream>::do_func,
+ local_handler,
+ boost::arg<1>(),
+ boost::arg<2>()
+ ),
+ strand_
+ );
+ local_handler->set_operation(op);
+
+ strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
+ }
+
+ // Read some data from the stream.
+ template <typename Stream, typename Mutable_Buffers>
+ std::size_t read_some(impl_type& impl, Stream& next_layer,
+ const Mutable_Buffers& buffers, boost::system::error_code& ec)
+ {
+ size_t bytes_transferred = 0;
+ try
+ {
+ boost::asio::mutable_buffer buffer =
+ boost::asio::detail::buffer_sequence_adapter<
+ boost::asio::mutable_buffer, Mutable_Buffers>::first(buffers);
+
+ std::size_t buffer_size = boost::asio::buffer_size(buffer);
+ if (buffer_size > max_buffer_size)
+ buffer_size = max_buffer_size;
+ else if (buffer_size == 0)
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ boost::function<int (SSL*)> recv_func =
+ boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
+ boost::asio::buffer_cast<void*>(buffer),
+ static_cast<int>(buffer_size));
+ openssl_operation<Stream> op(recv_func,
+ next_layer,
+ impl->recv_buf,
+ impl->ssl,
+ impl->ext_bio
+ );
+
+ bytes_transferred = static_cast<size_t>(op.start());
+ }
+ catch (boost::system::system_error& e)
+ {
+ ec = e.code();
+ return 0;
+ }
+
+ ec = boost::system::error_code();
+ return bytes_transferred;
+ }
+
+ // Start an asynchronous read.
+ template <typename Stream, typename Mutable_Buffers, typename Handler>
+ void async_read_some(impl_type& impl, Stream& next_layer,
+ const Mutable_Buffers& buffers, Handler handler)
+ {
+ typedef io_handler<Stream, Handler> recv_handler;
+
+ boost::asio::mutable_buffer buffer =
+ boost::asio::detail::buffer_sequence_adapter<
+ boost::asio::mutable_buffer, Mutable_Buffers>::first(buffers);
+
+ std::size_t buffer_size = boost::asio::buffer_size(buffer);
+ if (buffer_size > max_buffer_size)
+ buffer_size = max_buffer_size;
+ else if (buffer_size == 0)
+ {
+ get_io_service().post(boost::asio::detail::bind_handler(
+ handler, boost::system::error_code(), 0));
+ return;
+ }
+
+ recv_handler* local_handler = new recv_handler(handler, get_io_service());
+
+ boost::function<int (SSL*)> recv_func =
+ boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
+ boost::asio::buffer_cast<void*>(buffer),
+ static_cast<int>(buffer_size));
+
+ openssl_operation<Stream>* op = new openssl_operation<Stream>
+ (
+ recv_func,
+ next_layer,
+ impl->recv_buf,
+ impl->ssl,
+ impl->ext_bio,
+ boost::bind
+ (
+ &base_handler<Stream>::do_func,
+ local_handler,
+ boost::arg<1>(),
+ boost::arg<2>()
+ ),
+ strand_
+ );
+ local_handler->set_operation(op);
+
+ strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
+ }
+
+ // Peek at the incoming data on the stream.
+ template <typename Stream, typename Mutable_Buffers>
+ std::size_t peek(impl_type& /*impl*/, Stream& /*next_layer*/,
+ const Mutable_Buffers& /*buffers*/, boost::system::error_code& ec)
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ // Determine the amount of data that may be read without blocking.
+ template <typename Stream>
+ std::size_t in_avail(impl_type& /*impl*/, Stream& /*next_layer*/,
+ boost::system::error_code& ec)
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+private:
+ boost::asio::io_service::strand strand_;
+
+ typedef boost::asio::detail::mutex mutex_type;
+
+ template<typename Mutex>
+ struct ssl_wrap
+ {
+ static Mutex ssl_mutex_;
+
+ static int SSL_accept(SSL *ssl)
+ {
+ typename Mutex::scoped_lock lock(ssl_mutex_);
+ return ::SSL_accept(ssl);
+ }
+
+ static int SSL_connect(SSL *ssl)
+ {
+ typename Mutex::scoped_lock lock(ssl_mutex_);
+ return ::SSL_connect(ssl);
+ }
+
+ static int SSL_shutdown(SSL *ssl)
+ {
+ typename Mutex::scoped_lock lock(ssl_mutex_);
+ return ::SSL_shutdown(ssl);
+ }
+ };
+};
+
+template<typename Mutex>
+Mutex openssl_stream_service::ssl_wrap<Mutex>::ssl_mutex_;
+
+} // namespace detail
+} // namespace old
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP

Added: trunk/boost/asio/ssl/old/stream.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/old/stream.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,503 @@
+//
+// ssl/old/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)
+//
+// 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 BOOST_ASIO_SSL_OLD_STREAM_HPP
+#define BOOST_ASIO_SSL_OLD_STREAM_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/noncopyable.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/ssl/basic_context.hpp>
+#include <boost/asio/ssl/stream_base.hpp>
+#include <boost/asio/ssl/stream_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace old {
+
+/// 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._at_n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Example
+ * To use the SSL stream template with an ip::tcp::socket, you would write:
+ * @code
+ * boost::asio::io_service io_service;
+ * boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
+ * boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sock(io_service, context);
+ * @endcode
+ *
+ * @par Concepts:
+ * AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream.
+ */
+template <typename Stream, typename Service = old::stream_service>
+class stream
+ : public stream_base,
+ private boost::noncopyable
+{
+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;
+
+ /// The type of the service that will be used to provide stream operations.
+ typedef Service service_type;
+
+ /// The native implementation type of the stream.
+ typedef typename service_type::impl_type impl_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, typename Context_Service>
+ explicit stream(Arg& arg, basic_context<Context_Service>& context)
+ : next_layer_(arg),
+ service_(boost::asio::use_service<Service>(next_layer_.get_io_service())),
+ impl_(service_.null())
+ {
+ service_.create(impl_, next_layer_, context);
+ }
+
+ /// Destructor.
+ ~stream()
+ {
+ service_.destroy(impl_, next_layer_);
+ }
+
+ /// 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.
+ */
+ boost::asio::io_service& get_io_service()
+ {
+ return next_layer_.get_io_service();
+ }
+
+ /// 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 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 next_layer_.lowest_layer();
+ }
+
+ /// Get a const reference to the lowest layer.
+ /**
+ * This function returns a const reference to the lowest layer in a stack of
+ * stream layers.
+ *
+ * @return A const 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 next_layer_.lowest_layer();
+ }
+
+ /// 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 stream functionality that is
+ * not otherwise provided.
+ */
+ impl_type impl()
+ {
+ return impl_;
+ }
+
+ /// 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 boost::system::system_error Thrown on failure.
+ */
+ void handshake(handshake_type type)
+ {
+ boost::system::error_code ec;
+ service_.handshake(impl_, next_layer_, type, ec);
+ boost::asio::detail::throw_error(ec);
+ }
+
+ /// 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.
+ */
+ boost::system::error_code handshake(handshake_type type,
+ boost::system::error_code& ec)
+ {
+ return service_.handshake(impl_, next_layer_, type, 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 boost::system::error_code& error // Result of operation.
+ * ); @endcode
+ */
+ template <typename HandshakeHandler>
+ void async_handshake(handshake_type type, HandshakeHandler handler)
+ {
+ service_.async_handshake(impl_, next_layer_, type, handler);
+ }
+
+ /// 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 boost::system::system_error Thrown on failure.
+ */
+ void shutdown()
+ {
+ boost::system::error_code ec;
+ service_.shutdown(impl_, next_layer_, ec);
+ boost::asio::detail::throw_error(ec);
+ }
+
+ /// 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.
+ */
+ boost::system::error_code shutdown(boost::system::error_code& ec)
+ {
+ return service_.shutdown(impl_, next_layer_, 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 boost::system::error_code& error // Result of operation.
+ * ); @endcode
+ */
+ template <typename ShutdownHandler>
+ void async_shutdown(ShutdownHandler handler)
+ {
+ service_.async_shutdown(impl_, next_layer_, handler);
+ }
+
+ /// 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 boost::system::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)
+ {
+ boost::system::error_code ec;
+ std::size_t s = service_.write_some(impl_, next_layer_, buffers, ec);
+ boost::asio::detail::throw_error(ec);
+ return s;
+ }
+
+ /// 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,
+ boost::system::error_code& ec)
+ {
+ return service_.write_some(impl_, next_layer_, buffers, ec);
+ }
+
+ /// 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 boost::system::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)
+ {
+ service_.async_write_some(impl_, next_layer_, buffers, handler);
+ }
+
+ /// 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 boost::system::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)
+ {
+ boost::system::error_code ec;
+ std::size_t s = service_.read_some(impl_, next_layer_, buffers, ec);
+ boost::asio::detail::throw_error(ec);
+ return s;
+ }
+
+ /// 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,
+ boost::system::error_code& ec)
+ {
+ return service_.read_some(impl_, next_layer_, buffers, ec);
+ }
+
+ /// 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 boost::system::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)
+ {
+ service_.async_read_some(impl_, next_layer_, buffers, handler);
+ }
+
+ /// Peek at the incoming data on the stream.
+ /**
+ * This function is used to peek at the incoming data on the stream, without
+ * removing it from the input queue. The function call will block until data
+ * has been read successfully or an error occurs.
+ *
+ * @param buffers The buffers into which the data will be read.
+ *
+ * @returns The number of bytes read.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t peek(const MutableBufferSequence& buffers)
+ {
+ boost::system::error_code ec;
+ std::size_t s = service_.peek(impl_, next_layer_, buffers, ec);
+ boost::asio::detail::throw_error(ec);
+ return s;
+ }
+
+ /// Peek at the incoming data on the stream.
+ /**
+ * This function is used to peek at the incoming data on the stream, withoutxi
+ * removing it from the input queue. The function call will block until data
+ * has been read successfully or 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.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t peek(const MutableBufferSequence& buffers,
+ boost::system::error_code& ec)
+ {
+ return service_.peek(impl_, next_layer_, buffers, ec);
+ }
+
+ /// Determine the amount of data that may be read without blocking.
+ /**
+ * This function is used to determine the amount of data, in bytes, that may
+ * be read from the stream without blocking.
+ *
+ * @returns The number of bytes of data that can be read without blocking.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ std::size_t in_avail()
+ {
+ boost::system::error_code ec;
+ std::size_t s = service_.in_avail(impl_, next_layer_, ec);
+ boost::asio::detail::throw_error(ec);
+ return s;
+ }
+
+ /// Determine the amount of data that may be read without blocking.
+ /**
+ * This function is used to determine the amount of data, in bytes, that may
+ * be read from the stream without blocking.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes of data that can be read without blocking.
+ */
+ std::size_t in_avail(boost::system::error_code& ec)
+ {
+ return service_.in_avail(impl_, next_layer_, ec);
+ }
+
+private:
+ /// The next layer.
+ Stream next_layer_;
+
+ /// The backend service implementation.
+ service_type& service_;
+
+ /// The underlying native implementation.
+ impl_type impl_;
+};
+
+} // namespace old
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_OLD_STREAM_HPP

Added: trunk/boost/asio/ssl/old/stream_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ssl/old/stream_service.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,186 @@
+//
+// ssl/old/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)
+//
+// 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 BOOST_ASIO_SSL_OLD_STREAM_SERVICE_HPP
+#define BOOST_ASIO_SSL_OLD_STREAM_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/noncopyable.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ssl/basic_context.hpp>
+#include <boost/asio/ssl/old/detail/openssl_stream_service.hpp>
+#include <boost/asio/ssl/stream_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ssl {
+namespace old {
+
+/// Default service implementation for an SSL stream.
+class stream_service
+#if defined(GENERATING_DOCUMENTATION)
+ : public boost::asio::io_service::service
+#else
+ : public boost::asio::detail::service_base<stream_service>
+#endif
+{
+private:
+ // The type of the platform-specific implementation.
+ typedef old::detail::openssl_stream_service service_impl_type;
+
+public:
+#if defined(GENERATING_DOCUMENTATION)
+ /// The unique service identifier.
+ static boost::asio::io_service::id id;
+#endif
+
+ /// The type of a stream implementation.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined impl_type;
+#else
+ typedef service_impl_type::impl_type impl_type;
+#endif
+
+ /// Construct a new stream service for the specified io_service.
+ explicit stream_service(boost::asio::io_service& io_service)
+ : boost::asio::detail::service_base<stream_service>(io_service),
+ service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+ {
+ }
+
+ /// Return a null stream implementation.
+ impl_type null() const
+ {
+ return service_impl_.null();
+ }
+
+ /// Create a new stream implementation.
+ template <typename Stream, typename Context_Service>
+ void create(impl_type& impl, Stream& next_layer,
+ basic_context<Context_Service>& context)
+ {
+ service_impl_.create(impl, next_layer, context);
+ }
+
+ /// Destroy a stream implementation.
+ template <typename Stream>
+ void destroy(impl_type& impl, Stream& next_layer)
+ {
+ service_impl_.destroy(impl, next_layer);
+ }
+
+ /// Perform SSL handshaking.
+ template <typename Stream>
+ boost::system::error_code handshake(impl_type& impl, Stream& next_layer,
+ stream_base::handshake_type type, boost::system::error_code& ec)
+ {
+ return service_impl_.handshake(impl, next_layer, type, ec);
+ }
+
+ /// Start an asynchronous SSL handshake.
+ template <typename Stream, typename HandshakeHandler>
+ void async_handshake(impl_type& impl, Stream& next_layer,
+ stream_base::handshake_type type, HandshakeHandler handler)
+ {
+ service_impl_.async_handshake(impl, next_layer, type, handler);
+ }
+
+ /// Shut down SSL on the stream.
+ template <typename Stream>
+ boost::system::error_code shutdown(impl_type& impl, Stream& next_layer,
+ boost::system::error_code& ec)
+ {
+ return service_impl_.shutdown(impl, next_layer, ec);
+ }
+
+ /// Asynchronously shut down SSL on the stream.
+ template <typename Stream, typename ShutdownHandler>
+ void async_shutdown(impl_type& impl, Stream& next_layer,
+ ShutdownHandler handler)
+ {
+ service_impl_.async_shutdown(impl, next_layer, handler);
+ }
+
+ /// Write some data to the stream.
+ template <typename Stream, typename ConstBufferSequence>
+ std::size_t write_some(impl_type& impl, Stream& next_layer,
+ const ConstBufferSequence& buffers, boost::system::error_code& ec)
+ {
+ return service_impl_.write_some(impl, next_layer, buffers, ec);
+ }
+
+ /// Start an asynchronous write.
+ template <typename Stream, typename ConstBufferSequence,
+ typename WriteHandler>
+ void async_write_some(impl_type& impl, Stream& next_layer,
+ const ConstBufferSequence& buffers, WriteHandler handler)
+ {
+ service_impl_.async_write_some(impl, next_layer, buffers, handler);
+ }
+
+ /// Read some data from the stream.
+ template <typename Stream, typename MutableBufferSequence>
+ std::size_t read_some(impl_type& impl, Stream& next_layer,
+ const MutableBufferSequence& buffers, boost::system::error_code& ec)
+ {
+ return service_impl_.read_some(impl, next_layer, buffers, ec);
+ }
+
+ /// Start an asynchronous read.
+ template <typename Stream, typename MutableBufferSequence,
+ typename ReadHandler>
+ void async_read_some(impl_type& impl, Stream& next_layer,
+ const MutableBufferSequence& buffers, ReadHandler handler)
+ {
+ service_impl_.async_read_some(impl, next_layer, buffers, handler);
+ }
+
+ /// Peek at the incoming data on the stream.
+ template <typename Stream, typename MutableBufferSequence>
+ std::size_t peek(impl_type& impl, Stream& next_layer,
+ const MutableBufferSequence& buffers, boost::system::error_code& ec)
+ {
+ return service_impl_.peek(impl, next_layer, buffers, ec);
+ }
+
+ /// Determine the amount of data that may be read without blocking.
+ template <typename Stream>
+ std::size_t in_avail(impl_type& impl, Stream& next_layer,
+ boost::system::error_code& ec)
+ {
+ return service_impl_.in_avail(impl, next_layer, ec);
+ }
+
+private:
+ // Destroy all user-defined handler objects owned by the service.
+ void shutdown_service()
+ {
+ }
+
+ // The service that provides the platform-specific implementation.
+ service_impl_type& service_impl_;
+};
+
+} // namespace old
+} // namespace ssl
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SSL_OLD_STREAM_SERVICE_HPP

Modified: trunk/boost/asio/ssl/stream.hpp
==============================================================================
--- trunk/boost/asio/ssl/stream.hpp (original)
+++ trunk/boost/asio/ssl/stream.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -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)
@@ -17,14 +16,23 @@
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
 #include <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/noncopyable.hpp>
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/ssl/basic_context.hpp>
-#include <boost/asio/ssl/stream_base.hpp>
-#include <boost/asio/ssl/stream_service.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/old/stream.hpp>
+#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/detail/buffer_sequence_adapter.hpp>
+# include <boost/asio/detail/handler_type_requirements.hpp>
+# include <boost/asio/detail/noncopyable.hpp>
+# include <boost/asio/ssl/context.hpp>
+# include <boost/asio/ssl/detail/handshake_op.hpp>
+# include <boost/asio/ssl/detail/io.hpp>
+# include <boost/asio/ssl/detail/read_op.hpp>
+# include <boost/asio/ssl/detail/shutdown_op.hpp>
+# include <boost/asio/ssl/detail/stream_core.hpp>
+# include <boost/asio/ssl/detail/write_op.hpp>
+# include <boost/asio/ssl/stream_base.hpp>
+# include <boost/type_traits/remove_reference.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
 #include <boost/asio/detail/push_options.hpp>
 
@@ -32,6 +40,12 @@
 namespace asio {
 namespace ssl {
 
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+using boost::asio::ssl::old::stream;
+
+#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
 /// Provides stream-oriented functionality using SSL.
 /**
  * The stream class template provides asynchronous and blocking stream-oriented
@@ -39,37 +53,36 @@
  *
  * @par Thread Safety
  * @e Distinct @e objects: Safe._at_n
- * @e Shared @e objects: Unsafe.
+ * @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
  * boost::asio::io_service io_service;
- * boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
- * boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sock(io_service, context);
+ * boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
+ * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(io_service, ctx);
  * @endcode
  *
  * @par Concepts:
- * AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream.
+ * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
  */
-template <typename Stream, typename Service = stream_service>
-class stream
- : public stream_base,
- private boost::noncopyable
+template <typename Stream>
+class stream :
+ public stream_base,
+ private noncopyable
 {
 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;
 
- /// The type of the service that will be used to provide stream operations.
- typedef Service service_type;
-
- /// The native implementation type of the stream.
- typedef typename service_type::impl_type impl_type;
-
   /// Construct a stream.
   /**
    * This constructor creates a stream and initialises the underlying stream
@@ -79,19 +92,16 @@
    *
    * @param context The SSL context to be used for the stream.
    */
- template <typename Arg, typename Context_Service>
- explicit stream(Arg& arg, basic_context<Context_Service>& context)
+ template <typename Arg>
+ stream(Arg& arg, context& ctx)
     : next_layer_(arg),
- service_(boost::asio::use_service<Service>(next_layer_.get_io_service())),
- impl_(service_.null())
+ core_(ctx.native_handle(), next_layer_.lowest_layer().get_io_service())
   {
- service_.create(impl_, next_layer_, context);
   }
 
   /// Destructor.
   ~stream()
   {
- service_.destroy(impl_, next_layer_);
   }
 
   /// Get the io_service associated with the object.
@@ -104,7 +114,31 @@
    */
   boost::asio::io_service& get_io_service()
   {
- return next_layer_.get_io_service();
+ return next_layer_.lowest_layer().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 core_.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 next_layer_;
   }
 
   /// Get a reference to the next layer.
@@ -133,30 +167,19 @@
     return next_layer_.lowest_layer();
   }
 
- /// Get a const reference to the lowest layer.
+ /// Get a reference to the lowest layer.
   /**
- * This function returns a const reference to the lowest layer in a stack of
+ * This function returns a reference to the lowest layer in a stack of
    * stream layers.
    *
- * @return A const reference to the lowest layer in the stack of stream
- * layers. Ownership is not transferred to the caller.
+ * @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 next_layer_.lowest_layer();
   }
 
- /// 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 stream functionality that is
- * not otherwise provided.
- */
- impl_type impl()
- {
- return impl_;
- }
-
   /// Perform SSL handshaking.
   /**
    * This function is used to perform SSL handshaking on the stream. The
@@ -170,8 +193,8 @@
   void handshake(handshake_type type)
   {
     boost::system::error_code ec;
- service_.handshake(impl_, next_layer_, type, ec);
- boost::asio::detail::throw_error(ec);
+ handshake(type, ec);
+ boost::asio::detail::throw_error(ec, "handshake");
   }
 
   /// Perform SSL handshaking.
@@ -187,7 +210,8 @@
   boost::system::error_code handshake(handshake_type type,
       boost::system::error_code& ec)
   {
- return service_.handshake(impl_, next_layer_, type, ec);
+ detail::io(next_layer_, core_, detail::handshake_op(type), ec);
+ return ec;
   }
 
   /// Start an asynchronous SSL handshake.
@@ -206,9 +230,14 @@
    * ); @endcode
    */
   template <typename HandshakeHandler>
- void async_handshake(handshake_type type, HandshakeHandler handler)
+ void async_handshake(handshake_type type,
+ HandshakeHandler handler)
   {
- service_.async_handshake(impl_, next_layer_, type, handler);
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a HandshakeHandler.
+ BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
+
+ detail::async_io(next_layer_, core_, detail::handshake_op(type), handler);
   }
 
   /// Shut down SSL on the stream.
@@ -221,8 +250,8 @@
   void shutdown()
   {
     boost::system::error_code ec;
- service_.shutdown(impl_, next_layer_, ec);
- boost::asio::detail::throw_error(ec);
+ shutdown(ec);
+ boost::asio::detail::throw_error(ec, "shutdown");
   }
 
   /// Shut down SSL on the stream.
@@ -234,7 +263,8 @@
    */
   boost::system::error_code shutdown(boost::system::error_code& ec)
   {
- return service_.shutdown(impl_, next_layer_, ec);
+ detail::io(next_layer_, core_, detail::shutdown_op(), ec);
+ return ec;
   }
 
   /// Asynchronously shut down SSL on the stream.
@@ -252,7 +282,11 @@
   template <typename ShutdownHandler>
   void async_shutdown(ShutdownHandler handler)
   {
- service_.async_shutdown(impl_, next_layer_, handler);
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a ShutdownHandler.
+ BOOST_ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check;
+
+ detail::async_io(next_layer_, core_, detail::shutdown_op(), handler);
   }
 
   /// Write some data to the stream.
@@ -275,9 +309,9 @@
   std::size_t write_some(const ConstBufferSequence& buffers)
   {
     boost::system::error_code ec;
- std::size_t s = service_.write_some(impl_, next_layer_, buffers, ec);
- boost::asio::detail::throw_error(ec);
- return s;
+ std::size_t n = write_some(buffers, ec);
+ boost::asio::detail::throw_error(ec, "write_some");
+ return n;
   }
 
   /// Write some data to the stream.
@@ -300,7 +334,8 @@
   std::size_t write_some(const ConstBufferSequence& buffers,
       boost::system::error_code& ec)
   {
- return service_.write_some(impl_, next_layer_, buffers, ec);
+ return detail::io(next_layer_, core_,
+ detail::write_op<ConstBufferSequence>(buffers), ec);
   }
 
   /// Start an asynchronous write.
@@ -329,7 +364,12 @@
   void async_write_some(const ConstBufferSequence& buffers,
       WriteHandler handler)
   {
- service_.async_write_some(impl_, next_layer_, buffers, handler);
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::async_io(next_layer_, core_,
+ detail::write_op<ConstBufferSequence>(buffers), handler);
   }
 
   /// Read some data from the stream.
@@ -352,9 +392,9 @@
   std::size_t read_some(const MutableBufferSequence& buffers)
   {
     boost::system::error_code ec;
- std::size_t s = service_.read_some(impl_, next_layer_, buffers, ec);
- boost::asio::detail::throw_error(ec);
- return s;
+ std::size_t n = read_some(buffers, ec);
+ boost::asio::detail::throw_error(ec, "read_some");
+ return n;
   }
 
   /// Read some data from the stream.
@@ -377,7 +417,8 @@
   std::size_t read_some(const MutableBufferSequence& buffers,
       boost::system::error_code& ec)
   {
- return service_.read_some(impl_, next_layer_, buffers, ec);
+ return detail::io(next_layer_, core_,
+ detail::read_op<MutableBufferSequence>(buffers), ec);
   }
 
   /// Start an asynchronous read.
@@ -407,91 +448,21 @@
   void async_read_some(const MutableBufferSequence& buffers,
       ReadHandler handler)
   {
- service_.async_read_some(impl_, next_layer_, buffers, handler);
- }
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
 
- /// Peek at the incoming data on the stream.
- /**
- * This function is used to peek at the incoming data on the stream, without
- * removing it from the input queue. The function call will block until data
- * has been read successfully or an error occurs.
- *
- * @param buffers The buffers into which the data will be read.
- *
- * @returns The number of bytes read.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- template <typename MutableBufferSequence>
- std::size_t peek(const MutableBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = service_.peek(impl_, next_layer_, buffers, ec);
- boost::asio::detail::throw_error(ec);
- return s;
- }
-
- /// Peek at the incoming data on the stream.
- /**
- * This function is used to peek at the incoming data on the stream, withoutxi
- * removing it from the input queue. The function call will block until data
- * has been read successfully or 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.
- */
- template <typename MutableBufferSequence>
- std::size_t peek(const MutableBufferSequence& buffers,
- boost::system::error_code& ec)
- {
- return service_.peek(impl_, next_layer_, buffers, ec);
- }
-
- /// Determine the amount of data that may be read without blocking.
- /**
- * This function is used to determine the amount of data, in bytes, that may
- * be read from the stream without blocking.
- *
- * @returns The number of bytes of data that can be read without blocking.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- std::size_t in_avail()
- {
- boost::system::error_code ec;
- std::size_t s = service_.in_avail(impl_, next_layer_, ec);
- boost::asio::detail::throw_error(ec);
- return s;
- }
-
- /// Determine the amount of data that may be read without blocking.
- /**
- * This function is used to determine the amount of data, in bytes, that may
- * be read from the stream without blocking.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes of data that can be read without blocking.
- */
- std::size_t in_avail(boost::system::error_code& ec)
- {
- return service_.in_avail(impl_, next_layer_, ec);
+ detail::async_io(next_layer_, core_,
+ detail::read_op<MutableBufferSequence>(buffers), handler);
   }
 
 private:
- /// The next layer.
   Stream next_layer_;
-
- /// The backend service implementation.
- service_type& service_;
-
- /// The underlying native implementation.
- impl_type impl_;
+ detail::stream_core core_;
 };
 
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
 } // namespace ssl
 } // namespace asio
 } // namespace boost

Modified: trunk/boost/asio/ssl/stream_base.hpp
==============================================================================
--- trunk/boost/asio/ssl/stream_base.hpp (original)
+++ trunk/boost/asio/ssl/stream_base.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -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)

Modified: trunk/boost/asio/ssl/stream_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/stream_service.hpp (original)
+++ trunk/boost/asio/ssl/stream_service.hpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -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)
@@ -17,12 +16,10 @@
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
 #include <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/noncopyable.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/ssl/basic_context.hpp>
-#include <boost/asio/ssl/detail/openssl_stream_service.hpp>
-#include <boost/asio/ssl/stream_base.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/ssl/old/stream_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
 #include <boost/asio/detail/push_options.hpp>
 
@@ -30,150 +27,11 @@
 namespace asio {
 namespace ssl {
 
-/// Default service implementation for an SSL stream.
-class stream_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_service::service
-#else
- : public boost::asio::detail::service_base<stream_service>
-#endif
-{
-private:
- // The type of the platform-specific implementation.
- typedef detail::openssl_stream_service service_impl_type;
-
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_service::id id;
-#endif
-
- /// The type of a stream implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined impl_type;
-#else
- typedef service_impl_type::impl_type impl_type;
-#endif
-
- /// Construct a new stream service for the specified io_service.
- explicit stream_service(boost::asio::io_service& io_service)
- : boost::asio::detail::service_base<stream_service>(io_service),
- service_impl_(boost::asio::use_service<service_impl_type>(io_service))
- {
- }
-
- /// Return a null stream implementation.
- impl_type null() const
- {
- return service_impl_.null();
- }
-
- /// Create a new stream implementation.
- template <typename Stream, typename Context_Service>
- void create(impl_type& impl, Stream& next_layer,
- basic_context<Context_Service>& context)
- {
- service_impl_.create(impl, next_layer, context);
- }
-
- /// Destroy a stream implementation.
- template <typename Stream>
- void destroy(impl_type& impl, Stream& next_layer)
- {
- service_impl_.destroy(impl, next_layer);
- }
-
- /// Perform SSL handshaking.
- template <typename Stream>
- boost::system::error_code handshake(impl_type& impl, Stream& next_layer,
- stream_base::handshake_type type, boost::system::error_code& ec)
- {
- return service_impl_.handshake(impl, next_layer, type, ec);
- }
-
- /// Start an asynchronous SSL handshake.
- template <typename Stream, typename HandshakeHandler>
- void async_handshake(impl_type& impl, Stream& next_layer,
- stream_base::handshake_type type, HandshakeHandler handler)
- {
- service_impl_.async_handshake(impl, next_layer, type, handler);
- }
-
- /// Shut down SSL on the stream.
- template <typename Stream>
- boost::system::error_code shutdown(impl_type& impl, Stream& next_layer,
- boost::system::error_code& ec)
- {
- return service_impl_.shutdown(impl, next_layer, ec);
- }
-
- /// Asynchronously shut down SSL on the stream.
- template <typename Stream, typename ShutdownHandler>
- void async_shutdown(impl_type& impl, Stream& next_layer,
- ShutdownHandler handler)
- {
- service_impl_.async_shutdown(impl, next_layer, handler);
- }
-
- /// Write some data to the stream.
- template <typename Stream, typename ConstBufferSequence>
- std::size_t write_some(impl_type& impl, Stream& next_layer,
- const ConstBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.write_some(impl, next_layer, buffers, ec);
- }
-
- /// Start an asynchronous write.
- template <typename Stream, typename ConstBufferSequence,
- typename WriteHandler>
- void async_write_some(impl_type& impl, Stream& next_layer,
- const ConstBufferSequence& buffers, WriteHandler handler)
- {
- service_impl_.async_write_some(impl, next_layer, buffers, handler);
- }
-
- /// Read some data from the stream.
- template <typename Stream, typename MutableBufferSequence>
- std::size_t read_some(impl_type& impl, Stream& next_layer,
- const MutableBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.read_some(impl, next_layer, buffers, ec);
- }
-
- /// Start an asynchronous read.
- template <typename Stream, typename MutableBufferSequence,
- typename ReadHandler>
- void async_read_some(impl_type& impl, Stream& next_layer,
- const MutableBufferSequence& buffers, ReadHandler handler)
- {
- service_impl_.async_read_some(impl, next_layer, buffers, handler);
- }
-
- /// Peek at the incoming data on the stream.
- template <typename Stream, typename MutableBufferSequence>
- std::size_t peek(impl_type& impl, Stream& next_layer,
- const MutableBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.peek(impl, next_layer, buffers, ec);
- }
-
- /// Determine the amount of data that may be read without blocking.
- template <typename Stream>
- std::size_t in_avail(impl_type& impl, Stream& next_layer,
- boost::system::error_code& ec)
- {
- return service_impl_.in_avail(impl, next_layer, ec);
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- }
-
- // The service that provides the platform-specific implementation.
- service_impl_type& service_impl_;
-};
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
+
+using boost::asio::ssl::old::stream_service;
+
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
 } // namespace ssl
 } // namespace asio

Modified: trunk/libs/asio/doc/quickref.xml
==============================================================================
--- trunk/libs/asio/doc/quickref.xml (original)
+++ trunk/libs/asio/doc/quickref.xml 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -308,13 +308,12 @@
           </simplelist>
           <bridgehead renderas="sect3">Class Templates</bridgehead>
           <simplelist type="vert" columns="1">
- <member><link linkend="boost_asio.reference.ssl__basic_context">ssl::basic_context</link></member>
             <member><link linkend="boost_asio.reference.ssl__stream">ssl::stream</link></member>
           </simplelist>
- <bridgehead renderas="sect3">Services</bridgehead>
+ <bridgehead renderas="sect3">Type Requirements</bridgehead>
           <simplelist type="vert" columns="1">
- <member><link linkend="boost_asio.reference.ssl__context_service">ssl::context_service</link></member>
- <member><link linkend="boost_asio.reference.ssl__stream_service">ssl::stream_service</link></member>
+ <member><link linkend="boost_asio.reference.HandshakeHandler">HandshakeHandler</link></member>
+ <member><link linkend="boost_asio.reference.ShutdownHandler">ShutdownHandler</link></member>
           </simplelist>
         </entry>
         <entry valign="top">

Modified: trunk/libs/asio/doc/reference.xsl
==============================================================================
--- trunk/libs/asio/doc/reference.xsl (original)
+++ trunk/libs/asio/doc/reference.xsl 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -55,6 +55,7 @@
 [include requirements/GettableSocketOption.qbk]
 [include requirements/Handler.qbk]
 [include requirements/HandleService.qbk]
+[include requirements/HandshakeHandler.qbk]
 [include requirements/InternetProtocol.qbk]
 [include requirements/IoControlCommand.qbk]
 [include requirements/IoObjectService.qbk]
@@ -70,6 +71,7 @@
 [include requirements/Service.qbk]
 [include requirements/SettableSerialPortOption.qbk]
 [include requirements/SettableSocketOption.qbk]
+[include requirements/ShutdownHandler.qbk]
 [include requirements/SignalHandler.qbk]
 [include requirements/SignalSetService.qbk]
 [include requirements/SocketAcceptorService.qbk]
@@ -1300,9 +1302,6 @@
         <xsl:when test="declname = 'Function'">
           <xsl:value-of select="declname"/>
         </xsl:when>
- <xsl:when test="declname = 'HandshakeHandler'">
- <xsl:value-of select="declname"/>
- </xsl:when>
         <xsl:when test="declname = 'Iterator'">
           <xsl:value-of select="declname"/>
         </xsl:when>
@@ -1321,9 +1320,6 @@
         <xsl:when test="declname = 'PointerToPodType'">
           <xsl:value-of select="declname"/>
         </xsl:when>
- <xsl:when test="declname = 'ShutdownHandler'">
- <xsl:value-of select="declname"/>
- </xsl:when>
         <xsl:when test="declname = 'SocketService1' or declname = 'SocketService2'">
           <xsl:value-of select="concat('``[link boost_asio.reference.SocketService ', declname, ']``')"/>
         </xsl:when>

Added: trunk/libs/asio/doc/requirements/HandshakeHandler.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/asio/doc/requirements/HandshakeHandler.qbk 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,50 @@
+[/
+ / 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)
+ /]
+
+[section:HandshakeHandler SSL handshake handler requirements]
+
+A handshake handler must meet the requirements for a [link
+boost_asio.reference.Handler handler]. A value `h` of a handshake handler
+class should work correctly in the expression `h(ec)`, where `ec` is an lvalue
+of type `const error_code`.
+
+[heading Examples]
+
+A free function as a handshake handler:
+
+ void handshake_handler(
+ const boost::system::error_code& ec)
+ {
+ ...
+ }
+
+A handshake handler function object:
+
+ struct handshake_handler
+ {
+ ...
+ void operator()(
+ const boost::system::error_code& ec)
+ {
+ ...
+ }
+ ...
+ };
+
+A non-static class member function adapted to a handshake handler using `bind()`:
+
+ void my_class::handshake_handler(
+ const boost::system::error_code& ec)
+ {
+ ...
+ }
+ ...
+ ssl_stream.async_handshake(...,
+ boost::bind(&my_class::handshake_handler,
+ this, boost::asio::placeholders::error));
+
+[endsect]

Added: trunk/libs/asio/doc/requirements/ShutdownHandler.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/asio/doc/requirements/ShutdownHandler.qbk 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -0,0 +1,50 @@
+[/
+ / 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)
+ /]
+
+[section:ShutdownHandler SSL shutdown handler requirements]
+
+A shutdown handler must meet the requirements for a [link
+boost_asio.reference.Handler handler]. A value `h` of a shutdown handler
+class should work correctly in the expression `h(ec)`, where `ec` is an lvalue
+of type `const error_code`.
+
+[heading Examples]
+
+A free function as a shutdown handler:
+
+ void shutdown_handler(
+ const boost::system::error_code& ec)
+ {
+ ...
+ }
+
+A shutdown handler function object:
+
+ struct shutdown_handler
+ {
+ ...
+ void operator()(
+ const boost::system::error_code& ec)
+ {
+ ...
+ }
+ ...
+ };
+
+A non-static class member function adapted to a shutdown handler using `bind()`:
+
+ void my_class::shutdown_handler(
+ const boost::system::error_code& ec)
+ {
+ ...
+ }
+ ...
+ ssl_stream.async_shutdown(
+ boost::bind(&my_class::shutdown_handler,
+ this, boost::asio::placeholders::error));
+
+[endsect]

Modified: trunk/libs/asio/example/ssl/client.cpp
==============================================================================
--- trunk/libs/asio/example/ssl/client.cpp (original)
+++ trunk/libs/asio/example/ssl/client.cpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -19,7 +19,8 @@
 class client
 {
 public:
- client(boost::asio::io_service& io_service, boost::asio::ssl::context& context,
+ client(boost::asio::io_service& io_service,
+ boost::asio::ssl::context& context,
       boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
     : socket_(io_service, context)
   {
@@ -116,7 +117,7 @@
     boost::asio::ip::tcp::resolver::query query(argv[1], argv[2]);
     boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
 
- boost::asio::ssl::context ctx(io_service, boost::asio::ssl::context::sslv23);
+ boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
     ctx.set_verify_mode(boost::asio::ssl::context::verify_peer);
     ctx.load_verify_file("ca.pem");
 

Modified: trunk/libs/asio/example/ssl/server.cpp
==============================================================================
--- trunk/libs/asio/example/ssl/server.cpp (original)
+++ trunk/libs/asio/example/ssl/server.cpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -19,7 +19,8 @@
 class session
 {
 public:
- session(boost::asio::io_service& io_service, boost::asio::ssl::context& context)
+ session(boost::asio::io_service& io_service,
+ boost::asio::ssl::context& context)
     : socket_(io_service, context)
   {
   }
@@ -95,7 +96,7 @@
     : io_service_(io_service),
       acceptor_(io_service,
           boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
- context_(io_service, boost::asio::ssl::context::sslv23)
+ context_(boost::asio::ssl::context::sslv23)
   {
     context_.set_options(
         boost::asio::ssl::context::default_workarounds

Modified: trunk/libs/asio/test/buffer.cpp
==============================================================================
--- trunk/libs/asio/test/buffer.cpp (original)
+++ trunk/libs/asio/test/buffer.cpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -41,6 +41,11 @@
     boost::array<char, 1024> array_data;
     const boost::array<char, 1024>& const_array_data_1 = array_data;
     boost::array<const char, 1024> const_array_data_2 = { { 0 } };
+#if defined(BOOST_ASIO_HAS_STD_ARRAY)
+ std::array<char, 1024> std_array_data;
+ const std::array<char, 1024>& const_std_array_data_1 = std_array_data;
+ std::array<const char, 1024> const_std_array_data_2 = { { 0 } };
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
     std::vector<char> vector_data(1024);
     const std::vector<char>& const_vector_data = vector_data;
     const std::string string_data(1024, ' ');
@@ -134,6 +139,14 @@
     cb1 = buffer(const_array_data_1, 1024);
     cb1 = buffer(const_array_data_2);
     cb1 = buffer(const_array_data_2, 1024);
+#if defined(BOOST_ASIO_HAS_STD_ARRAY)
+ mb1 = buffer(std_array_data);
+ mb1 = buffer(std_array_data, 1024);
+ cb1 = buffer(const_std_array_data_1);
+ cb1 = buffer(const_std_array_data_1, 1024);
+ cb1 = buffer(const_std_array_data_2);
+ cb1 = buffer(const_std_array_data_2, 1024);
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
     mb1 = buffer(vector_data);
     mb1 = buffer(vector_data, 1024);
     cb1 = buffer(const_vector_data);

Modified: trunk/libs/asio/test/ssl/stream.cpp
==============================================================================
--- trunk/libs/asio/test/ssl/stream.cpp (original)
+++ trunk/libs/asio/test/ssl/stream.cpp 2011-03-17 20:25:54 EDT (Thu, 17 Mar 2011)
@@ -106,6 +106,7 @@
 
     stream1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
 
+#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
     stream1.peek(buffer(mutable_char_buffer));
     stream1.peek(buffer(mutable_char_buffer), ec);
 
@@ -113,6 +114,7 @@
     (void)in_avail1;
     std::size_t in_avail2 = stream1.in_avail(ec);
     (void)in_avail2;
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
   }
   catch (std::exception&)
   {


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk