Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

SSL_Asynch_Stream.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #include "SSL_Asynch_Stream.h"
00004 
00005 ACE_RCSID (ACE_SSL,
00006            SSL_Asynch_Stream,
00007            "$Id: SSL_Asynch_Stream.cpp,v 1.1.1.2 2003/02/21 18:36:32 chad Exp $")
00008 
00009 // This only works on platforms with Asynchronous IO support.
00010 #if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)))
00011 
00012 
00013 #if defined (ACE_WIN32)
00014 
00015 # define A_RESULT     ACE_WIN32_Asynch_Result
00016 # define ARS_RESULT   ACE_WIN32_Asynch_Read_Stream_Result
00017 # define AWS_RESULT   ACE_WIN32_Asynch_Write_Stream_Result
00018 
00019 # define ERR_CANCELED ERROR_OPERATION_ABORTED
00020 
00021 # include "ace/WIN32_Proactor.h"
00022 
00023 #else
00024 
00025 # define A_RESULT     ACE_POSIX_Asynch_Result
00026 # define ARS_RESULT   ACE_POSIX_Asynch_Read_Stream_Result
00027 # define AWS_RESULT   ACE_POSIX_Asynch_Write_Stream_Result
00028 
00029 # define ERR_CANCELED ECANCELED
00030 
00031 # include "ace/POSIX_Proactor.h"
00032 
00033 #endif  /* ACE_WIN32 */
00034 
00035 #include "ace/Proactor.h"
00036 
00037 #include <openssl/err.h>
00038 
00039 // ************************************************************
00040 //  SSL Asynchronous Write Result
00041 // ************************************************************
00042 
00043 class ACE_SSL_Export ACE_SSL_Asynch_Write_Stream_Result:
00044   public AWS_RESULT
00045 {
00046   /// Factory class will have special permissions.
00047   friend class ACE_SSL_Asynch_Stream;
00048 
00049 protected:
00050 
00051   ACE_SSL_Asynch_Write_Stream_Result (ACE_Handler &handler,
00052                                       ACE_HANDLE handle,
00053                                       ACE_Message_Block &message_block,
00054                                       size_t bytes_to_read,
00055                                       const void* act,
00056                                       ACE_HANDLE event,
00057                                       int priority,
00058                                       int signal_number);
00059 };
00060 
00061 ACE_SSL_Asynch_Write_Stream_Result::ACE_SSL_Asynch_Write_Stream_Result
00062   (ACE_Handler &       handler,
00063     ACE_HANDLE          handle,
00064     ACE_Message_Block & message_block,
00065     size_t              bytes_to_write,
00066     const void *        act,
00067     ACE_HANDLE          event,
00068     int                 priority,
00069     int                 signal_number
00070  )
00071   : AWS_RESULT (handler,
00072                  handle,
00073                  message_block,
00074                  bytes_to_write,
00075                  act,
00076                  event,
00077                  priority,
00078                  signal_number
00079               )
00080 {
00081 }
00082 
00083 // ************************************************************
00084 //  SSL Asynchronous Read Result
00085 // ************************************************************
00086 class ACE_SSL_Export ACE_SSL_Asynch_Read_Stream_Result:
00087   public ARS_RESULT
00088 {
00089   /// Factory class will have special permissions.
00090   friend class ACE_SSL_Asynch_Stream;
00091 
00092 protected:
00093 
00094   ACE_SSL_Asynch_Read_Stream_Result (ACE_Handler &handler,
00095                                      ACE_HANDLE handle,
00096                                      ACE_Message_Block &message_block,
00097                                      size_t bytes_to_read,
00098                                      const void* act,
00099                                      ACE_HANDLE event,
00100                                      int priority,
00101                                      int signal_number);
00102 };
00103 
00104 
00105 
00106 ACE_SSL_Asynch_Read_Stream_Result::ACE_SSL_Asynch_Read_Stream_Result
00107   (ACE_Handler &        handler,
00108     ACE_HANDLE           handle,
00109     ACE_Message_Block &  message_block,
00110     size_t               bytes_to_read,
00111     const void *         act,
00112     ACE_HANDLE           event,
00113     int                  priority,
00114     int                  signal_number
00115  )
00116   : ARS_RESULT (handler,
00117                  handle,
00118                  message_block,
00119                  bytes_to_read,
00120                  act,
00121                  event,
00122                  priority,
00123                  signal_number
00124               )
00125 {
00126 }
00127 
00128 
00129 // ************************************************************
00130 //   Faked Result. It is used for close notification
00131 // ************************************************************
00132 class ACE_SSL_Asynch_Result : public A_RESULT
00133 {
00134 public:
00135     ACE_SSL_Asynch_Result (ACE_Handler & handler);
00136 
00137     void complete (size_t bytes_transferred,
00138                    int    success,
00139                    const  void * completion_key,
00140                    u_long error);
00141 };
00142 
00143 ACE_SSL_Asynch_Result::ACE_SSL_Asynch_Result
00144   (ACE_Handler & handler)
00145   : A_RESULT (handler,
00146               0,          // act,
00147               ACE_INVALID_HANDLE,
00148               0,           // Offset
00149               0,           // OffsetHigh
00150               0,           // Priority
00151               ACE_SIGRTMIN //signal_number
00152               )
00153 {
00154 }
00155 
00156 void
00157 ACE_SSL_Asynch_Result::complete (size_t /* bytes_transferred */,
00158                                  int    /* success */,
00159                                  const  void * /* completion_key */,
00160                                  u_long /* error */)
00161 {
00162   this->handler_.handle_wakeup ();
00163 }
00164 
00165 // ************************************************************
00166 //  ACE_SSL_Asynch_Stream Constructor / Desctructor
00167 // ************************************************************
00168 ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream (
00169   ACE_SSL_Asynch_Stream::Stream_Type s_type,
00170   ACE_SSL_Context * context)
00171   : type_         (s_type),
00172     handle_       (ACE_INVALID_HANDLE),
00173     proactor_     (0),
00174     ext_handler_  (0),
00175     ext_read_result_ (0),
00176     ext_write_result_(0),
00177     flags_        (0),
00178     ssl_          (0),
00179     bio_          (0),
00180     bio_istream_  (),
00181     bio_inp_msg_  (),
00182     bio_inp_errno_(0),
00183     bio_inp_flag_ (0),
00184     bio_ostream_  (),
00185     bio_out_msg_  (),
00186     bio_out_errno_(0),
00187     bio_out_flag_ (0),
00188     mutex_ ()
00189 {
00190   ACE_TRACE ("ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream");
00191   // was honestly copied from ACE_SSL_SOCK_Stream :)
00192 
00193   ACE_SSL_Context * ctx =
00194     (context == 0 ? ACE_SSL_Context::instance () : context);
00195 
00196   this->ssl_ = ::SSL_new (ctx->context ());
00197 
00198   if (this->ssl_ == 0)
00199     ACE_ERROR
00200       ((LM_ERROR,
00201         ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00202         ACE_TEXT ("- cannot allocate new SSL structure")
00203      ));
00204 
00205   ::SSL_set_verify (this->ssl_,
00206                     ctx->default_verify_mode (),
00207                     0);
00208 }
00209 
00210 ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream (void)
00211 {
00212   ACE_TRACE ("ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream");
00213 
00214 
00215   // It is safe to delete stream if all notifications are received,
00216   // i.e., state is SF_DELETE_ENABLE or if proactor event loop is
00217   // done.
00218   if (this->flags_ & SF_STREAM_OPEN)             // open
00219     if ((this->flags_ & SF_DELETE_ENABLE) == 0)  // but ..
00220       ACE_DEBUG ((LM_DEBUG,
00221                   ACE_TEXT("ACE_SSL_Asynch_Stream::DTOR-")
00222                   ACE_TEXT("possible access violation ")
00223                   ACE_TEXT("if proactor still handles events\n")));
00224 
00225   ::SSL_free (this->ssl_);
00226   this->ssl_ = 0;
00227 
00228   // Was honestly copied from ACE_SSL_SOCK_Stream :)
00229 
00230   // @@ Question: should we reference count the Context object or
00231   // leave that to the application developer? We do not reference
00232   // count reactors (for example) and following some simple rules
00233   // seems to work fine!
00234 }
00235 
00236 // ************************************************************
00237 //  close ()
00238 //  returns :
00239 //  0  - Stream is in the state SF_DELETE_ENABLE,
00240 //       so  it is safe to delete stream
00241 //  -1 - Stream has pending AIO requests,
00242 //       close should be repeated later one more
00243 // ************************************************************
00244 
00245 int
00246 ACE_SSL_Asynch_Stream::close (void)
00247 {
00248   ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
00249 
00250   if ((flags_ & SF_STREAM_OPEN) == 0) // not open
00251     flags_ |= SF_DELETE_ENABLE;
00252 
00253   if (flags_ & SF_DELETE_ENABLE)
00254     return 0;
00255 
00256   flags_ |= SF_REQ_SHUTDOWN;
00257 
00258   this->do_SSL_state_machine ();
00259 
00260   return -1;
00261 }
00262 
00263 // ************************************************************
00264 //  Asynch_Operation interface
00265 //    cancel
00266 // ************************************************************
00267 int
00268 ACE_SSL_Asynch_Stream::cancel (void)
00269 {
00270   ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
00271 
00272   if ((flags_ & SF_STREAM_OPEN) == 0) // not open
00273     return 1;   //   AIO_ALLDONE
00274 
00275   // attempt to cancel internal, i.e. user's read/write
00276   int rc_r_int = bio_istream_.cancel();
00277   int rc_w_int = bio_ostream_.cancel();
00278 
00279   // attempt to cancel external, i.e. bio_ssl read/write
00280   int rc_r_ext = notify_read (0, ERR_CANCELED);
00281   int rc_w_ext = notify_read (0, ERR_CANCELED);
00282 
00283   if (rc_r_int < 0  || rc_w_int < 0
00284       && rc_r_ext < 0  || rc_w_ext < 0)
00285     return -1;  // at least one error
00286 
00287   if (rc_r_int == 1 && rc_w_int == 1
00288       && rc_r_ext == 1 && rc_w_ext == 1)
00289     return 1;  // AIO_ALLDONE
00290 
00291   if (rc_r_int == 2 || rc_w_int == 2
00292       && rc_r_ext == 2 || rc_w_ext == 2)
00293     return 2;  // AIO_NOT_CANCELED , at least one not canceled
00294 
00295   return 0;    // AIO_CANCELED, at least will be one notification
00296 }
00297 
00298 // ************************************************************
00299 //  Asynch_Operation interface
00300 //    open
00301 // ************************************************************
00302 int
00303 ACE_SSL_Asynch_Stream::open (ACE_Handler & handler,
00304                              ACE_HANDLE handle,
00305                              const void * completion_key,
00306                              ACE_Proactor * proactor)
00307 {
00308   ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
00309 
00310   if (this->flags_ & SF_STREAM_OPEN)
00311     ACE_ERROR_RETURN
00312       ((LM_ERROR,
00313         ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
00314         ACE_TEXT ("- already opened")),
00315        -1);
00316 
00317   if (this->ssl_ == 0)
00318     ACE_ERROR_RETURN
00319       ((LM_ERROR,
00320         ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
00321         ACE_TEXT ("- SSL structure is absent")),
00322        -1);
00323 
00324   if (handle == ACE_INVALID_HANDLE)
00325     ACE_ERROR_RETURN
00326       ((LM_ERROR,
00327         ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
00328         ACE_TEXT ("- invalid handle")),
00329        -1);
00330 
00331 
00332   // Get a proactor for/from the user.
00333   this->proactor_    = this->get_proactor (proactor, handler);
00334   this->ext_handler_ = & handler;
00335   this->handle_      = handle;
00336 
00337   // Open internal input stream
00338   if (this->bio_istream_.open (*this,   // real callbacks to this
00339                                handle,
00340                                completion_key,
00341                                this->proactor_) != 0)
00342     return -1;
00343 
00344   // Open internal output stream
00345   if (this->bio_ostream_.open (*this,  // real callbacks to this
00346                                handle,
00347                                completion_key,
00348                                this->proactor_) != 0)
00349     return -1;
00350 
00351   this->bio_ = ::BIO_new_ACE_Asynch (this);
00352 
00353   if (this->bio_ == 0)
00354     ACE_ERROR_RETURN
00355       ((LM_ERROR,
00356         ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
00357         ACE_TEXT ("- cannot allocate new BIO structure")),
00358        -1);
00359 
00360   ::SSL_set_bio (this->ssl_ , this->bio_ , this->bio_);
00361 
00362   switch (this->type_)
00363     {
00364     case ST_CLIENT:
00365       ::SSL_set_connect_state (this->ssl_);
00366       break;
00367 
00368     case ST_SERVER:
00369       ::SSL_set_accept_state (this->ssl_);
00370       break;
00371 
00372     default:
00373       ACE_ERROR_RETURN
00374         ((LM_ERROR,
00375           ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
00376           ACE_TEXT ("- invalid stream type")),
00377          -1);
00378     }
00379 
00380   this->flags_ |= SF_STREAM_OPEN;
00381 
00382   this->do_SSL_state_machine ();
00383 
00384   return 0;
00385 }
00386 
00387 void
00388 ACE_SSL_Asynch_Stream::open (ACE_HANDLE new_handle,
00389                              ACE_Message_Block &block)
00390 {
00391   ACE_Service_Handler::open (new_handle,
00392                              block);
00393 }
00394 
00395 // ************************************************************
00396 //  Asynch_Operation interface
00397 //    read
00398 // ************************************************************
00399 int
00400 ACE_SSL_Asynch_Stream::read (ACE_Message_Block & message_block,
00401                              size_t bytes_to_read,
00402                              const void * act,
00403                              int priority,
00404                              int signal_number)
00405 {
00406   ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
00407 
00408   if ((this->flags_ & SF_STREAM_OPEN) == 0)  // not open
00409     return -1;
00410 
00411   if (this->flags_ & SF_REQ_SHUTDOWN)
00412     return -1;
00413 
00414   // only one read operation is allowed now
00415   // later it will be possible to make a queue
00416 
00417   if (this->ext_read_result_ != 0)
00418     return -1;
00419 
00420   // create result for future notification
00421   ACE_NEW_RETURN (this->ext_read_result_,
00422                   ACE_SSL_Asynch_Read_Stream_Result (
00423                     *this->ext_handler_,
00424                     this->handle_,
00425                     message_block,
00426                     bytes_to_read,
00427                     act,
00428                     this->proactor_->get_handle(),
00429                     priority,
00430                     signal_number),
00431                   -1);
00432 
00433   this->do_SSL_state_machine (); // ignore return code
00434 
00435   return 0;
00436 }
00437 
00438 // ************************************************************
00439 //  Asynch_Operation interface
00440 //    write
00441 // ************************************************************
00442 int
00443 ACE_SSL_Asynch_Stream::write (ACE_Message_Block & message_block,
00444                               size_t bytes_to_write,
00445                               const void * act,
00446                               int priority,
00447                               int signal_number)
00448 {
00449   ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
00450 
00451   if ((this->flags_ & SF_STREAM_OPEN) == 0)  // not open
00452     return -1;
00453 
00454   if (this->flags_ & SF_REQ_SHUTDOWN)
00455     return -1;
00456 
00457   // only one read operation is allowed now
00458   // later it will be possible to make a queue
00459 
00460   if (this->ext_write_result_ != 0)
00461     return -1;
00462 
00463   // create result for future notification
00464   ACE_NEW_RETURN (this->ext_write_result_,
00465                   ACE_SSL_Asynch_Write_Stream_Result (
00466                     *this->ext_handler_,
00467                     this->handle_,
00468                     message_block,
00469                     bytes_to_write,
00470                     act,
00471                     this->proactor_->get_handle(),
00472                     priority,
00473                     signal_number),
00474                   -1);
00475 
00476   this->do_SSL_state_machine ();
00477 
00478   return 0;
00479 }
00480 
00481 // ************************************************************
00482 //  Main SSL engine
00483 // ************************************************************
00484 int
00485 ACE_SSL_Asynch_Stream::do_SSL_state_machine (void)
00486 {
00487   // this protected member should be called
00488   // with locked mutex_
00489 
00490   int retval = this->do_SSL_handshake ();
00491 
00492   if (retval == 0)          // handshake in progress ?
00493     return 0;
00494 
00495   if (retval < 0)
00496     this->flags_ |= SF_REQ_SHUTDOWN;
00497 
00498   this->do_SSL_read ();  // execute user read request
00499   this->do_SSL_write (); // execute user write request
00500 
00501   if ((this->flags_ & SF_REQ_SHUTDOWN) == 0)     // Do we have any errors
00502     return 0;
00503 
00504   this->do_SSL_shutdown ();
00505 
00506   this->notify_close ();
00507 
00508   return 0;
00509 }
00510 
00511 // ************************************************************
00512 // do_SSL_shutdown
00513 // return code:
00514 // 1   SSL shutdown is finished already, success
00515 // 0   SSL shutdown in progress
00516 // -1  failure
00517 // ************************************************************
00518 int
00519 ACE_SSL_Asynch_Stream::do_SSL_shutdown (void)
00520 {
00521   if (this->flags_ & SF_SHUTDOWN_DONE) // already done
00522     return 1;
00523 
00524   this->flags_ |= SF_REQ_SHUTDOWN;
00525 
00526   // if we have any uncompleted user requests
00527   // than cancel its
00528   this->notify_read  (0, ERR_CANCELED);
00529   this->notify_write (0, ERR_CANCELED);
00530 
00531   int retval = ::SSL_shutdown (this->ssl_);
00532 
00533   int status = ::SSL_get_error (this->ssl_, retval);
00534 
00535   switch (status)
00536     {
00537     case SSL_ERROR_NONE:
00538     case SSL_ERROR_ZERO_RETURN:
00539     case SSL_ERROR_SYSCALL:
00540       retval = 1;
00541       break;
00542 
00543     case SSL_ERROR_WANT_READ:
00544     case SSL_ERROR_WANT_WRITE:
00545     case SSL_ERROR_WANT_CONNECT:
00546     //   case SSL_ERROR_WANT_ACCEPT:
00547     case SSL_ERROR_WANT_X509_LOOKUP:
00548       return 0;
00549 
00550     default:
00551       this->print_error (status,
00552                          ACE_TEXT ("Shutdown error"));
00553       retval = -1;
00554       break;
00555     }
00556 
00557   this->flags_ |= SF_SHUTDOWN_DONE;
00558 
00559   return retval;
00560 }
00561 
00562 // ************************************************************
00563 // Do SSL handshake if necessary
00564 // return code:
00565 // 1   SSL handshake is finished already, success
00566 // 0   SSL handshake in progress
00567 // -1  failure
00568 // ************************************************************
00569 int
00570 ACE_SSL_Asynch_Stream::do_SSL_handshake (void)
00571 {
00572   if (SSL_is_init_finished (this->ssl_))
00573     return 1;
00574 
00575   if (this->flags_ & SF_REQ_SHUTDOWN)
00576     return -1;
00577 
00578   int retval = -1;
00579 
00580   switch (this->type_)
00581     {
00582     case ST_CLIENT:
00583       retval = ::SSL_connect (this->ssl_);
00584       break;
00585 
00586     case ST_SERVER:
00587       retval = ::SSL_accept (this->ssl_);
00588       break;
00589 
00590     default:
00591       ACE_ERROR_RETURN
00592         ((LM_ERROR,
00593           ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00594           ACE_TEXT ("- invalid stream type")),
00595          -1);
00596     }
00597 
00598   int status = ::SSL_get_error (this->ssl_, retval);
00599 
00600   switch (status)
00601     {
00602     case SSL_ERROR_NONE:
00603       break;
00604 
00605     case SSL_ERROR_WANT_READ:
00606     case SSL_ERROR_WANT_WRITE:
00607     case SSL_ERROR_WANT_CONNECT:
00608     //case SSL_ERROR_WANT_ACCEPT:
00609     case SSL_ERROR_WANT_X509_LOOKUP:
00610       return 0;
00611 
00612     case SSL_ERROR_ZERO_RETURN:
00613     case SSL_ERROR_SYSCALL:
00614     default:
00615       this->print_error (status,
00616                          ACE_TEXT ("Handshake error"));
00617       return -1;
00618     }
00619 
00620   return 1;
00621 }
00622 
00623 // ************************************************************
00624 // Perform SSL_read call if necessary and notify user
00625 // ************************************************************
00626 int
00627 ACE_SSL_Asynch_Stream::do_SSL_read (void)
00628 {
00629   if (this->ext_read_result_ == 0)  // nothing to do
00630     return 0;
00631 
00632   if (this->flags_ & SF_REQ_SHUTDOWN)
00633     {
00634       this->notify_read (0, ERR_CANCELED);
00635       return -1;
00636     }
00637 
00638   ACE_Message_Block & mb = this->ext_read_result_->message_block ();
00639   size_t bytes_req = this->ext_read_result_->bytes_to_read ();
00640 
00641   int bytes_trn = ::SSL_read (this->ssl_,
00642                               mb.rd_ptr (),
00643                               bytes_req);
00644 
00645   int status = ::SSL_get_error (this->ssl_, bytes_trn);
00646 
00647   switch (status)
00648     {
00649     case SSL_ERROR_NONE:
00650       this->notify_read (bytes_trn, 0);
00651       return 1;
00652 
00653     case SSL_ERROR_WANT_READ:
00654     case SSL_ERROR_WANT_WRITE:
00655       return 0;
00656 
00657     case SSL_ERROR_ZERO_RETURN:
00658       this->notify_read (0, 0);
00659       return 1;
00660 
00661     case SSL_ERROR_SYSCALL:
00662       if (bytes_trn == 0)
00663         {
00664           this->notify_read (0, 0);
00665           return 1;
00666         }
00667       // If not an EOF, then fall through to "default" case.
00668 
00669     default:
00670       break;
00671     }
00672 
00673  this->notify_read (0, EFAULT);
00674  this->print_error (status,
00675                     ACE_TEXT ("SSL_read error"));
00676 
00677  return -1;
00678 }
00679 
00680 // ************************************************************
00681 // Perform SSL_write call if necessary  and notify user
00682 // ************************************************************
00683 int
00684 ACE_SSL_Asynch_Stream::do_SSL_write (void)
00685 {
00686   if (this->ext_write_result_ == 0)  // nothing to do
00687     return 0;
00688 
00689   if (this->flags_ & SF_REQ_SHUTDOWN)
00690     {
00691       this->notify_write (0, ERR_CANCELED);
00692       return -1;
00693     }
00694 
00695   ACE_Message_Block & mb = this->ext_write_result_->message_block ();
00696   size_t       bytes_req = this->ext_write_result_->bytes_to_write ();
00697 
00698   int bytes_trn = ::SSL_write (this->ssl_,
00699                                mb.rd_ptr (),
00700                                bytes_req);
00701 
00702   int status = ::SSL_get_error (this->ssl_, bytes_trn);
00703 
00704   switch (status)
00705     {
00706     case SSL_ERROR_NONE:
00707       this->notify_write (bytes_trn, 0);
00708       return 1;
00709 
00710     case SSL_ERROR_WANT_READ:
00711     case SSL_ERROR_WANT_WRITE:
00712       return 0;
00713 
00714     case SSL_ERROR_ZERO_RETURN:
00715       this->notify_write (bytes_trn, 0);
00716       return 1;
00717 
00718     case SSL_ERROR_SYSCALL:
00719     default:
00720       break;
00721     }
00722 
00723  this->notify_write(0, EFAULT);
00724  this->print_error (status,
00725                     ACE_TEXT ("SSL_write error"));
00726 
00727  return -1;
00728 }
00729 
00730 // ************************************************************
00731 //  notify external user handler that
00732 //  it is now to safe destroy stream
00733 //  Return code  looks like cancel() return code
00734 //  0  - notified               NOTIFIED
00735 //  1  - nothing to notify      ALLDONE
00736 //  2  - unable to notify       NOT NOTIFIED
00737 // ************************************************************
00738 int
00739 ACE_SSL_Asynch_Stream::notify_close (void)
00740 {
00741   if (this->flags_ & SF_CLOSE_NTF_SENT)  // already sent
00742     return 1;
00743 
00744   if ((this->flags_ & SF_SHUTDOWN_DONE) == 0)  // only after shutdown
00745     return 2;    // too early , we will do later
00746 
00747   if (this->pending_BIO_count () != 0)   // wait for all internal IO
00748     return 2;   // too early , we will do later
00749 
00750   // create result for future notification
00751   ACE_SSL_Asynch_Result * close_result = 0;
00752 
00753   ACE_NEW_RETURN (close_result,
00754                   ACE_SSL_Asynch_Result (*this),
00755                   2);
00756   //@@ Not exception safe!
00757 
00758  int retval =
00759    close_result->post_completion (this->proactor_->implementation ());
00760 
00761  if (retval == 0)
00762    {
00763      this->flags_ |= SF_CLOSE_NTF_SENT;
00764      return 0;
00765    }
00766 
00767  delete close_result;
00768  return 2;
00769 }
00770 
00771 // ************************************************************
00772 //  notify external user handler about user write completion
00773 //  Return code  looks like cancel() return code
00774 //  0  - notified               NOTIFIED/CANCELED
00775 //  1  - nothing to notify      ALLDONE
00776 //  2  - unable to notify       NOT NOTIFIED/CANCELED
00777 // ************************************************************
00778 
00779 int
00780 ACE_SSL_Asynch_Stream::notify_read (int bytes_transferred,
00781                                     int error)
00782 {
00783   if (ext_read_result_ == 0) //nothing to notify
00784     return 1;
00785 
00786   ext_read_result_->set_bytes_transferred (bytes_transferred);
00787   ext_read_result_->set_error (error);
00788 
00789   int retval =  ext_read_result_->post_completion
00790                    (proactor_->implementation());
00791 
00792   if (retval == 0)
00793     {
00794       ext_read_result_ = 0;
00795       return 0;  // success
00796     }
00797 
00798   return 2; // unable to notify
00799 }
00800 
00801 // ************************************************************
00802 //  notify external user handler about user write completion
00803 //  Return code  looks like cancel() return code
00804 //  0  - notified               NOTIFIED/CANCELED
00805 //  1  - nothing to notify      ALLDONE
00806 //  2  - unable to notify       NOT NOTIFIED/CANCELED
00807 // ************************************************************
00808 
00809 int
00810 ACE_SSL_Asynch_Stream::notify_write (int bytes_transferred,
00811                                      int error)
00812 {
00813   if (this->ext_write_result_ == 0) //nothing to notify
00814     return 1;
00815 
00816   this->ext_write_result_->set_bytes_transferred (bytes_transferred);
00817   this->ext_write_result_->set_error (error);
00818 
00819   int retval =
00820     this->ext_write_result_->post_completion (
00821       this->proactor_->implementation ());
00822 
00823   if (retval == 0)
00824     {
00825       this->ext_write_result_ = 0;
00826       return 0;  // success
00827     }
00828 
00829   return 2; // unable to notify
00830 }
00831 
00832 // ************************************************************
00833 // Print SSL errors
00834 // ************************************************************
00835 void
00836 ACE_SSL_Asynch_Stream::print_error (int err_ssl,
00837                                     const ACE_TCHAR * pText)
00838 {
00839   ACE_DEBUG ((LM_DEBUG,
00840               "SSL-error:%d %s\n" ,
00841               err_ssl,
00842               pText));
00843 
00844 #if OPENSSL_VERSION_NUMBER >= 0x0090601fL
00845   // OpenSSL < 0.9.6a doesn't have ERR_error_string_n() function.
00846   unsigned long lerr = 0;
00847   char buf[1024];
00848 
00849   while ((lerr = ERR_get_error()) != 0)
00850     {
00851       ERR_error_string_n (lerr, buf, sizeof buf);
00852 
00853       ACE_DEBUG ((LM_DEBUG, "%s\n", buf));
00854     }
00855 #endif  /* OPENSSL_VERSION_NUMBER */
00856 }
00857 
00858 // ************************************************************
00859 //  BIO helper functions
00860 //  SSL library will ask BIO to do raw I/O
00861 //  BIO will call us to do this
00862 // ************************************************************
00863 int
00864 ACE_SSL_Asynch_Stream::ssl_bio_read (char * buf,
00865                                      size_t len,
00866                                      int & errval)
00867 {
00868   // We do not have to acquire mutex
00869   // as we called already with locked mutex
00870   // from do_SSL_state_machine()
00871 
00872   errval = 0;
00873 
00874   size_t cur_len = this->bio_inp_msg_.length ();
00875 
00876   if (cur_len > 0) // there are more data buffered
00877     {
00878       const char * rd_ptr = this->bio_inp_msg_.rd_ptr ();
00879 
00880       if (cur_len > len)
00881         cur_len = len;
00882 
00883       ACE_OS::memcpy (buf, rd_ptr, cur_len);
00884 
00885       this->bio_inp_msg_.rd_ptr (cur_len); // go ahead
00886 
00887       return cur_len;
00888     }
00889 
00890   if (this->bio_inp_errno_ != 0)     // if was error - it is permanent !
00891     {
00892       errval = this->bio_inp_errno_;
00893       return -1;
00894     }
00895 
00896   if (this->bio_inp_flag_ & BF_EOS)  // End of stream
00897     return 0;
00898 
00899   errval = EINPROGRESS;          // SSL will try later
00900 
00901   if (this->bio_inp_flag_ & BF_AIO)  // we are busy
00902     return -1;
00903 
00904   if (this->bio_inp_msg_.size (len) != 0)
00905     {
00906       ACE_ERROR
00907         ((LM_ERROR,
00908           ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00909           ACE_TEXT ("error in ACE_Message_Block::size() ")
00910           ));
00911 
00912       errval = EINVAL;
00913       return -1;
00914     }
00915 
00916   char * base = this->bio_inp_msg_.base ();
00917 
00918   this->bio_inp_msg_.rd_ptr (base);
00919   this->bio_inp_msg_.wr_ptr (base);
00920 
00921   if (this->bio_istream_.read (
00922         bio_inp_msg_,  // message block
00923         len,           // priority
00924         0,             // act
00925         0,             // priority
00926         ACE_SIGRTMIN   // default signal
00927         ) == -1)
00928     {
00929       ACE_ERROR
00930         ((LM_ERROR,
00931           ACE_TEXT ("%N:%l (%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00932           ACE_TEXT ("attempt read failed")
00933           ));
00934 
00935       errval = EINVAL;  // may be leave EINPROGRESS ??
00936       return -1;        // to try later
00937     }
00938 
00939   this->bio_inp_flag_ |= BF_AIO;  // AIO is active
00940 
00941   return -1;
00942 }
00943 
00944 
00945 int
00946 ACE_SSL_Asynch_Stream::ssl_bio_write (const char * buf,
00947                                       size_t len,
00948                                       int & errval)
00949 {
00950   // We do not have to acquire mutex
00951   // as we called already with locked mutex
00952   // from do_SSL_state_machine
00953 
00954   errval = 0;
00955 
00956   if (this->bio_out_flag_ & BF_AIO)  // sorry, we are busy
00957     {
00958       errval = EINPROGRESS;   // try later
00959       return -1;
00960     }
00961 
00962   if (this->bio_out_errno_ != 0)      // no recovery
00963     {
00964       errval = this->bio_out_errno_;
00965       return -1;
00966     }
00967 
00968   if (this->bio_out_msg_.size (len) != 0)
00969     {
00970       ACE_ERROR
00971         ((LM_ERROR,
00972           ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00973           ACE_TEXT ("error in ACE_Message_Block::size() ")
00974           ));
00975 
00976       errval = EINVAL;
00977       return -1;
00978     }
00979 
00980   char * base = this->bio_out_msg_.base ();
00981 
00982   this->bio_out_msg_.rd_ptr (base);
00983   this->bio_out_msg_.wr_ptr (base);
00984 
00985   if (this->bio_out_msg_.copy (buf, len) == -1)
00986     {
00987       ACE_ERROR
00988         ((LM_ERROR,
00989           ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00990           ACE_TEXT ("error in ACE_Message_Block::copy() ")
00991           ));
00992 
00993       errval = EINVAL;
00994       return -1;
00995     }
00996 
00997 
00998   if (this->bio_ostream_.write (
00999         this->bio_out_msg_, // message block
01000         len,          // priority
01001         0,            // act
01002         0,            // priority
01003         ACE_SIGRTMIN  // default signal
01004         ) == -1)
01005     {
01006       ACE_ERROR
01007         ((LM_ERROR,
01008           ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
01009           ACE_TEXT ("attempt write failed")
01010           ));
01011 
01012       errval = EINVAL;  // may be leave EINPROGRESS ??
01013       return -1;        // to try later
01014     }
01015 
01016   this->bio_out_flag_ |= BF_AIO;  // AIO is active
01017   errval = 0;               // Ok, go ahead
01018 
01019   return len;
01020 }
01021 
01022 // ************************************************************
01023 //  Internal IO handlers
01024 //  virtual from ACE_Service_Handler
01025 // ************************************************************
01026 void
01027 ACE_SSL_Asynch_Stream::handle_write_stream (
01028   const ACE_Asynch_Write_Stream::Result &result)
01029 {
01030   ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
01031 
01032   this->bio_out_flag_ &= ~BF_AIO;
01033 
01034   ACE_Message_Block & mb = result.message_block ();
01035 
01036   size_t bytes_req = result.bytes_to_write ();
01037   size_t bytes_trn = result.bytes_transferred ();
01038   u_long errval    = result.error ();
01039   size_t len       = bytes_req - bytes_trn;
01040 
01041   if (errval != 0)                    // error ?
01042     this->bio_out_errno_ = errval;    // save error code
01043   else if (len > 0)                   // TCP/IP overloaded ?
01044     {                                 // continue, rd_ptr at right place
01045       if (this->bio_ostream_.write (
01046             mb,          // message block
01047             len,         // priority
01048             0,           // act
01049             0,           // priority
01050             ACE_SIGRTMIN // default signal
01051             ) == 0)
01052         {
01053           this->bio_out_flag_ |= BF_AIO;
01054           return;
01055         }
01056 
01057       ACE_ERROR
01058         ((LM_ERROR,
01059           ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
01060           ACE_TEXT ("attempt write failed")
01061           ));
01062 
01063       this->bio_out_errno_ = EINVAL;
01064     }
01065 
01066   this->do_SSL_state_machine ();
01067 
01068   return;
01069 }
01070 
01071 void
01072 ACE_SSL_Asynch_Stream::handle_read_stream (
01073   const ACE_Asynch_Read_Stream::Result &result)
01074 {
01075   ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
01076 
01077   this->bio_inp_flag_ &= ~BF_AIO;
01078 
01079   size_t bytes_trn = result.bytes_transferred ();
01080   u_long errval    = result.error ();
01081 
01082   if (errval != 0)                     // error ?
01083      this->bio_inp_errno_ = errval;    // save error code
01084   else if (bytes_trn == 0)             // end of stream ?
01085      this->bio_inp_flag_ |= BF_EOS;    // set flag EOS
01086 
01087   this->do_SSL_state_machine ();
01088 
01089   return;
01090 }
01091 
01092 void
01093 ACE_SSL_Asynch_Stream::handle_wakeup (void)
01094 {
01095   ACE_Handler * user_handler = 0;
01096 
01097   {
01098     ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
01099 
01100     this->flags_ |= SF_DELETE_ENABLE;
01101 
01102     user_handler = this->ext_handler_;
01103   }
01104 
01105   if (user_handler != 0)
01106     user_handler->handle_wakeup();
01107 }
01108 
01109 int
01110 ACE_SSL_Asynch_Stream::pending_BIO_count (void)
01111 {
01112   int ret = 0;
01113 
01114   if (this->bio_inp_flag_ & BF_AIO)
01115     ret++;
01116 
01117   if (this->bio_out_flag_ & BF_AIO)
01118     return ret++;
01119 
01120   return ret;
01121 }
01122 
01123 #endif  /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
01124            ACE_HAS_AIO_CALLS) */

Generated on Mon Jun 16 13:15:54 2003 for ACE_SSL by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002