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            "SSL_Asynch_Stream.cpp,v 1.16 2006/06/22 15:10:08 shuston Exp")
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   const int bytes_trn = ::SSL_read (this->ssl_,
00554                                     mb.wr_ptr (),
00555                                     bytes_req);
00556 
00557   int status = ::SSL_get_error (this->ssl_, bytes_trn);
00558 
00559   switch (status)
00560     {
00561     case SSL_ERROR_NONE:
00562       this->notify_read (bytes_trn, 0);
00563       return 1;
00564 
00565     case SSL_ERROR_WANT_READ:
00566     case SSL_ERROR_WANT_WRITE:
00567       return 0;
00568 
00569     case SSL_ERROR_ZERO_RETURN:
00570       this->notify_read (0, 0);
00571       return 1;
00572 
00573     case SSL_ERROR_SYSCALL:
00574       if (bytes_trn == 0)
00575         {
00576           this->notify_read (0, 0);
00577           return 1;
00578         }
00579       // If not an EOF, then fall through to "default" case.
00580 
00581     default:
00582       break;
00583     }
00584 
00585  this->notify_read (0, EFAULT);
00586  this->print_error (status,
00587                     ACE_TEXT ("SSL_read error"));
00588 
00589  return -1;
00590 }
00591 
00592 // ************************************************************
00593 // Perform SSL_write call if necessary  and notify user
00594 // ************************************************************
00595 int
00596 ACE_SSL_Asynch_Stream::do_SSL_write (void)
00597 {
00598   if (this->ext_write_result_ == 0)  // nothing to do
00599     return 0;
00600 
00601   if (this->flags_ & SF_REQ_SHUTDOWN)
00602     {
00603       this->notify_write (0, ERR_CANCELED);
00604       return -1;
00605     }
00606 
00607   ACE_Message_Block & mb = this->ext_write_result_->message_block ();
00608   size_t       bytes_req = this->ext_write_result_->bytes_to_write ();
00609 
00610   const int bytes_trn = ::SSL_write (this->ssl_,
00611                                      mb.rd_ptr (),
00612                                      bytes_req);
00613 
00614   int status = ::SSL_get_error (this->ssl_, bytes_trn);
00615 
00616   switch (status)
00617     {
00618     case SSL_ERROR_NONE:
00619       this->notify_write (bytes_trn, 0);
00620       return 1;
00621 
00622     case SSL_ERROR_WANT_READ:
00623     case SSL_ERROR_WANT_WRITE:
00624       return 0;
00625 
00626     case SSL_ERROR_ZERO_RETURN:
00627       this->notify_write (bytes_trn, 0);
00628       return 1;
00629 
00630     case SSL_ERROR_SYSCALL:
00631     default:
00632       break;
00633     }
00634 
00635  this->notify_write(0, EFAULT);
00636  this->print_error (status,
00637                     ACE_TEXT ("SSL_write error"));
00638 
00639  return -1;
00640 }
00641 
00642 // ************************************************************
00643 //  notify external user handler that
00644 //  it is now to safe destroy stream
00645 //  Return code  looks like cancel() return code
00646 //  0  - notified               NOTIFIED
00647 //  1  - nothing to notify      ALLDONE
00648 //  2  - unable to notify       NOT NOTIFIED
00649 // ************************************************************
00650 int
00651 ACE_SSL_Asynch_Stream::notify_close (void)
00652 {
00653   if (this->flags_ & SF_CLOSE_NTF_SENT)  // already sent
00654     return 1;
00655 
00656   if ((this->flags_ & SF_SHUTDOWN_DONE) == 0)  // only after shutdown
00657     return 2;    // too early , we will do later
00658 
00659   if (this->pending_BIO_count () != 0)   // wait for all internal IO
00660     return 2;   // too early , we will do later
00661 
00662   // create result for future notification
00663   ACE_SSL_Asynch_Result * close_result = 0;
00664 
00665   ACE_NEW_RETURN (close_result,
00666                   ACE_SSL_Asynch_Result (*this),
00667                   2);
00668   //@@ Not exception safe!
00669 
00670  int retval =
00671    close_result->post_completion (this->proactor_->implementation ());
00672 
00673  if (retval == 0)
00674    {
00675      this->flags_ |= SF_CLOSE_NTF_SENT;
00676      return 0;
00677    }
00678 
00679  delete close_result;
00680  return 2;
00681 }
00682 
00683 // ************************************************************
00684 //  notify external user handler about user write completion
00685 //  Return code  looks like cancel() return code
00686 //  0  - notified               NOTIFIED/CANCELED
00687 //  1  - nothing to notify      ALLDONE
00688 //  2  - unable to notify       NOT NOTIFIED/CANCELED
00689 // ************************************************************
00690 
00691 int
00692 ACE_SSL_Asynch_Stream::notify_read (int bytes_transferred,
00693                                     int error)
00694 {
00695   if (ext_read_result_ == 0) //nothing to notify
00696     return 1;
00697 
00698   this->ext_read_result_->set_bytes_transferred (bytes_transferred);
00699   this->ext_read_result_->set_error (error);
00700 
00701   int retval =
00702     this->ext_read_result_->post_completion (proactor_->implementation ());
00703 
00704   if (retval == 0)
00705     {
00706       this->ext_read_result_ = 0;
00707       return 0;  // success
00708     }
00709 
00710   return 2; // unable to notify
00711 }
00712 
00713 // ************************************************************
00714 //  notify external user handler about user write completion
00715 //  Return code  looks like cancel() return code
00716 //  0  - notified               NOTIFIED/CANCELED
00717 //  1  - nothing to notify      ALLDONE
00718 //  2  - unable to notify       NOT NOTIFIED/CANCELED
00719 // ************************************************************
00720 
00721 int
00722 ACE_SSL_Asynch_Stream::notify_write (int bytes_transferred,
00723                                      int error)
00724 {
00725   if (this->ext_write_result_ == 0) //nothing to notify
00726     return 1;
00727 
00728   this->ext_write_result_->set_bytes_transferred (bytes_transferred);
00729   this->ext_write_result_->set_error (error);
00730 
00731   int retval =
00732     this->ext_write_result_->post_completion (
00733       this->proactor_->implementation ());
00734 
00735   if (retval == 0)
00736     {
00737       this->ext_write_result_ = 0;
00738       return 0;  // success
00739     }
00740 
00741   return 2; // unable to notify
00742 }
00743 
00744 // ************************************************************
00745 // Print SSL errors
00746 // ************************************************************
00747 void
00748 ACE_SSL_Asynch_Stream::print_error (int err_ssl,
00749                                     const ACE_TCHAR * pText)
00750 {
00751   ACE_DEBUG ((LM_DEBUG,
00752               "SSL-error:%d %s\n" ,
00753               err_ssl,
00754               pText));
00755 
00756 #if OPENSSL_VERSION_NUMBER >= 0x0090601fL
00757   // OpenSSL < 0.9.6a doesn't have ERR_error_string_n() function.
00758   unsigned long lerr = 0;
00759   char buf[1024];
00760 
00761   while ((lerr = ERR_get_error()) != 0)
00762     {
00763       ERR_error_string_n (lerr, buf, sizeof buf);
00764 
00765       ACE_DEBUG ((LM_DEBUG, "%s\n", buf));
00766     }
00767 #endif  /* OPENSSL_VERSION_NUMBER */
00768 }
00769 
00770 // ************************************************************
00771 //  BIO helper functions
00772 //  SSL library will ask BIO to do raw I/O
00773 //  BIO will call us to do this
00774 // ************************************************************
00775 int
00776 ACE_SSL_Asynch_Stream::ssl_bio_read (char * buf,
00777                                      size_t len,
00778                                      int & errval)
00779 {
00780   // We do not have to acquire mutex
00781   // as we called already with locked mutex
00782   // from do_SSL_state_machine()
00783 
00784   errval = 0;
00785 
00786   size_t cur_len = this->bio_inp_msg_.length ();
00787 
00788   if (cur_len > 0) // there are more data buffered
00789     {
00790       const char * rd_ptr = this->bio_inp_msg_.rd_ptr ();
00791 
00792       if (cur_len > len)
00793         cur_len = len;
00794 
00795       ACE_OS::memcpy (buf, rd_ptr, cur_len);
00796 
00797       this->bio_inp_msg_.rd_ptr (cur_len); // go ahead
00798 
00799       return cur_len;
00800     }
00801 
00802   if (this->bio_inp_errno_ != 0)     // if was error - it is permanent !
00803     {
00804       errval = this->bio_inp_errno_;
00805       return -1;
00806     }
00807 
00808   if (this->bio_inp_flag_ & BF_EOS)  // End of stream
00809     return 0;
00810 
00811   errval = EINPROGRESS;          // SSL will try later
00812 
00813   if (this->bio_inp_flag_ & BF_AIO)  // we are busy
00814     return -1;
00815 
00816   if (this->bio_inp_msg_.size (len) != 0)
00817     {
00818       ACE_ERROR
00819         ((LM_ERROR,
00820           ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00821           ACE_TEXT ("error in ACE_Message_Block::size() ")
00822           ));
00823 
00824       errval = EINVAL;
00825       return -1;
00826     }
00827 
00828   char * base = this->bio_inp_msg_.base ();
00829 
00830   this->bio_inp_msg_.rd_ptr (base);
00831   this->bio_inp_msg_.wr_ptr (base);
00832 
00833   if (this->bio_istream_.read (
00834         bio_inp_msg_,  // message block
00835         len,           // priority
00836         0,             // act
00837         0,             // priority
00838         ACE_SIGRTMIN   // default signal
00839         ) == -1)
00840     {
00841       ACE_ERROR
00842         ((LM_ERROR,
00843           ACE_TEXT ("%N:%l (%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00844           ACE_TEXT ("attempt read failed")
00845           ));
00846 
00847       errval = EINVAL;  // may be leave EINPROGRESS ??
00848       return -1;        // to try later
00849     }
00850 
00851   this->bio_inp_flag_ |= BF_AIO;  // AIO is active
00852 
00853   return -1;
00854 }
00855 
00856 
00857 int
00858 ACE_SSL_Asynch_Stream::ssl_bio_write (const char * buf,
00859                                       size_t len,
00860                                       int & errval)
00861 {
00862   // We do not have to acquire mutex
00863   // as we called already with locked mutex
00864   // from do_SSL_state_machine
00865 
00866   errval = 0;
00867 
00868   if (this->bio_out_flag_ & BF_AIO)  // sorry, we are busy
00869     {
00870       errval = EINPROGRESS;   // try later
00871       return -1;
00872     }
00873 
00874   if (this->bio_out_errno_ != 0)      // no recovery
00875     {
00876       errval = this->bio_out_errno_;
00877       return -1;
00878     }
00879 
00880   if (this->bio_out_msg_.size (len) != 0)
00881     {
00882       ACE_ERROR
00883         ((LM_ERROR,
00884           ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00885           ACE_TEXT ("error in ACE_Message_Block::size() ")
00886           ));
00887 
00888       errval = EINVAL;
00889       return -1;
00890     }
00891 
00892   char * base = this->bio_out_msg_.base ();
00893 
00894   this->bio_out_msg_.rd_ptr (base);
00895   this->bio_out_msg_.wr_ptr (base);
00896 
00897   if (this->bio_out_msg_.copy (buf, len) == -1)
00898     {
00899       ACE_ERROR
00900         ((LM_ERROR,
00901           ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00902           ACE_TEXT ("error in ACE_Message_Block::copy() ")
00903           ));
00904 
00905       errval = EINVAL;
00906       return -1;
00907     }
00908 
00909 
00910   if (this->bio_ostream_.write (
00911         this->bio_out_msg_, // message block
00912         len,          // priority
00913         0,            // act
00914         0,            // priority
00915         ACE_SIGRTMIN  // default signal
00916         ) == -1)
00917     {
00918       ACE_ERROR
00919         ((LM_ERROR,
00920           ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00921           ACE_TEXT ("attempt write failed")
00922           ));
00923 
00924       errval = EINVAL;  // may be leave EINPROGRESS ??
00925       return -1;        // to try later
00926     }
00927 
00928   this->bio_out_flag_ |= BF_AIO;  // AIO is active
00929   errval = 0;               // Ok, go ahead
00930 
00931   return len;
00932 }
00933 
00934 // ************************************************************
00935 //  Internal IO handlers
00936 //  virtual from ACE_Service_Handler
00937 // ************************************************************
00938 void
00939 ACE_SSL_Asynch_Stream::handle_write_stream (
00940   const ACE_Asynch_Write_Stream::Result &result)
00941 {
00942   ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
00943 
00944   this->bio_out_flag_ &= ~BF_AIO;
00945 
00946   ACE_Message_Block & mb = result.message_block ();
00947 
00948   size_t bytes_req = result.bytes_to_write ();
00949   size_t bytes_trn = result.bytes_transferred ();
00950   u_long errval    = result.error ();
00951   size_t len       = bytes_req - bytes_trn;
00952 
00953   if (errval != 0)                    // error ?
00954     this->bio_out_errno_ = errval;    // save error code
00955   else if (len > 0)                   // TCP/IP overloaded ?
00956     {                                 // continue, rd_ptr at right place
00957       if (this->bio_ostream_.write (
00958             mb,          // message block
00959             len,         // priority
00960             0,           // act
00961             0,           // priority
00962             ACE_SIGRTMIN // default signal
00963             ) == 0)
00964         {
00965           this->bio_out_flag_ |= BF_AIO;
00966           return;
00967         }
00968 
00969       ACE_ERROR
00970         ((LM_ERROR,
00971           ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
00972           ACE_TEXT ("attempt write failed")
00973           ));
00974 
00975       this->bio_out_errno_ = EINVAL;
00976     }
00977 
00978   this->do_SSL_state_machine ();
00979 
00980   return;
00981 }
00982 
00983 void
00984 ACE_SSL_Asynch_Stream::handle_read_stream (
00985   const ACE_Asynch_Read_Stream::Result &result)
00986 {
00987   ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
00988 
00989   this->bio_inp_flag_ &= ~BF_AIO;
00990 
00991   size_t bytes_trn = result.bytes_transferred ();
00992   u_long errval    = result.error ();
00993 
00994   if (errval != 0)                     // error ?
00995      this->bio_inp_errno_ = errval;    // save error code
00996   else if (bytes_trn == 0)             // end of stream ?
00997      this->bio_inp_flag_ |= BF_EOS;    // set flag EOS
00998 
00999   this->do_SSL_state_machine ();
01000 
01001   return;
01002 }
01003 
01004 void
01005 ACE_SSL_Asynch_Stream::handle_wakeup (void)
01006 {
01007   ACE_Handler * user_handler = 0;
01008 
01009   {
01010     ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
01011 
01012     this->flags_ |= SF_DELETE_ENABLE;
01013 
01014     user_handler = this->ext_handler_;
01015   }
01016 
01017   if (user_handler != 0)
01018     user_handler->handle_wakeup();
01019 }
01020 
01021 int
01022 ACE_SSL_Asynch_Stream::pending_BIO_count (void)
01023 {
01024   int ret = 0;
01025 
01026   if (this->bio_inp_flag_ & BF_AIO)
01027     ++ret;
01028 
01029   if (this->bio_out_flag_ & BF_AIO)
01030     ++ret;
01031 
01032   return ret;
01033 }
01034 
01035 ACE_END_VERSIONED_NAMESPACE_DECL
01036 
01037 #endif  /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
01038            ACE_HAS_AIO_CALLS) */

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