SSL_Asynch_Stream.cpp

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

Generated on Sun Jan 27 13:03:21 2008 for ACE_SSL by doxygen 1.3.6