diff options
Diffstat (limited to 'ACE/ace/SSL/SSL_Asynch_Stream.cpp')
-rw-r--r-- | ACE/ace/SSL/SSL_Asynch_Stream.cpp | 1042 |
1 files changed, 0 insertions, 1042 deletions
diff --git a/ACE/ace/SSL/SSL_Asynch_Stream.cpp b/ACE/ace/SSL/SSL_Asynch_Stream.cpp deleted file mode 100644 index 877125d19c4..00000000000 --- a/ACE/ace/SSL/SSL_Asynch_Stream.cpp +++ /dev/null @@ -1,1042 +0,0 @@ -#include "SSL_Asynch_Stream.h" - -ACE_RCSID (ACE_SSL, - SSL_Asynch_Stream, - "$Id$") - -// This only works on platforms with Asynchronous IO support. -#if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS))) - -#if defined (ACE_WIN32) -# include "ace/WIN32_Proactor.h" -#else -# include "ace/POSIX_Proactor.h" -#endif /* ACE_WIN32 */ - -#include "ace/OS_NS_string.h" -#include "ace/Proactor.h" - -#include <openssl/err.h> - -ACE_BEGIN_VERSIONED_NAMESPACE_DECL - -ACE_SSL_Asynch_Write_Stream_Result::ACE_SSL_Asynch_Write_Stream_Result - (ACE_Handler & handler, - ACE_HANDLE handle, - ACE_Message_Block & message_block, - size_t bytes_to_write, - const void * act, - ACE_HANDLE event, - int priority, - int signal_number - ) - : AWS_RESULT (handler.proxy (), - handle, - message_block, - bytes_to_write, - act, - event, - priority, - signal_number - ) -{ -} - -ACE_SSL_Asynch_Read_Stream_Result::ACE_SSL_Asynch_Read_Stream_Result - (ACE_Handler & handler, - ACE_HANDLE handle, - ACE_Message_Block & message_block, - size_t bytes_to_read, - const void * act, - ACE_HANDLE event, - int priority, - int signal_number - ) - : ARS_RESULT (handler.proxy (), - handle, - message_block, - bytes_to_read, - act, - event, - priority, - signal_number - ) -{ -} - -ACE_SSL_Asynch_Result::ACE_SSL_Asynch_Result (ACE_Handler & handler) - : A_RESULT (handler.proxy (), - 0, // act, - ACE_INVALID_HANDLE, - 0, // Offset - 0, // OffsetHigh - 0, // Priority - ACE_SIGRTMIN //signal_number - ) -{ -} - -void -ACE_SSL_Asynch_Result::complete (size_t /* bytes_transferred */, - int /* success */, - const void * /* completion_key */, - u_long /* error */) -{ - this->handler_proxy_->handler ()->handle_wakeup (); -} - -// ************************************************************ -// ACE_SSL_Asynch_Stream Constructor / Destructor -// ************************************************************ -ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream ( - ACE_SSL_Asynch_Stream::Stream_Type s_type, - ACE_SSL_Context * context) - : type_ (s_type), - handle_ (ACE_INVALID_HANDLE), - proactor_ (0), - ext_handler_ (0), - ext_read_result_ (0), - ext_write_result_(0), - flags_ (0), - ssl_ (0), - bio_ (0), - bio_istream_ (), - bio_inp_msg_ (), - bio_inp_errno_(0), - bio_inp_flag_ (0), - bio_ostream_ (), - bio_out_msg_ (), - bio_out_errno_(0), - bio_out_flag_ (0), - mutex_ () -{ - ACE_TRACE ("ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream"); - // was honestly copied from ACE_SSL_SOCK_Stream :) - - ACE_SSL_Context * ctx = - (context == 0 ? ACE_SSL_Context::instance () : context); - - this->ssl_ = ::SSL_new (ctx->context ()); - - if (this->ssl_ == 0) - ACE_ERROR - ((LM_ERROR, - ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"), - ACE_TEXT ("- cannot allocate new SSL structure") - )); - -} - -ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream (void) -{ - ACE_TRACE ("ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream"); - - - // It is safe to delete stream if all notifications are received, - // i.e., state is SF_DELETE_ENABLE or if proactor event loop is - // done. - if (this->flags_ & SF_STREAM_OPEN) // open - if ((this->flags_ & SF_DELETE_ENABLE) == 0) // but .. - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT("ACE_SSL_Asynch_Stream::DTOR-") - ACE_TEXT("possible access violation ") - ACE_TEXT("if proactor still handles events\n"))); - - ::SSL_free (this->ssl_); - - // Was honestly copied from ACE_SSL_SOCK_Stream :) - - // @@ Question: should we reference count the Context object or - // leave that to the application developer? We do not reference - // count reactors (for example) and following some simple rules - // seems to work fine! -} - -// ************************************************************ -// close () -// returns : -// 0 - Stream is in the state SF_DELETE_ENABLE, -// so it is safe to delete stream -// -1 - Stream has pending AIO requests, -// close should be repeated later one more -// ************************************************************ - -int -ACE_SSL_Asynch_Stream::close (void) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); - - if ((flags_ & SF_STREAM_OPEN) == 0) // not open - flags_ |= SF_DELETE_ENABLE; - - if (flags_ & SF_DELETE_ENABLE) - return 0; - - flags_ |= SF_REQ_SHUTDOWN; - - this->do_SSL_state_machine (); - - return -1; -} - -// ************************************************************ -// Asynch_Operation interface -// cancel -// ************************************************************ -int -ACE_SSL_Asynch_Stream::cancel (void) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); - - if ((flags_ & SF_STREAM_OPEN) == 0) // not open - return 1; // AIO_ALLDONE - - // attempt to cancel internal, i.e. user's read/write - int rc_r_int = bio_istream_.cancel(); - int rc_w_int = bio_ostream_.cancel(); - - // attempt to cancel external, i.e. bio_ssl read/write - int rc_r_ext = notify_read (0, ERR_CANCELED); - int rc_w_ext = notify_write (0, ERR_CANCELED); - - if (rc_r_int < 0 || rc_w_int < 0 - && rc_r_ext < 0 || rc_w_ext < 0) - return -1; // at least one error - - if (rc_r_int == 1 && rc_w_int == 1 - && rc_r_ext == 1 && rc_w_ext == 1) - return 1; // AIO_ALLDONE - - if (rc_r_int == 2 || rc_w_int == 2 - && rc_r_ext == 2 || rc_w_ext == 2) - return 2; // AIO_NOT_CANCELED , at least one not canceled - - return 0; // AIO_CANCELED, at least will be one notification -} - -// ************************************************************ -// Asynch_Operation interface -// open -// ************************************************************ -int -ACE_SSL_Asynch_Stream::open (ACE_Handler & handler, - ACE_HANDLE handle, - const void * completion_key, - ACE_Proactor * proactor) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); - - if (this->flags_ & SF_STREAM_OPEN) - ACE_ERROR_RETURN - ((LM_ERROR, - ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), - ACE_TEXT ("- already opened")), - -1); - - if (this->ssl_ == 0) - ACE_ERROR_RETURN - ((LM_ERROR, - ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), - ACE_TEXT ("- SSL structure is absent")), - -1); - - if (handle == ACE_INVALID_HANDLE) - ACE_ERROR_RETURN - ((LM_ERROR, - ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), - ACE_TEXT ("- invalid handle")), - -1); - - - // Get a proactor for/from the user. - this->proactor_ = this->get_proactor (proactor, handler); - this->ext_handler_ = & handler; - this->handle_ = handle; - - // Open internal input stream - if (this->bio_istream_.open (*this, // real callbacks to this - handle, - completion_key, - this->proactor_) != 0) - return -1; - - // Open internal output stream - if (this->bio_ostream_.open (*this, // real callbacks to this - handle, - completion_key, - this->proactor_) != 0) - return -1; - - this->bio_ = ACE_SSL_make_BIO (this); - - if (this->bio_ == 0) - ACE_ERROR_RETURN - ((LM_ERROR, - ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), - ACE_TEXT ("- cannot allocate new BIO structure")), - -1); - - ::SSL_set_bio (this->ssl_ , this->bio_ , this->bio_); - - switch (this->type_) - { - case ST_CLIENT: - ::SSL_set_connect_state (this->ssl_); - break; - - case ST_SERVER: - ::SSL_set_accept_state (this->ssl_); - break; - - default: - ACE_ERROR_RETURN - ((LM_ERROR, - ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), - ACE_TEXT ("- invalid stream type")), - -1); - } - - this->flags_ |= SF_STREAM_OPEN; - - this->do_SSL_state_machine (); - - return 0; -} - - -// ************************************************************ -// Asynch_Operation interface -// read -// ************************************************************ -int -ACE_SSL_Asynch_Stream::read (ACE_Message_Block & message_block, - size_t bytes_to_read, - const void * act, - int priority, - int signal_number) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); - - if ((this->flags_ & SF_STREAM_OPEN) == 0) // not open - return -1; - - if (this->flags_ & SF_REQ_SHUTDOWN) - return -1; - - // only one read operation is allowed now - // later it will be possible to make a queue - - if (this->ext_read_result_ != 0) - return -1; - - // create result for future notification - ACE_NEW_RETURN (this->ext_read_result_, - ACE_SSL_Asynch_Read_Stream_Result ( - *this->ext_handler_, - this->handle_, - message_block, - bytes_to_read, - act, - this->proactor_->get_handle(), - priority, - signal_number), - -1); - - this->do_SSL_state_machine (); // ignore return code - - return 0; -} - -// ************************************************************ -// Asynch_Operation interface -// write -// ************************************************************ -int -ACE_SSL_Asynch_Stream::write (ACE_Message_Block & message_block, - size_t bytes_to_write, - const void * act, - int priority, - int signal_number) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); - - if ((this->flags_ & SF_STREAM_OPEN) == 0) // not open - return -1; - - if (this->flags_ & SF_REQ_SHUTDOWN) - return -1; - - // only one read operation is allowed now - // later it will be possible to make a queue - - if (this->ext_write_result_ != 0) - return -1; - - // create result for future notification - ACE_NEW_RETURN (this->ext_write_result_, - ACE_SSL_Asynch_Write_Stream_Result ( - *this->ext_handler_, - this->handle_, - message_block, - bytes_to_write, - act, - this->proactor_->get_handle(), - priority, - signal_number), - -1); - - this->do_SSL_state_machine (); - - return 0; -} - -// ************************************************************ -// Main SSL engine -// ************************************************************ -int -ACE_SSL_Asynch_Stream::do_SSL_state_machine (void) -{ - // this protected member should be called - // with locked mutex_ - - int retval = this->do_SSL_handshake (); - - if (retval == 0) // handshake in progress ? - return 0; - - if (retval < 0) - this->flags_ |= SF_REQ_SHUTDOWN; - - this->do_SSL_read (); // execute user read request - this->do_SSL_write (); // execute user write request - - if ((this->flags_ & SF_REQ_SHUTDOWN) == 0) // Do we have any errors - return 0; - - this->do_SSL_shutdown (); - - this->notify_close (); - - return 0; -} - -// ************************************************************ -// do_SSL_shutdown -// return code: -// 1 SSL shutdown is finished already, success -// 0 SSL shutdown in progress -// -1 failure -// ************************************************************ -int -ACE_SSL_Asynch_Stream::do_SSL_shutdown (void) -{ - if (this->flags_ & SF_SHUTDOWN_DONE) // already done - return 1; - - this->flags_ |= SF_REQ_SHUTDOWN; - - // if we have any uncompleted user requests - // than cancel its - this->notify_read (0, ERR_CANCELED); - this->notify_write (0, ERR_CANCELED); - - int retval = ::SSL_shutdown (this->ssl_); - - int status = ::SSL_get_error (this->ssl_, retval); - - switch (status) - { - case SSL_ERROR_NONE: - case SSL_ERROR_ZERO_RETURN: - case SSL_ERROR_SYSCALL: - retval = 1; - break; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_CONNECT: - // case SSL_ERROR_WANT_ACCEPT: - case SSL_ERROR_WANT_X509_LOOKUP: - return 0; - - default: - this->print_error (status, - ACE_TEXT ("Shutdown error")); - retval = -1; - break; - } - - this->flags_ |= SF_SHUTDOWN_DONE; - - return retval; -} - -// ************************************************************ -// Do SSL handshake if necessary -// return code: -// 1 SSL handshake is finished already, success -// 0 SSL handshake in progress -// -1 failure -// ************************************************************ -int -ACE_SSL_Asynch_Stream::do_SSL_handshake (void) -{ - if (SSL_is_init_finished (this->ssl_)) - return 1; - - if (this->flags_ & SF_REQ_SHUTDOWN) - return -1; - - int retval = -1; - - switch (this->type_) - { - case ST_CLIENT: - retval = ::SSL_connect (this->ssl_); - break; - - case ST_SERVER: - retval = ::SSL_accept (this->ssl_); - break; - - default: - ACE_ERROR_RETURN - ((LM_ERROR, - ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"), - ACE_TEXT ("- invalid stream type")), - -1); - } - - int status = ::SSL_get_error (this->ssl_, retval); - - switch (status) - { - case SSL_ERROR_NONE: - break; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_CONNECT: - //case SSL_ERROR_WANT_ACCEPT: - case SSL_ERROR_WANT_X509_LOOKUP: - return 0; - - case SSL_ERROR_ZERO_RETURN: - case SSL_ERROR_SYSCALL: - default: - this->print_error (status, - ACE_TEXT ("Handshake error")); - return -1; - } - - return 1; -} - -// ************************************************************ -// Perform SSL_read call if necessary and notify user -// ************************************************************ -int -ACE_SSL_Asynch_Stream::do_SSL_read (void) -{ - if (this->ext_read_result_ == 0) // nothing to do - return 0; - - if (this->flags_ & SF_REQ_SHUTDOWN) - { - this->notify_read (0, ERR_CANCELED); - return -1; - } - - ACE_Message_Block & mb = this->ext_read_result_->message_block (); - size_t bytes_req = this->ext_read_result_->bytes_to_read (); - - ERR_clear_error(); - - const int bytes_trn = ::SSL_read (this->ssl_, - mb.wr_ptr (), - bytes_req); - - int const status = ::SSL_get_error (this->ssl_, bytes_trn); - - switch (status) - { - case SSL_ERROR_NONE: - this->notify_read (bytes_trn, 0); - return 1; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - return 0; - - case SSL_ERROR_ZERO_RETURN: - this->notify_read (0, 0); - return 1; - - case SSL_ERROR_SYSCALL: - if (bytes_trn == 0) - { - this->notify_read (0, 0); - return 1; - } - // If not an EOF, then fall through to "default" case. - - default: - break; - } - - this->notify_read (0, EFAULT); - this->print_error (status, - ACE_TEXT ("SSL_read error")); - - return -1; -} - -// ************************************************************ -// Perform SSL_write call if necessary and notify user -// ************************************************************ -int -ACE_SSL_Asynch_Stream::do_SSL_write (void) -{ - if (this->ext_write_result_ == 0) // nothing to do - return 0; - - if (this->flags_ & SF_REQ_SHUTDOWN) - { - this->notify_write (0, ERR_CANCELED); - return -1; - } - - ACE_Message_Block & mb = this->ext_write_result_->message_block (); - size_t bytes_req = this->ext_write_result_->bytes_to_write (); - - ERR_clear_error(); - - const int bytes_trn = ::SSL_write (this->ssl_, - mb.rd_ptr (), - bytes_req); - - int const status = ::SSL_get_error (this->ssl_, bytes_trn); - - switch (status) - { - case SSL_ERROR_NONE: - this->notify_write (bytes_trn, 0); - return 1; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - return 0; - - case SSL_ERROR_ZERO_RETURN: - this->notify_write (bytes_trn, 0); - return 1; - - case SSL_ERROR_SYSCALL: - default: - break; - } - - this->notify_write(0, EFAULT); - this->print_error (status, - ACE_TEXT ("SSL_write error")); - - return -1; -} - -// ************************************************************ -// notify external user handler that -// it is now to safe destroy stream -// Return code looks like cancel() return code -// 0 - notified NOTIFIED -// 1 - nothing to notify ALLDONE -// 2 - unable to notify NOT NOTIFIED -// ************************************************************ -int -ACE_SSL_Asynch_Stream::notify_close (void) -{ - if (this->flags_ & SF_CLOSE_NTF_SENT) // already sent - return 1; - - if ((this->flags_ & SF_SHUTDOWN_DONE) == 0) // only after shutdown - return 2; // too early , we will do later - - if (this->pending_BIO_count () != 0) // wait for all internal IO - return 2; // too early , we will do later - - // create result for future notification - ACE_SSL_Asynch_Result * close_result = 0; - - ACE_NEW_RETURN (close_result, - ACE_SSL_Asynch_Result (*this), - 2); - //@@ Not exception safe! - - int retval = - close_result->post_completion (this->proactor_->implementation ()); - - if (retval == 0) - { - this->flags_ |= SF_CLOSE_NTF_SENT; - return 0; - } - - delete close_result; - return 2; -} - -// ************************************************************ -// notify external user handler about user write completion -// Return code looks like cancel() return code -// 0 - notified NOTIFIED/CANCELED -// 1 - nothing to notify ALLDONE -// 2 - unable to notify NOT NOTIFIED/CANCELED -// ************************************************************ - -int -ACE_SSL_Asynch_Stream::notify_read (int bytes_transferred, - int error) -{ - if (ext_read_result_ == 0) //nothing to notify - return 1; - - this->ext_read_result_->set_bytes_transferred (bytes_transferred); - this->ext_read_result_->set_error (error); - - int retval = - this->ext_read_result_->post_completion (proactor_->implementation ()); - - if (retval == 0) - { - this->ext_read_result_ = 0; - return 0; // success - } - - return 2; // unable to notify -} - -// ************************************************************ -// notify external user handler about user write completion -// Return code looks like cancel() return code -// 0 - notified NOTIFIED/CANCELED -// 1 - nothing to notify ALLDONE -// 2 - unable to notify NOT NOTIFIED/CANCELED -// ************************************************************ - -int -ACE_SSL_Asynch_Stream::notify_write (int bytes_transferred, - int error) -{ - if (this->ext_write_result_ == 0) //nothing to notify - return 1; - - this->ext_write_result_->set_bytes_transferred (bytes_transferred); - this->ext_write_result_->set_error (error); - - int retval = - this->ext_write_result_->post_completion ( - this->proactor_->implementation ()); - - if (retval == 0) - { - this->ext_write_result_ = 0; - return 0; // success - } - - return 2; // unable to notify -} - -// ************************************************************ -// Print SSL errors -// ************************************************************ -void -ACE_SSL_Asynch_Stream::print_error (int err_ssl, - const ACE_TCHAR * pText) -{ - ACE_DEBUG ((LM_DEBUG, - "SSL-error:%d %s\n" , - err_ssl, - pText)); - -#if OPENSSL_VERSION_NUMBER >= 0x0090601fL - // OpenSSL < 0.9.6a doesn't have ERR_error_string_n() function. - unsigned long lerr = 0; - char buf[1024]; - - while ((lerr = ERR_get_error()) != 0) - { - ERR_error_string_n (lerr, buf, sizeof buf); - - ACE_DEBUG ((LM_DEBUG, "%s\n", buf)); - } -#endif /* OPENSSL_VERSION_NUMBER */ -} - -// ************************************************************ -// BIO helper functions -// SSL library will ask BIO to do raw I/O -// BIO will call us to do this -// ************************************************************ -int -ACE_SSL_Asynch_Stream::ssl_bio_read (char * buf, - size_t len, - int & errval) -{ - // We do not have to acquire mutex - // as we called already with locked mutex - // from do_SSL_state_machine() - - errval = 0; - - size_t cur_len = this->bio_inp_msg_.length (); - - if (cur_len > 0) // there are more data buffered - { - const char * rd_ptr = this->bio_inp_msg_.rd_ptr (); - - if (cur_len > len) - cur_len = len; - - ACE_OS::memcpy (buf, rd_ptr, cur_len); - - this->bio_inp_msg_.rd_ptr (cur_len); // go ahead - - return cur_len; - } - - if (this->bio_inp_errno_ != 0) // if was error - it is permanent ! - { - errval = this->bio_inp_errno_; - return -1; - } - - if (this->bio_inp_flag_ & BF_EOS) // End of stream - return 0; - - errval = EINPROGRESS; // SSL will try later - - if (this->bio_inp_flag_ & BF_AIO) // we are busy - return -1; - - if (this->bio_inp_msg_.size (len) != 0) - { - ACE_ERROR - ((LM_ERROR, - ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"), - ACE_TEXT ("error in ACE_Message_Block::size() ") - )); - - errval = EINVAL; - return -1; - } - - char * base = this->bio_inp_msg_.base (); - - this->bio_inp_msg_.rd_ptr (base); - this->bio_inp_msg_.wr_ptr (base); - - if (this->bio_istream_.read ( - bio_inp_msg_, // message block - len, // priority - 0, // act - 0, // priority - ACE_SIGRTMIN // default signal - ) == -1) - { - ACE_ERROR - ((LM_ERROR, - ACE_TEXT ("%N:%l (%P|%t) ACE_SSL_Asynch_Stream %p\n"), - ACE_TEXT ("attempt read failed") - )); - - errval = EINVAL; // may be leave EINPROGRESS ?? - return -1; // to try later - } - - this->bio_inp_flag_ |= BF_AIO; // AIO is active - - return -1; -} - - -int -ACE_SSL_Asynch_Stream::ssl_bio_write (const char * buf, - size_t len, - int & errval) -{ - // We do not have to acquire mutex - // as we called already with locked mutex - // from do_SSL_state_machine - - errval = 0; - - if (this->bio_out_flag_ & BF_AIO) // sorry, we are busy - { - errval = EINPROGRESS; // try later - return -1; - } - - if (this->bio_out_errno_ != 0) // no recovery - { - errval = this->bio_out_errno_; - return -1; - } - - if (this->bio_out_msg_.size (len) != 0) - { - ACE_ERROR - ((LM_ERROR, - ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"), - ACE_TEXT ("error in ACE_Message_Block::size() ") - )); - - errval = EINVAL; - return -1; - } - - char * base = this->bio_out_msg_.base (); - - this->bio_out_msg_.rd_ptr (base); - this->bio_out_msg_.wr_ptr (base); - - if (this->bio_out_msg_.copy (buf, len) == -1) - { - ACE_ERROR - ((LM_ERROR, - ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"), - ACE_TEXT ("error in ACE_Message_Block::copy() ") - )); - - errval = EINVAL; - return -1; - } - - - if (this->bio_ostream_.write ( - this->bio_out_msg_, // message block - len, // priority - 0, // act - 0, // priority - ACE_SIGRTMIN // default signal - ) == -1) - { - ACE_ERROR - ((LM_ERROR, - ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"), - ACE_TEXT ("attempt write failed") - )); - - errval = EINVAL; // may be leave EINPROGRESS ?? - return -1; // to try later - } - - this->bio_out_flag_ |= BF_AIO; // AIO is active - errval = 0; // Ok, go ahead - - return len; -} - -// ************************************************************ -// Internal IO handlers -// virtual from ACE_Service_Handler -// ************************************************************ -void -ACE_SSL_Asynch_Stream::handle_write_stream ( - const ACE_Asynch_Write_Stream::Result &result) -{ - ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_)); - - this->bio_out_flag_ &= ~BF_AIO; - - ACE_Message_Block & mb = result.message_block (); - - size_t bytes_req = result.bytes_to_write (); - size_t bytes_trn = result.bytes_transferred (); - u_long errval = result.error (); - size_t len = bytes_req - bytes_trn; - - if (errval != 0) // error ? - this->bio_out_errno_ = errval; // save err code - else if (len > 0) // TCP/IP overloaded ? - { // continue, rd_ptr at right place - if (this->bio_ostream_.write ( - mb, // message block - len, // priority - 0, // act - 0, // priority - ACE_SIGRTMIN // default signal - ) == 0) - { - this->bio_out_flag_ |= BF_AIO; - return; - } - - ACE_ERROR - ((LM_ERROR, - ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"), - ACE_TEXT ("attempt write failed") - )); - - this->bio_out_errno_ = EINVAL; - } - - this->do_SSL_state_machine (); - - return; -} - -void -ACE_SSL_Asynch_Stream::handle_read_stream ( - const ACE_Asynch_Read_Stream::Result &result) -{ - ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_)); - - this->bio_inp_flag_ &= ~BF_AIO; - - size_t bytes_trn = result.bytes_transferred (); - u_long errval = result.error (); - - if (errval != 0) // error ? - this->bio_inp_errno_ = errval; // save err code - else if (bytes_trn == 0) // end of stream ? - this->bio_inp_flag_ |= BF_EOS; // set flag EOS - - this->do_SSL_state_machine (); - - return; -} - -void -ACE_SSL_Asynch_Stream::handle_wakeup (void) -{ - ACE_Handler * user_handler = 0; - - { - ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_)); - - this->flags_ |= SF_DELETE_ENABLE; - - user_handler = this->ext_handler_; - } - - if (user_handler != 0) - user_handler->handle_wakeup(); -} - -int -ACE_SSL_Asynch_Stream::pending_BIO_count (void) -{ - int ret = 0; - - if (this->bio_inp_flag_ & BF_AIO) - ++ret; - - if (this->bio_out_flag_ & BF_AIO) - ++ret; - - return ret; -} - -ACE_END_VERSIONED_NAMESPACE_DECL - -#endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 || - ACE_HAS_AIO_CALLS) */ |