SSL_Asynch_Stream.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   SSL_Asynch_Stream.h
00006  *
00007  *  SSL_Asynch_Stream.h,v 1.18 2006/04/14 16:14:41 shuston Exp
00008  *
00009  *  @author Alexander Libman <alibman@baltimore.com>
00010  */
00011 //=============================================================================
00012 
00013 #ifndef ACE_SSL_ASYNCH_STREAM_H
00014 #define ACE_SSL_ASYNCH_STREAM_H
00015 
00016 #include /**/ "ace/pre.h"
00017 #include "SSL_Context.h"
00018 
00019 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00020 #pragma once
00021 #endif /* ACE_LACKS_PRAGMA_ONCE */
00022 
00023 #if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)))
00024 
00025 #include "SSL_Asynch_BIO.h"
00026 
00027 #include "ace/Asynch_IO_Impl.h"
00028 #include "ace/Message_Block.h"
00029 #include "ace/Synch_Traits.h"
00030 #include "ace/Thread_Mutex.h"
00031 
00032 /*
00033  * This facility doesn't follow the normal ACE asynch I/O support classes'
00034  * interface/implementation arrangement. It's not needed because rather than
00035  * branching off to platform-specific APIs, all platforms use the OpenSSL
00036  * API. Thus, you can think of this class as the implementation class (for
00037  * OpenSSL) and there's no separate interface class.
00038  * Also, since both read and write operations are defined in one I/O
00039  * factory, there's no single Result class defined as there is for
00040  * ACE_Asynch_Read_Stream, et al. There are separate result classes defined
00041  * for read and write operations.
00042  */
00043 
00044 #if defined (ACE_WIN32)
00045 #  include "ace/WIN32_Asynch_IO.h"
00046 typedef ACE_WIN32_Asynch_Result              A_RESULT;
00047 typedef ACE_WIN32_Asynch_Read_Stream_Result  ARS_RESULT;
00048 typedef ACE_WIN32_Asynch_Write_Stream_Result AWS_RESULT;
00049 
00050 # define ERR_CANCELED ERROR_OPERATION_ABORTED
00051 
00052 #else
00053 #  include "ace/POSIX_Asynch_IO.h"
00054 typedef ACE_POSIX_Asynch_Result              A_RESULT;
00055 typedef ACE_POSIX_Asynch_Read_Stream_Result  ARS_RESULT;
00056 typedef ACE_POSIX_Asynch_Write_Stream_Result AWS_RESULT;
00057 
00058 # define ERR_CANCELED ECANCELED
00059 
00060 #endif  /* ACE_WIN32 */
00061 
00062 
00063 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00064 
00065 class ACE_SSL_Asynch_Stream;     // Forward decl for use in result class def.
00066 
00067 /**
00068  * @class ACE_SSL_Asynch_Read_Stream_Result
00069  *
00070  * Result class that communicates result of read operations initiated on
00071  * an ACE_SSL_Asynch_Stream object.
00072  */
00073 class ACE_SSL_Asynch_Read_Stream_Result : public ARS_RESULT
00074 {
00075   /// Factory class will have special permissions.
00076   friend class ACE_SSL_Asynch_Stream;
00077 
00078 protected:
00079   ACE_SSL_Asynch_Read_Stream_Result (ACE_Handler &handler,
00080                                      ACE_HANDLE handle,
00081                                      ACE_Message_Block &message_block,
00082                                      size_t bytes_to_read,
00083                                      const void* act,
00084                                      ACE_HANDLE event,
00085                                      int priority,
00086                                      int signal_number);
00087 };
00088 
00089 /**
00090  * @class ACE_SSL_Asynch_Write_Stream_Result
00091  *
00092  * Result class that communicates result of write operations initiated on
00093  * an ACE_SSL_Asynch_Stream object.
00094  */
00095 class ACE_SSL_Asynch_Write_Stream_Result : public AWS_RESULT
00096 {
00097   /// Factory class will have special permissions.
00098   friend class ACE_SSL_Asynch_Stream;
00099 
00100 protected:
00101   ACE_SSL_Asynch_Write_Stream_Result (ACE_Handler &handler,
00102                                       ACE_HANDLE handle,
00103                                       ACE_Message_Block &message_block,
00104                                       size_t bytes_to_read,
00105                                       const void* act,
00106                                       ACE_HANDLE event,
00107                                       int priority,
00108                                       int signal_number);
00109 };
00110 
00111 
00112 /**
00113  * @class ACE_SSL_Asynch_Result
00114  *
00115  * Result class that is used internally for socket close notifications.
00116  */
00117 class ACE_SSL_Asynch_Result : public A_RESULT
00118 {
00119 public:
00120     ACE_SSL_Asynch_Result (ACE_Handler &handler);
00121 
00122     void complete (size_t bytes_transferred,
00123                    int    success,
00124                    const  void * completion_key,
00125                    u_long error);
00126 };
00127 
00128 
00129 // Only provide forward declarations to prevent possible abuse of the
00130 // friend declarations in ACE_SSL_Asynch_Stream.
00131 struct ACE_SSL_Asynch_Stream_Accessor;
00132 
00133 /**
00134  * @class ACE_SSL_Asynch_Stream
00135  *
00136  * @brief This class is a factory for initiating asynchronous reads
00137  * and writes on an SSL stream.
00138  *
00139  * Once open() is called, multiple asynchronous read and write operations
00140  * can be started using this class.  The handler object (derived from
00141  * ACE_Handler) specified in open() will receive completion events for the
00142  * operations initiated via this class.
00143  */
00144 class ACE_SSL_Export ACE_SSL_Asynch_Stream
00145   : public ACE_Asynch_Operation,
00146     public ACE_Handler
00147 {
00148 public:
00149 
00150   // Use a class/struct to work around scoping
00151   // problems for extern "C" free functions with some compilers.  For
00152   // example, some can't handle
00153   //
00154   //   friend ::some_extern_c_free_function (...)
00155   //
00156   // Note that we could use a straight C++ (i.e. not extern "C") free
00157   // function, but using a class or struct allows us to hide the
00158   // interface from the user, which prevents abuse of this friend
00159   // relationship.
00160   friend struct ACE_SSL_Asynch_Stream_Accessor;
00161 
00162   enum Stream_Type
00163     {
00164       ST_CLIENT = 0x0001,
00165       ST_SERVER = 0x0002
00166     };
00167 
00168   /// Constructor.
00169   /**
00170    * @arg context  Pointer to an ACE_SSL_Context instance containing
00171    *               the OpenSSL information to be associated with this
00172    *               ACE_SSL_Asynch_Stream.  The needed SSL data will be
00173    *               copied before return. Therefore, this object can be
00174    *               reused, modified, or deleted upon return. If a 0 pointer
00175    *               is passed, the ACE_SSL_Context::instance() method will
00176    *               be called to get access to a singleton.
00177    */
00178   ACE_SSL_Asynch_Stream (Stream_Type s_type = ST_SERVER,
00179                          ACE_SSL_Context * context = 0);
00180 
00181   /// Destructor
00182   virtual ~ACE_SSL_Asynch_Stream (void);
00183 
00184   int cancel (void);
00185 
00186   int close (void);
00187 
00188   /**
00189    * Initializes the factory with information which will be used with
00190    * each asynchronous call.
00191    *
00192    * @arg handler The ACE_Handler that will be called to handle completions
00193    *              for operations initiated using this factory.
00194    * @arg handle  The handle that future read/write operations will use.
00195    *
00196    * @retval 0    for success.
00197    * @retval -1   for failure; consult @c errno for further information.
00198    */
00199   int open (ACE_Handler &handler,
00200             ACE_HANDLE handle = ACE_INVALID_HANDLE,
00201             const void *completion_key = 0,
00202             ACE_Proactor *proactor = 0);
00203 
00204   /**
00205    * Initiates an asynchronous read. If the operation is successfully
00206    * initiated, the handle_read_stream() method will be called on the
00207    * ACE_Handler object passed to open() when the operation completes.
00208    * Data is read into the specified ACE_Message_Block beginning at its
00209    * write pointer; the block's write pointer is updated to reflect any
00210    * added data when the operation completes.
00211    *
00212    * @arg message_block      The specified ACE_Message_Block will receive any
00213    *                         data that is read. Data will be read into the
00214    *                         block beginning at the block's write pointer.
00215    * @arg num_bytes_to_read  The maximum number of bytes to read. The actual
00216    *                         amount read may be less.
00217    * @arg act                ACT which is passed to the completion handler in
00218    *                         the result object.
00219    * @arg priority           Specifies the operation priority. This has an
00220    *                         affect on POSIX only. Works like @i nice in Unix.
00221    *                         Negative values are not allowed. 0 means priority
00222    *                         of the operation same as the process priority.
00223    *                         1 means priority of the operation is one less than
00224    *                         process, and so forth. This parameter has no
00225    *                         affect on Win32.
00226    * @arg signal_number      The POSIX4 real-time signal number to be used
00227    *                         for the operation. signal_number ranges from
00228    *                         ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is
00229    *                         unused on non-POSIX4 systems.
00230    *
00231    * @retval 0    for success.
00232    * @retval -1   for failure; consult @c errno for further information.
00233    */
00234   int read (ACE_Message_Block &message_block,
00235             size_t num_bytes_to_read,
00236             const void *act = 0,
00237             int priority = 0,
00238             int signal_number = ACE_SIGRTMIN);
00239 
00240   /**
00241    * Initiates an asynchronous write. If the operation is successfully
00242    * initiated, the handle_write_stream() method will be called on the
00243    * ACE_Handler object passed to open() when the operation completes.
00244    * Data is taken from the specified ACE_Message_Block beginning at its
00245    * read pointer; the block's read pointer is updated to reflect any
00246    * data successfully sent when the operation completes.
00247    *
00248    * @arg message_block      The specified ACE_Message_Block is the source of
00249    *                         data that is written. Data will be taken from the
00250    *                         block beginning at the block's read pointer.
00251    * @arg bytes_to_write     The maximum number of bytes to write. The actual
00252    *                         amount written may be less.
00253    * @arg act                ACT which is passed to the completion handler in
00254    *                         the result object.
00255    * @arg priority           Specifies the operation priority. This has an
00256    *                         affect on POSIX only. Works like @i nice in Unix.
00257    *                         Negative values are not allowed. 0 means priority
00258    *                         of the operation same as the process priority.
00259    *                         1 means priority of the operation is one less than
00260    *                         process, and so forth. This parameter has no
00261    *                         affect on Win32.
00262    * @arg signal_number      The POSIX4 real-time signal number to be used
00263    *                         for the operation. signal_number ranges from
00264    *                         ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is
00265    *                         unused on non-POSIX4 systems.
00266    *
00267    * @retval 0    for success.
00268    * @retval -1   for failure; consult @c errno for further information.
00269    */
00270   int write (ACE_Message_Block &message_block,
00271              size_t bytes_to_write,
00272              const void *act = 0,
00273              int priority = 0,
00274              int signal_number = ACE_SIGRTMIN);
00275 
00276 protected:
00277   /// Virtual from ACE_Asynch_Operation. Since this class is essentially an
00278   /// implementation class, simply return 0.
00279   virtual ACE_Asynch_Operation_Impl *implementation (void) const { return 0; }
00280 
00281   /// virtual from ACE_Handler
00282 
00283   /// This method is called when BIO write request is completed. It
00284   /// processes the IO completion and calls do_SSL_state_machine().
00285   virtual void handle_write_stream
00286                (const ACE_Asynch_Write_Stream::Result &result);
00287 
00288   /// This method is called when BIO read request is completed. It
00289   /// processes the IO completion and calls do_SSL_state_machine().
00290   virtual void handle_read_stream
00291                (const ACE_Asynch_Read_Stream::Result &result);
00292 
00293   /// This method is called when all SSL sessions are closed and no
00294   /// more pending AIOs exist.  It also calls users handle_wakeup().
00295   virtual void handle_wakeup (void);
00296 
00297   /**
00298    * @name SSL State Machine
00299    */
00300   //@{
00301   int do_SSL_state_machine (void);
00302   int do_SSL_handshake (void);
00303   int do_SSL_read (void);
00304   int do_SSL_write(void);
00305   int do_SSL_shutdown(void);
00306   //@}
00307 
00308   void print_error (int err_ssl,
00309                     const ACE_TCHAR *pText);
00310 
00311   int pending_BIO_count (void);
00312 
00313   /// This method is called to notify user handler when user's read in
00314   /// done.
00315   int notify_read (int bytes_transferred, int error);
00316 
00317   /// This method is called to notify user handler when user's write
00318   /// in done.
00319   int notify_write (int bytes_transferred, int error);
00320 
00321   /// This method is called to notify ourself that SSL session is
00322   /// shutdown and that there is no more I/O activity now and in the
00323   /// future.
00324   int notify_close(void);
00325 
00326   /**
00327    * @name BIO Helpers
00328    */
00329   //@{
00330   int ssl_bio_read (char * buf, size_t len, int & errval);
00331   int ssl_bio_write (const char * buf, size_t len, int & errval);
00332   //@}
00333 
00334 private:
00335 
00336   // Preventing copying through construction or assignment.
00337   ACE_SSL_Asynch_Stream (ACE_SSL_Asynch_Stream const &);
00338   ACE_SSL_Asynch_Stream & operator= (ACE_SSL_Asynch_Stream const &);
00339 
00340 protected:
00341 
00342   /// Stream Type ST_CLIENT/ST_SERVER
00343   Stream_Type type_;
00344 
00345   /// The real file/socket handle
00346   ACE_HANDLE handle_;
00347 
00348   /// The proactor
00349   ACE_Proactor * proactor_;
00350 
00351   /// External,i.e user  handler
00352   ACE_Handler * ext_handler_;
00353 
00354   /// External, i.e. read result faked for user
00355   ACE_SSL_Asynch_Read_Stream_Result *  ext_read_result_ ;
00356 
00357   /// External, i.e. write result faked for user
00358   ACE_SSL_Asynch_Write_Stream_Result * ext_write_result_ ;
00359 
00360   /// Stream state/flags
00361   enum Stream_Flag
00362     {
00363       /// istream_ open OK
00364       SF_STREAM_OPEN    = 0x0001,
00365       /// request to SSL shutdown
00366       SF_REQ_SHUTDOWN   = 0x0002,
00367       /// SSL shutdown finished
00368       SF_SHUTDOWN_DONE  = 0x0004,
00369       /// Close notification sent
00370       SF_CLOSE_NTF_SENT = 0x0008,
00371       /// Stream can be safely destroyed
00372       SF_DELETE_ENABLE  = 0x0010
00373     };
00374 
00375   int flags_;
00376 
00377   /// The SSL session.
00378   SSL * ssl_;
00379 
00380   /// The BIO implementation
00381   BIO * bio_;
00382 
00383   /// The real streams which work under the ssl connection.
00384   /// BIO performs I/O via this streams
00385   enum BIO_Flag  // internal IO flags
00386     {
00387       /// End of stream
00388       BF_EOS   = 0x01,
00389       /// Real AIO in progress
00390       BF_AIO   = 0x02
00391     };
00392 
00393   /**
00394    * @name Internal stream, buffer and info for BIO read
00395    */
00396   //@{
00397   ACE_Asynch_Read_Stream  bio_istream_;
00398   ACE_Message_Block       bio_inp_msg_;
00399   int                     bio_inp_errno_;
00400   int                     bio_inp_flag_;
00401   //@}
00402 
00403   /**
00404    * @name Internal stream, buffer and info for BIO write
00405    */
00406   //@{
00407   ACE_Asynch_Write_Stream bio_ostream_;
00408   ACE_Message_Block       bio_out_msg_;
00409   int                     bio_out_errno_;
00410   int                     bio_out_flag_;
00411   //@}
00412 
00413   /// Mutex to protect work
00414   ACE_SYNCH_MUTEX mutex_;
00415 
00416 };
00417 
00418 ACE_END_VERSIONED_NAMESPACE_DECL
00419 
00420 #endif  /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
00421            ACE_HAS_AIO_CALLS) */
00422 
00423 #include /**/ "ace/post.h"
00424 
00425 #endif  /* ACE_SSL_ASYNCH_STREAM_H */

Generated on Thu Nov 9 11:41:56 2006 for ACE_SSL by doxygen 1.3.6