00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file SSL_Asynch_Stream.h 00006 * 00007 * $Id: SSL_Asynch_Stream.h 72092 2006-04-14 16:15:58Z shuston $ 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 */