Cleanup ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE, all platforms support it so far as I can...
[ACE_TAO.git] / ACE / ace / SSL / SSL_Asynch_Stream.cpp
blobed5a1e1f440bf5fe9f41112d987fc2ef243d8941
1 #include "SSL_Asynch_Stream.h"
3 // This only works on platforms with Asynchronous IO support.
4 #if OPENSSL_VERSION_NUMBER > 0x0090581fL && (defined (ACE_WIN32) || (defined (ACE_HAS_AIO_CALLS)))
6 #if defined (ACE_WIN32)
7 # include "ace/WIN32_Proactor.h"
8 #else
9 # include "ace/POSIX_Proactor.h"
10 #endif /* ACE_WIN32 */
12 #include "ace/OS_NS_string.h"
13 #include "ace/Proactor.h"
14 #include "ace/Truncate.h"
16 #if !defined(__ACE_INLINE__)
17 #include "SSL_Asynch_Stream.inl"
18 #endif /* __ACE_INLINE__ */
20 #include <openssl/err.h>
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
24 ACE_SSL_Asynch_Write_Stream_Result::ACE_SSL_Asynch_Write_Stream_Result
25 (ACE_Handler & handler,
26 ACE_HANDLE handle,
27 ACE_Message_Block & message_block,
28 size_t bytes_to_write,
29 const void * act,
30 ACE_HANDLE event,
31 int priority,
32 int signal_number
34 : AWS_RESULT (handler.proxy (),
35 handle,
36 message_block,
37 bytes_to_write,
38 act,
39 event,
40 priority,
41 signal_number
46 ACE_SSL_Asynch_Read_Stream_Result::ACE_SSL_Asynch_Read_Stream_Result
47 (ACE_Handler & handler,
48 ACE_HANDLE handle,
49 ACE_Message_Block & message_block,
50 size_t bytes_to_read,
51 const void * act,
52 ACE_HANDLE event,
53 int priority,
54 int signal_number
56 : ARS_RESULT (handler.proxy (),
57 handle,
58 message_block,
59 bytes_to_read,
60 act,
61 event,
62 priority,
63 signal_number
68 ACE_SSL_Asynch_Result::ACE_SSL_Asynch_Result (ACE_Handler & handler)
69 : A_RESULT (handler.proxy (),
70 0, // act,
71 ACE_INVALID_HANDLE,
72 0, // Offset
73 0, // OffsetHigh
74 0, // Priority
75 ACE_SIGRTMIN //signal_number
80 void
81 ACE_SSL_Asynch_Result::complete (size_t /* bytes_transferred */,
82 int /* success */,
83 const void * /* completion_key */,
84 u_long /* error */)
86 this->handler_proxy_->handler ()->handle_wakeup ();
89 // ************************************************************
90 // ACE_SSL_Asynch_Stream Constructor / Destructor
91 // ************************************************************
92 ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream (
93 ACE_SSL_Asynch_Stream::Stream_Type s_type,
94 ACE_SSL_Context * context)
95 : type_ (s_type),
96 proactor_ (0),
97 ext_handler_ (0),
98 ext_read_result_ (0),
99 ext_write_result_(0),
100 flags_ (0),
101 ssl_ (0),
102 handshake_complete_(false),
103 bio_ (0),
104 bio_istream_ (),
105 bio_inp_msg_ (),
106 bio_inp_errno_(0),
107 bio_inp_flag_ (0),
108 bio_ostream_ (),
109 bio_out_msg_ (),
110 bio_out_errno_(0),
111 bio_out_flag_ (0),
112 mutex_ ()
114 ACE_TRACE ("ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream");
115 // was honestly copied from ACE_SSL_SOCK_Stream :)
117 ACE_SSL_Context * ctx =
118 (context == 0 ? ACE_SSL_Context::instance () : context);
120 this->ssl_ = ::SSL_new (ctx->context ());
122 if (this->ssl_ == 0)
123 ACELIB_ERROR
124 ((LM_ERROR,
125 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
126 ACE_TEXT ("- cannot allocate new SSL structure")
130 ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream ()
132 ACE_TRACE ("ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream");
135 // It is safe to delete stream if all notifications are received,
136 // i.e., state is SF_DELETE_ENABLE or if proactor event loop is
137 // done.
138 if (this->flags_ & SF_STREAM_OPEN) // open
139 if ((this->flags_ & SF_DELETE_ENABLE) == 0) // but ..
140 ACELIB_DEBUG ((LM_DEBUG,
141 ACE_TEXT("ACE_SSL_Asynch_Stream::DTOR-")
142 ACE_TEXT("possible access violation ")
143 ACE_TEXT("if proactor still handles events\n")));
145 ::SSL_free (this->ssl_);
147 // Was honestly copied from ACE_SSL_SOCK_Stream :)
149 // @@ Question: should we reference count the Context object or
150 // leave that to the application developer? We do not reference
151 // count reactors (for example) and following some simple rules
152 // seems to work fine!
155 // ************************************************************
156 // close ()
157 // returns :
158 // 0 - Stream is in the state SF_DELETE_ENABLE,
159 // so it is safe to delete stream
160 // -1 - Stream has pending AIO requests,
161 // close should be repeated later one more
162 // ************************************************************
165 ACE_SSL_Asynch_Stream::close ()
167 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
169 if ((flags_ & SF_STREAM_OPEN) == 0) // not open
170 flags_ |= SF_DELETE_ENABLE;
172 if (flags_ & SF_DELETE_ENABLE)
173 return 0;
175 flags_ |= SF_REQ_SHUTDOWN;
177 this->do_SSL_state_machine ();
179 return -1;
182 // ************************************************************
183 // Asynch_Operation interface
184 // cancel
185 // ************************************************************
187 ACE_SSL_Asynch_Stream::cancel ()
189 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
191 if ((flags_ & SF_STREAM_OPEN) == 0) // not open
193 return 1; // AIO_ALLDONE
196 // attempt to cancel internal, i.e. user's read/write
197 int rc_r_int = bio_istream_.cancel();
198 int rc_w_int = bio_ostream_.cancel();
200 // attempt to cancel external, i.e. bio_ssl read/write
201 int rc_r_ext = notify_read (0, ERR_CANCELED);
202 int rc_w_ext = notify_write (0, ERR_CANCELED);
204 if ((rc_r_int < 0 || rc_w_int < 0)
205 && (rc_r_ext < 0 || rc_w_ext < 0))
207 return -1; // at least one error
210 if (rc_r_int == 1 && rc_w_int == 1
211 && rc_r_ext == 1 && rc_w_ext == 1)
213 return 1; // AIO_ALLDONE
216 if ((rc_r_int == 2 || rc_w_int == 2)
217 && (rc_r_ext == 2 || rc_w_ext == 2))
219 return 2; // AIO_NOT_CANCELED , at least one not canceled
222 return 0; // AIO_CANCELED, at least will be one notification
225 // ************************************************************
226 // Asynch_Operation interface
227 // open
228 // ************************************************************
230 ACE_SSL_Asynch_Stream::open (ACE_Handler & handler,
231 ACE_HANDLE handle,
232 const void * completion_key,
233 ACE_Proactor * proactor)
235 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
237 if (this->flags_ & SF_STREAM_OPEN)
238 ACELIB_ERROR_RETURN
239 ((LM_ERROR,
240 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
241 ACE_TEXT ("- already opened")),
242 -1);
244 if (this->ssl_ == 0)
245 ACELIB_ERROR_RETURN
246 ((LM_ERROR,
247 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
248 ACE_TEXT ("- SSL structure is absent")),
249 -1);
251 if (handle == ACE_INVALID_HANDLE)
252 ACELIB_ERROR_RETURN
253 ((LM_ERROR,
254 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
255 ACE_TEXT ("- invalid handle")),
256 -1);
258 // Get a proactor for/from the user.
259 this->proactor_ = this->get_proactor (proactor, handler);
260 this->ext_handler_ = & handler;
261 this->handle (handle);
263 // Open internal input stream
264 if (this->bio_istream_.open (*this, // real callbacks to this
265 handle,
266 completion_key,
267 this->proactor_) != 0)
268 return -1;
270 // Open internal output stream
271 if (this->bio_ostream_.open (*this, // real callbacks to this
272 handle,
273 completion_key,
274 this->proactor_) != 0)
275 return -1;
277 this->bio_ = ACE_SSL_make_BIO (this);
279 if (this->bio_ == 0)
280 ACELIB_ERROR_RETURN
281 ((LM_ERROR,
282 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
283 ACE_TEXT ("- cannot allocate new BIO structure")),
284 -1);
286 ::SSL_set_bio (this->ssl_ , this->bio_ , this->bio_);
288 switch (this->type_)
290 case ST_CLIENT:
291 ::SSL_set_connect_state (this->ssl_);
292 break;
294 case ST_SERVER:
295 ::SSL_set_accept_state (this->ssl_);
296 break;
298 default:
299 ACELIB_ERROR_RETURN
300 ((LM_ERROR,
301 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
302 ACE_TEXT ("- invalid stream type")),
303 -1);
306 this->flags_ |= SF_STREAM_OPEN;
308 this->do_SSL_state_machine ();
310 return 0;
314 // ************************************************************
315 // Asynch_Operation interface
316 // read
317 // ************************************************************
319 ACE_SSL_Asynch_Stream::read (ACE_Message_Block & message_block,
320 size_t bytes_to_read,
321 const void * act,
322 int priority,
323 int signal_number)
325 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
327 if ((this->flags_ & SF_STREAM_OPEN) == 0) // not open
328 return -1;
330 if (this->flags_ & SF_REQ_SHUTDOWN)
331 return -1;
333 // only one read operation is allowed now
334 // later it will be possible to make a queue
336 if (this->ext_read_result_ != 0)
337 return -1;
339 // create result for future notification
340 ACE_NEW_RETURN (this->ext_read_result_,
341 ACE_SSL_Asynch_Read_Stream_Result (
342 *this->ext_handler_,
343 this->handle (),
344 message_block,
345 bytes_to_read,
346 act,
347 this->proactor_->get_handle(),
348 priority,
349 signal_number),
350 -1);
352 this->do_SSL_state_machine (); // ignore return code
354 return 0;
357 // ************************************************************
358 // Asynch_Operation interface
359 // write
360 // ************************************************************
362 ACE_SSL_Asynch_Stream::write (ACE_Message_Block & message_block,
363 size_t bytes_to_write,
364 const void * act,
365 int priority,
366 int signal_number)
368 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
370 if ((this->flags_ & SF_STREAM_OPEN) == 0) // not open
371 return -1;
373 if (this->flags_ & SF_REQ_SHUTDOWN)
374 return -1;
376 // only one read operation is allowed now
377 // later it will be possible to make a queue
379 if (this->ext_write_result_ != 0)
380 return -1;
382 // create result for future notification
383 ACE_NEW_RETURN (this->ext_write_result_,
384 ACE_SSL_Asynch_Write_Stream_Result (
385 *this->ext_handler_,
386 this->handle (),
387 message_block,
388 bytes_to_write,
389 act,
390 this->proactor_->get_handle(),
391 priority,
392 signal_number),
393 -1);
395 this->do_SSL_state_machine ();
397 return 0;
400 // ************************************************************
401 // Main SSL engine
402 // ************************************************************
404 ACE_SSL_Asynch_Stream::do_SSL_state_machine ()
406 // this protected member should be called
407 // with locked mutex_
408 int const retval = this->do_SSL_handshake ();
410 if (retval == 0) // handshake in progress ?
411 return 0;
413 if (retval < 0)
414 this->flags_ |= SF_REQ_SHUTDOWN;
416 this->do_SSL_read (); // execute user read request
417 this->do_SSL_write (); // execute user write request
419 if ((this->flags_ & SF_REQ_SHUTDOWN) == 0) // Do we have any errors
420 return 0;
422 this->do_SSL_shutdown ();
424 this->notify_close ();
426 return 0;
429 // ************************************************************
430 // do_SSL_shutdown
431 // return code:
432 // 1 SSL shutdown is finished already, success
433 // 0 SSL shutdown in progress
434 // -1 failure
435 // ************************************************************
437 ACE_SSL_Asynch_Stream::do_SSL_shutdown ()
439 if (this->flags_ & SF_SHUTDOWN_DONE) // already done
440 return 1;
442 this->flags_ |= SF_REQ_SHUTDOWN;
444 // if we have any uncompleted user requests
445 // than cancel its
446 this->notify_read (0, ERR_CANCELED);
447 this->notify_write (0, ERR_CANCELED);
449 int retval = ::SSL_shutdown (this->ssl_);
451 int const status = ::SSL_get_error (this->ssl_, retval);
453 switch (status)
455 case SSL_ERROR_NONE:
456 case SSL_ERROR_ZERO_RETURN:
457 case SSL_ERROR_SYSCALL:
458 retval = 1;
459 break;
461 case SSL_ERROR_WANT_READ:
462 case SSL_ERROR_WANT_WRITE:
463 case SSL_ERROR_WANT_CONNECT:
464 // case SSL_ERROR_WANT_ACCEPT:
465 case SSL_ERROR_WANT_X509_LOOKUP:
466 return 0;
468 default:
469 this->print_error (status,
470 ACE_TEXT ("Shutdown error"));
471 retval = -1;
472 break;
475 this->flags_ |= SF_SHUTDOWN_DONE;
477 return retval;
480 // ************************************************************
481 // Do SSL handshake if necessary
482 // return code:
483 // 1 SSL handshake is finished already, success
484 // 0 SSL handshake in progress
485 // -1 failure
486 // ************************************************************
488 ACE_SSL_Asynch_Stream::do_SSL_handshake ()
490 if (SSL_is_init_finished (this->ssl_))
492 if (!handshake_complete_)
494 handshake_complete_ = true;
496 if (!post_handshake_check ())
498 return -1;
501 return 1;
504 if (this->flags_ & SF_REQ_SHUTDOWN)
505 return -1;
507 int retval = -1;
509 switch (this->type_)
511 case ST_CLIENT:
512 retval = ::SSL_connect (this->ssl_);
513 break;
515 case ST_SERVER:
516 retval = ::SSL_accept (this->ssl_);
517 break;
519 default:
520 ACELIB_ERROR_RETURN
521 ((LM_ERROR,
522 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
523 ACE_TEXT ("- invalid stream type")),
524 -1);
527 int const status = ::SSL_get_error (this->ssl_, retval);
529 switch (status)
531 case SSL_ERROR_NONE:
532 break;
534 case SSL_ERROR_WANT_READ:
535 case SSL_ERROR_WANT_WRITE:
536 case SSL_ERROR_WANT_CONNECT:
537 //case SSL_ERROR_WANT_ACCEPT:
538 case SSL_ERROR_WANT_X509_LOOKUP:
539 return 0;
541 case SSL_ERROR_ZERO_RETURN:
542 case SSL_ERROR_SYSCALL:
543 default:
544 this->print_error (status,
545 ACE_TEXT ("Handshake error"));
546 return -1;
549 return 1;
552 bool
553 ACE_SSL_Asynch_Stream::post_handshake_check ()
555 return true;
558 // ************************************************************
559 // Perform SSL_read call if necessary and notify user
560 // ************************************************************
562 ACE_SSL_Asynch_Stream::do_SSL_read ()
564 if (this->ext_read_result_ == 0) // nothing to do
566 return 0;
569 if (this->flags_ & SF_REQ_SHUTDOWN)
571 this->notify_read (0, ERR_CANCELED);
572 return -1;
575 ACE_Message_Block & mb = this->ext_read_result_->message_block ();
576 size_t bytes_req = this->ext_read_result_->bytes_to_read ();
578 ERR_clear_error ();
580 const int bytes_trn =
581 ::SSL_read (this->ssl_,
582 mb.wr_ptr (),
583 ACE_Utils::truncate_cast<int> (bytes_req));
585 int const status = ::SSL_get_error (this->ssl_, bytes_trn);
587 switch (status)
589 case SSL_ERROR_NONE:
590 this->notify_read (bytes_trn, 0);
591 return 1;
593 case SSL_ERROR_WANT_READ:
594 case SSL_ERROR_WANT_WRITE:
595 return 0;
597 case SSL_ERROR_ZERO_RETURN:
598 this->notify_read (0, 0);
599 return 1;
601 case SSL_ERROR_SYSCALL:
602 if (bytes_trn == 0)
604 this->notify_read (0, 0);
605 return 1;
607 // If not an EOF, then fall through to "default" case.
609 default:
610 break;
613 this->notify_read (0, EFAULT);
614 this->print_error (status,
615 ACE_TEXT ("SSL_read error"));
617 return -1;
620 // ************************************************************
621 // Perform SSL_write call if necessary and notify user
622 // ************************************************************
624 ACE_SSL_Asynch_Stream::do_SSL_write ()
626 if (this->ext_write_result_ == 0) // nothing to do
628 return 0;
631 if (this->flags_ & SF_REQ_SHUTDOWN)
633 this->notify_write (0, ERR_CANCELED);
634 return -1;
637 ACE_Message_Block & mb = this->ext_write_result_->message_block ();
638 size_t bytes_req = this->ext_write_result_->bytes_to_write ();
640 ERR_clear_error ();
642 const int bytes_trn =
643 ::SSL_write (this->ssl_,
644 mb.rd_ptr (),
645 ACE_Utils::truncate_cast<int> (bytes_req));
647 int const status = ::SSL_get_error (this->ssl_, bytes_trn);
649 switch (status)
651 case SSL_ERROR_NONE:
652 this->notify_write (bytes_trn, 0);
653 return 1;
655 case SSL_ERROR_WANT_READ:
656 case SSL_ERROR_WANT_WRITE:
657 return 0;
659 case SSL_ERROR_ZERO_RETURN:
660 this->notify_write (bytes_trn, 0);
661 return 1;
663 case SSL_ERROR_SYSCALL:
664 default:
665 break;
668 this->notify_write(0, EFAULT);
669 this->print_error (status,
670 ACE_TEXT ("SSL_write error"));
672 return -1;
675 // ************************************************************
676 // notify external user handler that
677 // it is now to safe destroy stream
678 // Return code looks like cancel() return code
679 // 0 - notified NOTIFIED
680 // 1 - nothing to notify ALLDONE
681 // 2 - unable to notify NOT NOTIFIED
682 // ************************************************************
684 ACE_SSL_Asynch_Stream::notify_close ()
686 if (this->flags_ & SF_CLOSE_NTF_SENT) // already sent
687 return 1;
689 if ((this->flags_ & SF_SHUTDOWN_DONE) == 0) // only after shutdown
690 return 2; // too early , we will do later
692 if (this->pending_BIO_count () != 0) // wait for all internal IO
693 return 2; // too early , we will do later
695 // create result for future notification
696 ACE_SSL_Asynch_Result * close_result = 0;
698 ACE_NEW_RETURN (close_result,
699 ACE_SSL_Asynch_Result (*this),
701 //@@ Not exception safe!
703 int retval =
704 close_result->post_completion (this->proactor_->implementation ());
706 if (retval == 0)
708 this->flags_ |= SF_CLOSE_NTF_SENT;
709 return 0;
712 delete close_result;
713 return 2;
716 // ************************************************************
717 // notify external user handler about user write completion
718 // Return code looks like cancel() return code
719 // 0 - notified NOTIFIED/CANCELED
720 // 1 - nothing to notify ALLDONE
721 // 2 - unable to notify NOT NOTIFIED/CANCELED
722 // ************************************************************
725 ACE_SSL_Asynch_Stream::notify_read (int bytes_transferred,
726 int error)
728 if (ext_read_result_ == 0) //nothing to notify
729 return 1;
731 this->ext_read_result_->set_bytes_transferred (bytes_transferred);
732 this->ext_read_result_->set_error (error);
734 int retval =
735 this->ext_read_result_->post_completion (proactor_->implementation ());
737 if (retval == 0)
739 this->ext_read_result_ = 0;
740 return 0; // success
743 return 2; // unable to notify
746 // ************************************************************
747 // notify external user handler about user write completion
748 // Return code looks like cancel() return code
749 // 0 - notified NOTIFIED/CANCELED
750 // 1 - nothing to notify ALLDONE
751 // 2 - unable to notify NOT NOTIFIED/CANCELED
752 // ************************************************************
755 ACE_SSL_Asynch_Stream::notify_write (int bytes_transferred,
756 int error)
758 if (this->ext_write_result_ == 0) //nothing to notify
759 return 1;
761 this->ext_write_result_->set_bytes_transferred (bytes_transferred);
762 this->ext_write_result_->set_error (error);
764 int retval =
765 this->ext_write_result_->post_completion (
766 this->proactor_->implementation ());
768 if (retval == 0)
770 this->ext_write_result_ = 0;
771 return 0; // success
774 return 2; // unable to notify
777 // ************************************************************
778 // Print SSL errors
779 // ************************************************************
780 void
781 ACE_SSL_Asynch_Stream::print_error (int err_ssl,
782 const ACE_TCHAR * pText)
784 ACELIB_DEBUG ((LM_DEBUG,
785 ACE_TEXT("SSL-error:%d %s\n"),
786 err_ssl,
787 pText));
789 #if OPENSSL_VERSION_NUMBER >= 0x0090601fL
790 // OpenSSL < 0.9.6a doesn't have ERR_error_string_n() function.
791 unsigned long lerr = 0;
792 char buf[1024];
794 while ((lerr = ERR_get_error()) != 0)
796 ERR_error_string_n (lerr, buf, sizeof buf);
798 ACELIB_DEBUG ((LM_DEBUG, "%C\n", buf));
800 #endif /* OPENSSL_VERSION_NUMBER */
803 // ************************************************************
804 // BIO helper functions
805 // SSL library will ask BIO to do raw I/O
806 // BIO will call us to do this
807 // ************************************************************
809 ACE_SSL_Asynch_Stream::ssl_bio_read (char * buf,
810 size_t len,
811 int & errval)
813 // We do not have to acquire mutex
814 // as we called already with locked mutex
815 // from do_SSL_state_machine()
817 errval = 0;
819 size_t cur_len = this->bio_inp_msg_.length ();
821 if (cur_len > 0) // there are more data buffered
823 const char * rd_ptr = this->bio_inp_msg_.rd_ptr ();
825 if (cur_len > len)
827 cur_len = len;
830 ACE_OS::memcpy (buf, rd_ptr, cur_len);
832 this->bio_inp_msg_.rd_ptr (cur_len); // go ahead
834 return ACE_Utils::truncate_cast<int> (cur_len);
837 if (this->bio_inp_errno_ != 0) // if was error - it is permanent !
839 errval = this->bio_inp_errno_;
840 return -1;
843 if (this->bio_inp_flag_ & BF_EOS) // End of stream
845 return 0;
848 errval = EINPROGRESS; // SSL will try later
850 if (this->bio_inp_flag_ & BF_AIO) // we are busy
852 return -1;
855 if (this->bio_inp_msg_.size (len) != 0)
857 ACELIB_ERROR
858 ((LM_ERROR,
859 ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
860 ACE_TEXT ("error in ACE_Message_Block::size() ")
863 errval = EINVAL;
864 return -1;
867 char * base = this->bio_inp_msg_.base ();
869 this->bio_inp_msg_.rd_ptr (base);
870 this->bio_inp_msg_.wr_ptr (base);
872 if (this->bio_istream_.read (
873 bio_inp_msg_, // message block
874 len, // priority
875 0, // act
876 0, // priority
877 ACE_SIGRTMIN // default signal
878 ) == -1)
880 ACELIB_ERROR
881 ((LM_ERROR,
882 ACE_TEXT ("%N:%l (%P|%t) ACE_SSL_Asynch_Stream %p\n"),
883 ACE_TEXT ("attempt read failed")
886 errval = EINVAL; // may be leave EINPROGRESS ??
887 return -1; // to try later
890 this->bio_inp_flag_ |= BF_AIO; // AIO is active
892 return -1;
897 ACE_SSL_Asynch_Stream::ssl_bio_write (const char * buf,
898 size_t len,
899 int & errval)
901 // We do not have to acquire mutex
902 // as we called already with locked mutex
903 // from do_SSL_state_machine
905 errval = 0;
907 if (this->bio_out_flag_ & BF_AIO) // sorry, we are busy
909 errval = EINPROGRESS; // try later
910 return -1;
913 if (this->bio_out_errno_ != 0) // no recovery
915 errval = this->bio_out_errno_;
916 return -1;
919 if (this->bio_out_msg_.size (len) != 0)
921 ACELIB_ERROR
922 ((LM_ERROR,
923 ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
924 ACE_TEXT ("error in ACE_Message_Block::size() ")
927 errval = EINVAL;
928 return -1;
931 char * base = this->bio_out_msg_.base ();
933 this->bio_out_msg_.rd_ptr (base);
934 this->bio_out_msg_.wr_ptr (base);
936 if (this->bio_out_msg_.copy (buf, len) == -1)
938 ACELIB_ERROR
939 ((LM_ERROR,
940 ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
941 ACE_TEXT ("error in ACE_Message_Block::copy() ")
944 errval = EINVAL;
945 return -1;
949 if (this->bio_ostream_.write (
950 this->bio_out_msg_, // message block
951 len, // priority
952 0, // act
953 0, // priority
954 ACE_SIGRTMIN // default signal
955 ) == -1)
957 ACELIB_ERROR
958 ((LM_ERROR,
959 ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
960 ACE_TEXT ("attempt write failed")
963 errval = EINVAL; // may be leave EINPROGRESS ??
964 return -1; // to try later
967 this->bio_out_flag_ |= BF_AIO; // AIO is active
968 errval = 0; // Ok, go ahead
970 return ACE_Utils::truncate_cast<int> (len);
973 // ************************************************************
974 // Internal IO handlers
975 // virtual from ACE_Service_Handler
976 // ************************************************************
977 void
978 ACE_SSL_Asynch_Stream::handle_write_stream (
979 const ACE_Asynch_Write_Stream::Result &result)
981 ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
983 this->bio_out_flag_ &= ~BF_AIO;
985 ACE_Message_Block & mb = result.message_block ();
987 size_t bytes_req = result.bytes_to_write ();
988 size_t bytes_trn = result.bytes_transferred ();
989 u_long errval = result.error ();
990 size_t len = bytes_req - bytes_trn;
992 if (errval != 0) // error ?
993 this->bio_out_errno_ = errval; // save err code
994 else if (len > 0) // TCP/IP overloaded ?
995 { // continue, rd_ptr at right place
996 if (this->bio_ostream_.write (
997 mb, // message block
998 len, // priority
999 0, // act
1000 0, // priority
1001 ACE_SIGRTMIN // default signal
1002 ) == 0)
1004 this->bio_out_flag_ |= BF_AIO;
1005 return;
1008 ACELIB_ERROR
1009 ((LM_ERROR,
1010 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
1011 ACE_TEXT ("attempt write failed")
1014 this->bio_out_errno_ = EINVAL;
1017 this->do_SSL_state_machine ();
1019 return;
1022 void
1023 ACE_SSL_Asynch_Stream::handle_read_stream (
1024 const ACE_Asynch_Read_Stream::Result &result)
1026 ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
1028 this->bio_inp_flag_ &= ~BF_AIO;
1030 size_t bytes_trn = result.bytes_transferred ();
1031 u_long errval = result.error ();
1033 if (errval != 0) // error ?
1034 this->bio_inp_errno_ = errval; // save err code
1035 else if (bytes_trn == 0) // end of stream ?
1036 this->bio_inp_flag_ |= BF_EOS; // set flag EOS
1038 this->do_SSL_state_machine ();
1040 return;
1043 void
1044 ACE_SSL_Asynch_Stream::handle_wakeup ()
1046 ACE_Handler * user_handler = 0;
1049 ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
1051 this->flags_ |= SF_DELETE_ENABLE;
1053 user_handler = this->ext_handler_;
1056 if (user_handler != 0)
1057 user_handler->handle_wakeup();
1061 ACE_SSL_Asynch_Stream::pending_BIO_count ()
1063 int ret = 0;
1065 if (this->bio_inp_flag_ & BF_AIO)
1066 ++ret;
1068 if (this->bio_out_flag_ & BF_AIO)
1069 ++ret;
1071 return ret;
1074 ACE_END_VERSIONED_NAMESPACE_DECL
1076 #endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
1077 ACE_HAS_AIO_CALLS) */