summaryrefslogtreecommitdiff
path: root/ACE/ace/SSL/SSL_Asynch_Stream.h
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/SSL/SSL_Asynch_Stream.h')
-rw-r--r--ACE/ace/SSL/SSL_Asynch_Stream.h425
1 files changed, 425 insertions, 0 deletions
diff --git a/ACE/ace/SSL/SSL_Asynch_Stream.h b/ACE/ace/SSL/SSL_Asynch_Stream.h
new file mode 100644
index 00000000000..671cca46c24
--- /dev/null
+++ b/ACE/ace/SSL/SSL_Asynch_Stream.h
@@ -0,0 +1,425 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file SSL_Asynch_Stream.h
+ *
+ * $Id$
+ *
+ * @author Alexander Libman <alibman@baltimore.com>
+ */
+//=============================================================================
+
+#ifndef ACE_SSL_ASYNCH_STREAM_H
+#define ACE_SSL_ASYNCH_STREAM_H
+
+#include /**/ "ace/pre.h"
+#include "SSL_Context.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)))
+
+#include "SSL_Asynch_BIO.h"
+
+#include "ace/Asynch_IO_Impl.h"
+#include "ace/Message_Block.h"
+#include "ace/Synch_Traits.h"
+#include "ace/Thread_Mutex.h"
+
+/*
+ * This facility doesn't follow the normal ACE asynch I/O support classes'
+ * interface/implementation arrangement. It's not needed because rather than
+ * branching off to platform-specific APIs, all platforms use the OpenSSL
+ * API. Thus, you can think of this class as the implementation class (for
+ * OpenSSL) and there's no separate interface class.
+ * Also, since both read and write operations are defined in one I/O
+ * factory, there's no single Result class defined as there is for
+ * ACE_Asynch_Read_Stream, et al. There are separate result classes defined
+ * for read and write operations.
+ */
+
+#if defined (ACE_WIN32)
+# include "ace/WIN32_Asynch_IO.h"
+typedef ACE_WIN32_Asynch_Result A_RESULT;
+typedef ACE_WIN32_Asynch_Read_Stream_Result ARS_RESULT;
+typedef ACE_WIN32_Asynch_Write_Stream_Result AWS_RESULT;
+
+# define ERR_CANCELED ERROR_OPERATION_ABORTED
+
+#else
+# include "ace/POSIX_Asynch_IO.h"
+typedef ACE_POSIX_Asynch_Result A_RESULT;
+typedef ACE_POSIX_Asynch_Read_Stream_Result ARS_RESULT;
+typedef ACE_POSIX_Asynch_Write_Stream_Result AWS_RESULT;
+
+# define ERR_CANCELED ECANCELED
+
+#endif /* ACE_WIN32 */
+
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class ACE_SSL_Asynch_Stream; // Forward decl for use in result class def.
+
+/**
+ * @class ACE_SSL_Asynch_Read_Stream_Result
+ *
+ * Result class that communicates result of read operations initiated on
+ * an ACE_SSL_Asynch_Stream object.
+ */
+class ACE_SSL_Asynch_Read_Stream_Result : public ARS_RESULT
+{
+ /// Factory class will have special permissions.
+ friend class ACE_SSL_Asynch_Stream;
+
+protected:
+ ACE_SSL_Asynch_Read_Stream_Result (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ ACE_Message_Block &message_block,
+ size_t bytes_to_read,
+ const void* act,
+ ACE_HANDLE event,
+ int priority,
+ int signal_number);
+};
+
+/**
+ * @class ACE_SSL_Asynch_Write_Stream_Result
+ *
+ * Result class that communicates result of write operations initiated on
+ * an ACE_SSL_Asynch_Stream object.
+ */
+class ACE_SSL_Asynch_Write_Stream_Result : public AWS_RESULT
+{
+ /// Factory class will have special permissions.
+ friend class ACE_SSL_Asynch_Stream;
+
+protected:
+ ACE_SSL_Asynch_Write_Stream_Result (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ ACE_Message_Block &message_block,
+ size_t bytes_to_read,
+ const void* act,
+ ACE_HANDLE event,
+ int priority,
+ int signal_number);
+};
+
+
+/**
+ * @class ACE_SSL_Asynch_Result
+ *
+ * Result class that is used internally for socket close notifications.
+ */
+class ACE_SSL_Asynch_Result : public A_RESULT
+{
+public:
+ ACE_SSL_Asynch_Result (ACE_Handler &handler);
+
+ void complete (size_t bytes_transferred,
+ int success,
+ const void * completion_key,
+ u_long error);
+};
+
+
+// Only provide forward declarations to prevent possible abuse of the
+// friend declarations in ACE_SSL_Asynch_Stream.
+struct ACE_SSL_Asynch_Stream_Accessor;
+
+/**
+ * @class ACE_SSL_Asynch_Stream
+ *
+ * @brief This class is a factory for initiating asynchronous reads
+ * and writes on an SSL stream.
+ *
+ * Once open() is called, multiple asynchronous read and write operations
+ * can be started using this class. The handler object (derived from
+ * ACE_Handler) specified in open() will receive completion events for the
+ * operations initiated via this class.
+ */
+class ACE_SSL_Export ACE_SSL_Asynch_Stream
+ : public ACE_Asynch_Operation,
+ public ACE_Handler
+{
+public:
+
+ // Use a class/struct to work around scoping
+ // problems for extern "C" free functions with some compilers. For
+ // example, some can't handle
+ //
+ // friend ::some_extern_c_free_function (...)
+ //
+ // Note that we could use a straight C++ (i.e. not extern "C") free
+ // function, but using a class or struct allows us to hide the
+ // interface from the user, which prevents abuse of this friend
+ // relationship.
+ friend struct ACE_SSL_Asynch_Stream_Accessor;
+
+ enum Stream_Type
+ {
+ ST_CLIENT = 0x0001,
+ ST_SERVER = 0x0002
+ };
+
+ /// Constructor.
+ /**
+ * @arg context Pointer to an ACE_SSL_Context instance containing
+ * the OpenSSL information to be associated with this
+ * ACE_SSL_Asynch_Stream. The needed SSL data will be
+ * copied before return. Therefore, this object can be
+ * reused, modified, or deleted upon return. If a 0 pointer
+ * is passed, the ACE_SSL_Context::instance() method will
+ * be called to get access to a singleton.
+ */
+ ACE_SSL_Asynch_Stream (Stream_Type s_type = ST_SERVER,
+ ACE_SSL_Context * context = 0);
+
+ /// Destructor
+ virtual ~ACE_SSL_Asynch_Stream (void);
+
+ int cancel (void);
+
+ int close (void);
+
+ /**
+ * Initializes the factory with information which will be used with
+ * each asynchronous call.
+ *
+ * @arg handler The ACE_Handler that will be called to handle completions
+ * for operations initiated using this factory.
+ * @arg handle The handle that future read/write operations will use.
+ *
+ * @retval 0 for success.
+ * @retval -1 for failure; consult @c errno for further information.
+ */
+ int open (ACE_Handler &handler,
+ ACE_HANDLE handle = ACE_INVALID_HANDLE,
+ const void *completion_key = 0,
+ ACE_Proactor *proactor = 0);
+
+ /**
+ * Initiates an asynchronous read. If the operation is successfully
+ * initiated, the handle_read_stream() method will be called on the
+ * ACE_Handler object passed to open() when the operation completes.
+ * Data is read into the specified ACE_Message_Block beginning at its
+ * write pointer; the block's write pointer is updated to reflect any
+ * added data when the operation completes.
+ *
+ * @arg message_block The specified ACE_Message_Block will receive any
+ * data that is read. Data will be read into the
+ * block beginning at the block's write pointer.
+ * @arg num_bytes_to_read The maximum number of bytes to read. The actual
+ * amount read may be less.
+ * @arg act ACT which is passed to the completion handler in
+ * the result object.
+ * @arg priority Specifies the operation priority. This has an
+ * affect on POSIX only. Works like @i nice in Unix.
+ * Negative values are not allowed. 0 means priority
+ * of the operation same as the process priority.
+ * 1 means priority of the operation is one less than
+ * process, and so forth. This parameter has no
+ * affect on Win32.
+ * @arg signal_number The POSIX4 real-time signal number to be used
+ * for the operation. signal_number ranges from
+ * ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is
+ * unused on non-POSIX4 systems.
+ *
+ * @retval 0 for success.
+ * @retval -1 for failure; consult @c errno for further information.
+ */
+ int read (ACE_Message_Block &message_block,
+ size_t num_bytes_to_read,
+ const void *act = 0,
+ int priority = 0,
+ int signal_number = ACE_SIGRTMIN);
+
+ /**
+ * Initiates an asynchronous write. If the operation is successfully
+ * initiated, the handle_write_stream() method will be called on the
+ * ACE_Handler object passed to open() when the operation completes.
+ * Data is taken from the specified ACE_Message_Block beginning at its
+ * read pointer; the block's read pointer is updated to reflect any
+ * data successfully sent when the operation completes.
+ *
+ * @arg message_block The specified ACE_Message_Block is the source of
+ * data that is written. Data will be taken from the
+ * block beginning at the block's read pointer.
+ * @arg bytes_to_write The maximum number of bytes to write. The actual
+ * amount written may be less.
+ * @arg act ACT which is passed to the completion handler in
+ * the result object.
+ * @arg priority Specifies the operation priority. This has an
+ * affect on POSIX only. Works like @i nice in Unix.
+ * Negative values are not allowed. 0 means priority
+ * of the operation same as the process priority.
+ * 1 means priority of the operation is one less than
+ * process, and so forth. This parameter has no
+ * affect on Win32.
+ * @arg signal_number The POSIX4 real-time signal number to be used
+ * for the operation. signal_number ranges from
+ * ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is
+ * unused on non-POSIX4 systems.
+ *
+ * @retval 0 for success.
+ * @retval -1 for failure; consult @c errno for further information.
+ */
+ int write (ACE_Message_Block &message_block,
+ size_t bytes_to_write,
+ const void *act = 0,
+ int priority = 0,
+ int signal_number = ACE_SIGRTMIN);
+
+protected:
+ /// Virtual from ACE_Asynch_Operation. Since this class is essentially an
+ /// implementation class, simply return 0.
+ virtual ACE_Asynch_Operation_Impl *implementation (void) const { return 0; }
+
+ /// virtual from ACE_Handler
+
+ /// This method is called when BIO write request is completed. It
+ /// processes the IO completion and calls do_SSL_state_machine().
+ virtual void handle_write_stream
+ (const ACE_Asynch_Write_Stream::Result &result);
+
+ /// This method is called when BIO read request is completed. It
+ /// processes the IO completion and calls do_SSL_state_machine().
+ virtual void handle_read_stream
+ (const ACE_Asynch_Read_Stream::Result &result);
+
+ /// This method is called when all SSL sessions are closed and no
+ /// more pending AIOs exist. It also calls users handle_wakeup().
+ virtual void handle_wakeup (void);
+
+ /**
+ * @name SSL State Machine
+ */
+ //@{
+ int do_SSL_state_machine (void);
+ int do_SSL_handshake (void);
+ int do_SSL_read (void);
+ int do_SSL_write(void);
+ int do_SSL_shutdown(void);
+ //@}
+
+ void print_error (int err_ssl,
+ const ACE_TCHAR *pText);
+
+ int pending_BIO_count (void);
+
+ /// This method is called to notify user handler when user's read in
+ /// done.
+ int notify_read (int bytes_transferred, int error);
+
+ /// This method is called to notify user handler when user's write
+ /// in done.
+ int notify_write (int bytes_transferred, int error);
+
+ /// This method is called to notify ourself that SSL session is
+ /// shutdown and that there is no more I/O activity now and in the
+ /// future.
+ int notify_close(void);
+
+ /**
+ * @name BIO Helpers
+ */
+ //@{
+ int ssl_bio_read (char * buf, size_t len, int & errval);
+ int ssl_bio_write (const char * buf, size_t len, int & errval);
+ //@}
+
+private:
+
+ // Preventing copying through construction or assignment.
+ ACE_SSL_Asynch_Stream (ACE_SSL_Asynch_Stream const &);
+ ACE_SSL_Asynch_Stream & operator= (ACE_SSL_Asynch_Stream const &);
+
+protected:
+
+ /// Stream Type ST_CLIENT/ST_SERVER
+ Stream_Type type_;
+
+ /// The real file/socket handle
+ ACE_HANDLE handle_;
+
+ /// The proactor
+ ACE_Proactor * proactor_;
+
+ /// External,i.e user handler
+ ACE_Handler * ext_handler_;
+
+ /// External, i.e. read result faked for user
+ ACE_SSL_Asynch_Read_Stream_Result * ext_read_result_ ;
+
+ /// External, i.e. write result faked for user
+ ACE_SSL_Asynch_Write_Stream_Result * ext_write_result_ ;
+
+ /// Stream state/flags
+ enum Stream_Flag
+ {
+ /// istream_ open OK
+ SF_STREAM_OPEN = 0x0001,
+ /// request to SSL shutdown
+ SF_REQ_SHUTDOWN = 0x0002,
+ /// SSL shutdown finished
+ SF_SHUTDOWN_DONE = 0x0004,
+ /// Close notification sent
+ SF_CLOSE_NTF_SENT = 0x0008,
+ /// Stream can be safely destroyed
+ SF_DELETE_ENABLE = 0x0010
+ };
+
+ int flags_;
+
+ /// The SSL session.
+ SSL * ssl_;
+
+ /// The BIO implementation
+ BIO * bio_;
+
+ /// The real streams which work under the ssl connection.
+ /// BIO performs I/O via this streams
+ enum BIO_Flag // internal IO flags
+ {
+ /// End of stream
+ BF_EOS = 0x01,
+ /// Real AIO in progress
+ BF_AIO = 0x02
+ };
+
+ /**
+ * @name Internal stream, buffer and info for BIO read
+ */
+ //@{
+ ACE_Asynch_Read_Stream bio_istream_;
+ ACE_Message_Block bio_inp_msg_;
+ int bio_inp_errno_;
+ int bio_inp_flag_;
+ //@}
+
+ /**
+ * @name Internal stream, buffer and info for BIO write
+ */
+ //@{
+ ACE_Asynch_Write_Stream bio_ostream_;
+ ACE_Message_Block bio_out_msg_;
+ int bio_out_errno_;
+ int bio_out_flag_;
+ //@}
+
+ /// Mutex to protect work
+ ACE_SYNCH_MUTEX mutex_;
+
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
+ ACE_HAS_AIO_CALLS) */
+
+#include /**/ "ace/post.h"
+
+#endif /* ACE_SSL_ASYNCH_STREAM_H */