PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/dep/acelite/ace/SSL/SSL_Asynch_Stream.cpp

https://github.com/chucho/FaceCore
C++ | 1082 lines | 745 code | 214 blank | 123 comment | 130 complexity | 2301a6463940c0362ce34a3dc394ba17 MD5 | raw file
  1. // $Id: SSL_Asynch_Stream.cpp 91813 2010-09-17 07:52:52Z johnnyw $
  2. #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_WINCE)) || (defined (ACE_HAS_AIO_CALLS)))
  5. #if defined (ACE_WIN32)
  6. # include "ace/WIN32_Proactor.h"
  7. #else
  8. # include "ace/POSIX_Proactor.h"
  9. #endif /* ACE_WIN32 */
  10. #include "ace/OS_NS_string.h"
  11. #include "ace/Proactor.h"
  12. #include "ace/Truncate.h"
  13. #if !defined(__ACE_INLINE__)
  14. #include "SSL_Asynch_Stream.inl"
  15. #endif /* __ACE_INLINE__ */
  16. #include <openssl/err.h>
  17. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  18. ACE_SSL_Asynch_Write_Stream_Result::ACE_SSL_Asynch_Write_Stream_Result
  19. (ACE_Handler & handler,
  20. ACE_HANDLE handle,
  21. ACE_Message_Block & message_block,
  22. size_t bytes_to_write,
  23. const void * act,
  24. ACE_HANDLE event,
  25. int priority,
  26. int signal_number
  27. )
  28. : AWS_RESULT (handler.proxy (),
  29. handle,
  30. message_block,
  31. bytes_to_write,
  32. act,
  33. event,
  34. priority,
  35. signal_number
  36. )
  37. {
  38. }
  39. ACE_SSL_Asynch_Read_Stream_Result::ACE_SSL_Asynch_Read_Stream_Result
  40. (ACE_Handler & handler,
  41. ACE_HANDLE handle,
  42. ACE_Message_Block & message_block,
  43. size_t bytes_to_read,
  44. const void * act,
  45. ACE_HANDLE event,
  46. int priority,
  47. int signal_number
  48. )
  49. : ARS_RESULT (handler.proxy (),
  50. handle,
  51. message_block,
  52. bytes_to_read,
  53. act,
  54. event,
  55. priority,
  56. signal_number
  57. )
  58. {
  59. }
  60. ACE_SSL_Asynch_Result::ACE_SSL_Asynch_Result (ACE_Handler & handler)
  61. : A_RESULT (handler.proxy (),
  62. 0, // act,
  63. ACE_INVALID_HANDLE,
  64. 0, // Offset
  65. 0, // OffsetHigh
  66. 0, // Priority
  67. ACE_SIGRTMIN //signal_number
  68. )
  69. {
  70. }
  71. void
  72. ACE_SSL_Asynch_Result::complete (size_t /* bytes_transferred */,
  73. int /* success */,
  74. const void * /* completion_key */,
  75. u_long /* error */)
  76. {
  77. this->handler_proxy_->handler ()->handle_wakeup ();
  78. }
  79. // ************************************************************
  80. // ACE_SSL_Asynch_Stream Constructor / Destructor
  81. // ************************************************************
  82. ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream (
  83. ACE_SSL_Asynch_Stream::Stream_Type s_type,
  84. ACE_SSL_Context * context)
  85. : type_ (s_type),
  86. proactor_ (0),
  87. ext_handler_ (0),
  88. ext_read_result_ (0),
  89. ext_write_result_(0),
  90. flags_ (0),
  91. ssl_ (0),
  92. handshake_complete_(false),
  93. bio_ (0),
  94. bio_istream_ (),
  95. bio_inp_msg_ (),
  96. bio_inp_errno_(0),
  97. bio_inp_flag_ (0),
  98. bio_ostream_ (),
  99. bio_out_msg_ (),
  100. bio_out_errno_(0),
  101. bio_out_flag_ (0),
  102. mutex_ ()
  103. {
  104. ACE_TRACE ("ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream");
  105. // was honestly copied from ACE_SSL_SOCK_Stream :)
  106. ACE_SSL_Context * ctx =
  107. (context == 0 ? ACE_SSL_Context::instance () : context);
  108. this->ssl_ = ::SSL_new (ctx->context ());
  109. if (this->ssl_ == 0)
  110. ACE_ERROR
  111. ((LM_ERROR,
  112. ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
  113. ACE_TEXT ("- cannot allocate new SSL structure")
  114. ));
  115. }
  116. ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream (void)
  117. {
  118. ACE_TRACE ("ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream");
  119. // It is safe to delete stream if all notifications are received,
  120. // i.e., state is SF_DELETE_ENABLE or if proactor event loop is
  121. // done.
  122. if (this->flags_ & SF_STREAM_OPEN) // open
  123. if ((this->flags_ & SF_DELETE_ENABLE) == 0) // but ..
  124. ACE_DEBUG ((LM_DEBUG,
  125. ACE_TEXT("ACE_SSL_Asynch_Stream::DTOR-")
  126. ACE_TEXT("possible access violation ")
  127. ACE_TEXT("if proactor still handles events\n")));
  128. ::SSL_free (this->ssl_);
  129. // Was honestly copied from ACE_SSL_SOCK_Stream :)
  130. // @@ Question: should we reference count the Context object or
  131. // leave that to the application developer? We do not reference
  132. // count reactors (for example) and following some simple rules
  133. // seems to work fine!
  134. }
  135. // ************************************************************
  136. // close ()
  137. // returns :
  138. // 0 - Stream is in the state SF_DELETE_ENABLE,
  139. // so it is safe to delete stream
  140. // -1 - Stream has pending AIO requests,
  141. // close should be repeated later one more
  142. // ************************************************************
  143. int
  144. ACE_SSL_Asynch_Stream::close (void)
  145. {
  146. ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
  147. if ((flags_ & SF_STREAM_OPEN) == 0) // not open
  148. flags_ |= SF_DELETE_ENABLE;
  149. if (flags_ & SF_DELETE_ENABLE)
  150. return 0;
  151. flags_ |= SF_REQ_SHUTDOWN;
  152. this->do_SSL_state_machine ();
  153. return -1;
  154. }
  155. // ************************************************************
  156. // Asynch_Operation interface
  157. // cancel
  158. // ************************************************************
  159. int
  160. ACE_SSL_Asynch_Stream::cancel (void)
  161. {
  162. ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
  163. if ((flags_ & SF_STREAM_OPEN) == 0) // not open
  164. {
  165. return 1; // AIO_ALLDONE
  166. }
  167. // attempt to cancel internal, i.e. user's read/write
  168. int rc_r_int = bio_istream_.cancel();
  169. int rc_w_int = bio_ostream_.cancel();
  170. // attempt to cancel external, i.e. bio_ssl read/write
  171. int rc_r_ext = notify_read (0, ERR_CANCELED);
  172. int rc_w_ext = notify_write (0, ERR_CANCELED);
  173. if ((rc_r_int < 0 || rc_w_int < 0)
  174. && (rc_r_ext < 0 || rc_w_ext < 0))
  175. {
  176. return -1; // at least one error
  177. }
  178. if (rc_r_int == 1 && rc_w_int == 1
  179. && rc_r_ext == 1 && rc_w_ext == 1)
  180. {
  181. return 1; // AIO_ALLDONE
  182. }
  183. if ((rc_r_int == 2 || rc_w_int == 2)
  184. && (rc_r_ext == 2 || rc_w_ext == 2))
  185. {
  186. return 2; // AIO_NOT_CANCELED , at least one not canceled
  187. }
  188. return 0; // AIO_CANCELED, at least will be one notification
  189. }
  190. // ************************************************************
  191. // Asynch_Operation interface
  192. // open
  193. // ************************************************************
  194. int
  195. ACE_SSL_Asynch_Stream::open (ACE_Handler & handler,
  196. ACE_HANDLE handle,
  197. const void * completion_key,
  198. ACE_Proactor * proactor)
  199. {
  200. ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
  201. if (this->flags_ & SF_STREAM_OPEN)
  202. ACE_ERROR_RETURN
  203. ((LM_ERROR,
  204. ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
  205. ACE_TEXT ("- already opened")),
  206. -1);
  207. if (this->ssl_ == 0)
  208. ACE_ERROR_RETURN
  209. ((LM_ERROR,
  210. ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
  211. ACE_TEXT ("- SSL structure is absent")),
  212. -1);
  213. if (handle == ACE_INVALID_HANDLE)
  214. ACE_ERROR_RETURN
  215. ((LM_ERROR,
  216. ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
  217. ACE_TEXT ("- invalid handle")),
  218. -1);
  219. // Get a proactor for/from the user.
  220. this->proactor_ = this->get_proactor (proactor, handler);
  221. this->ext_handler_ = & handler;
  222. this->handle (handle);
  223. // Open internal input stream
  224. if (this->bio_istream_.open (*this, // real callbacks to this
  225. handle,
  226. completion_key,
  227. this->proactor_) != 0)
  228. return -1;
  229. // Open internal output stream
  230. if (this->bio_ostream_.open (*this, // real callbacks to this
  231. handle,
  232. completion_key,
  233. this->proactor_) != 0)
  234. return -1;
  235. this->bio_ = ACE_SSL_make_BIO (this);
  236. if (this->bio_ == 0)
  237. ACE_ERROR_RETURN
  238. ((LM_ERROR,
  239. ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
  240. ACE_TEXT ("- cannot allocate new BIO structure")),
  241. -1);
  242. ::SSL_set_bio (this->ssl_ , this->bio_ , this->bio_);
  243. switch (this->type_)
  244. {
  245. case ST_CLIENT:
  246. ::SSL_set_connect_state (this->ssl_);
  247. break;
  248. case ST_SERVER:
  249. ::SSL_set_accept_state (this->ssl_);
  250. break;
  251. default:
  252. ACE_ERROR_RETURN
  253. ((LM_ERROR,
  254. ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
  255. ACE_TEXT ("- invalid stream type")),
  256. -1);
  257. }
  258. this->flags_ |= SF_STREAM_OPEN;
  259. this->do_SSL_state_machine ();
  260. return 0;
  261. }
  262. // ************************************************************
  263. // Asynch_Operation interface
  264. // read
  265. // ************************************************************
  266. int
  267. ACE_SSL_Asynch_Stream::read (ACE_Message_Block & message_block,
  268. size_t bytes_to_read,
  269. const void * act,
  270. int priority,
  271. int signal_number)
  272. {
  273. ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
  274. if ((this->flags_ & SF_STREAM_OPEN) == 0) // not open
  275. return -1;
  276. if (this->flags_ & SF_REQ_SHUTDOWN)
  277. return -1;
  278. // only one read operation is allowed now
  279. // later it will be possible to make a queue
  280. if (this->ext_read_result_ != 0)
  281. return -1;
  282. // create result for future notification
  283. ACE_NEW_RETURN (this->ext_read_result_,
  284. ACE_SSL_Asynch_Read_Stream_Result (
  285. *this->ext_handler_,
  286. this->handle (),
  287. message_block,
  288. bytes_to_read,
  289. act,
  290. this->proactor_->get_handle(),
  291. priority,
  292. signal_number),
  293. -1);
  294. this->do_SSL_state_machine (); // ignore return code
  295. return 0;
  296. }
  297. // ************************************************************
  298. // Asynch_Operation interface
  299. // write
  300. // ************************************************************
  301. int
  302. ACE_SSL_Asynch_Stream::write (ACE_Message_Block & message_block,
  303. size_t bytes_to_write,
  304. const void * act,
  305. int priority,
  306. int signal_number)
  307. {
  308. ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1));
  309. if ((this->flags_ & SF_STREAM_OPEN) == 0) // not open
  310. return -1;
  311. if (this->flags_ & SF_REQ_SHUTDOWN)
  312. return -1;
  313. // only one read operation is allowed now
  314. // later it will be possible to make a queue
  315. if (this->ext_write_result_ != 0)
  316. return -1;
  317. // create result for future notification
  318. ACE_NEW_RETURN (this->ext_write_result_,
  319. ACE_SSL_Asynch_Write_Stream_Result (
  320. *this->ext_handler_,
  321. this->handle (),
  322. message_block,
  323. bytes_to_write,
  324. act,
  325. this->proactor_->get_handle(),
  326. priority,
  327. signal_number),
  328. -1);
  329. this->do_SSL_state_machine ();
  330. return 0;
  331. }
  332. // ************************************************************
  333. // Main SSL engine
  334. // ************************************************************
  335. int
  336. ACE_SSL_Asynch_Stream::do_SSL_state_machine (void)
  337. {
  338. // this protected member should be called
  339. // with locked mutex_
  340. int retval = this->do_SSL_handshake ();
  341. if (retval == 0) // handshake in progress ?
  342. return 0;
  343. if (retval < 0)
  344. this->flags_ |= SF_REQ_SHUTDOWN;
  345. this->do_SSL_read (); // execute user read request
  346. this->do_SSL_write (); // execute user write request
  347. if ((this->flags_ & SF_REQ_SHUTDOWN) == 0) // Do we have any errors
  348. return 0;
  349. this->do_SSL_shutdown ();
  350. this->notify_close ();
  351. return 0;
  352. }
  353. // ************************************************************
  354. // do_SSL_shutdown
  355. // return code:
  356. // 1 SSL shutdown is finished already, success
  357. // 0 SSL shutdown in progress
  358. // -1 failure
  359. // ************************************************************
  360. int
  361. ACE_SSL_Asynch_Stream::do_SSL_shutdown (void)
  362. {
  363. if (this->flags_ & SF_SHUTDOWN_DONE) // already done
  364. return 1;
  365. this->flags_ |= SF_REQ_SHUTDOWN;
  366. // if we have any uncompleted user requests
  367. // than cancel its
  368. this->notify_read (0, ERR_CANCELED);
  369. this->notify_write (0, ERR_CANCELED);
  370. int retval = ::SSL_shutdown (this->ssl_);
  371. int status = ::SSL_get_error (this->ssl_, retval);
  372. switch (status)
  373. {
  374. case SSL_ERROR_NONE:
  375. case SSL_ERROR_ZERO_RETURN:
  376. case SSL_ERROR_SYSCALL:
  377. retval = 1;
  378. break;
  379. case SSL_ERROR_WANT_READ:
  380. case SSL_ERROR_WANT_WRITE:
  381. case SSL_ERROR_WANT_CONNECT:
  382. // case SSL_ERROR_WANT_ACCEPT:
  383. case SSL_ERROR_WANT_X509_LOOKUP:
  384. return 0;
  385. default:
  386. this->print_error (status,
  387. ACE_TEXT ("Shutdown error"));
  388. retval = -1;
  389. break;
  390. }
  391. this->flags_ |= SF_SHUTDOWN_DONE;
  392. return retval;
  393. }
  394. // ************************************************************
  395. // Do SSL handshake if necessary
  396. // return code:
  397. // 1 SSL handshake is finished already, success
  398. // 0 SSL handshake in progress
  399. // -1 failure
  400. // ************************************************************
  401. int
  402. ACE_SSL_Asynch_Stream::do_SSL_handshake (void)
  403. {
  404. if (SSL_is_init_finished (this->ssl_))
  405. {
  406. if (!handshake_complete_)
  407. {
  408. handshake_complete_ = true;
  409. if (!post_handshake_check ())
  410. {
  411. return -1;
  412. }
  413. }
  414. return 1;
  415. }
  416. if (this->flags_ & SF_REQ_SHUTDOWN)
  417. return -1;
  418. int retval = -1;
  419. switch (this->type_)
  420. {
  421. case ST_CLIENT:
  422. retval = ::SSL_connect (this->ssl_);
  423. break;
  424. case ST_SERVER:
  425. retval = ::SSL_accept (this->ssl_);
  426. break;
  427. default:
  428. ACE_ERROR_RETURN
  429. ((LM_ERROR,
  430. ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
  431. ACE_TEXT ("- invalid stream type")),
  432. -1);
  433. }
  434. int status = ::SSL_get_error (this->ssl_, retval);
  435. switch (status)
  436. {
  437. case SSL_ERROR_NONE:
  438. break;
  439. case SSL_ERROR_WANT_READ:
  440. case SSL_ERROR_WANT_WRITE:
  441. case SSL_ERROR_WANT_CONNECT:
  442. //case SSL_ERROR_WANT_ACCEPT:
  443. case SSL_ERROR_WANT_X509_LOOKUP:
  444. return 0;
  445. case SSL_ERROR_ZERO_RETURN:
  446. case SSL_ERROR_SYSCALL:
  447. default:
  448. this->print_error (status,
  449. ACE_TEXT ("Handshake error"));
  450. return -1;
  451. }
  452. return 1;
  453. }
  454. bool
  455. ACE_SSL_Asynch_Stream::post_handshake_check (void)
  456. {
  457. return true;
  458. }
  459. // ************************************************************
  460. // Perform SSL_read call if necessary and notify user
  461. // ************************************************************
  462. int
  463. ACE_SSL_Asynch_Stream::do_SSL_read (void)
  464. {
  465. if (this->ext_read_result_ == 0) // nothing to do
  466. {
  467. return 0;
  468. }
  469. if (this->flags_ & SF_REQ_SHUTDOWN)
  470. {
  471. this->notify_read (0, ERR_CANCELED);
  472. return -1;
  473. }
  474. ACE_Message_Block & mb = this->ext_read_result_->message_block ();
  475. size_t bytes_req = this->ext_read_result_->bytes_to_read ();
  476. ERR_clear_error ();
  477. const int bytes_trn =
  478. ::SSL_read (this->ssl_,
  479. mb.wr_ptr (),
  480. ACE_Utils::truncate_cast<int> (bytes_req));
  481. int const status = ::SSL_get_error (this->ssl_, bytes_trn);
  482. switch (status)
  483. {
  484. case SSL_ERROR_NONE:
  485. this->notify_read (bytes_trn, 0);
  486. return 1;
  487. case SSL_ERROR_WANT_READ:
  488. case SSL_ERROR_WANT_WRITE:
  489. return 0;
  490. case SSL_ERROR_ZERO_RETURN:
  491. this->notify_read (0, 0);
  492. return 1;
  493. case SSL_ERROR_SYSCALL:
  494. if (bytes_trn == 0)
  495. {
  496. this->notify_read (0, 0);
  497. return 1;
  498. }
  499. // If not an EOF, then fall through to "default" case.
  500. default:
  501. break;
  502. }
  503. this->notify_read (0, EFAULT);
  504. this->print_error (status,
  505. ACE_TEXT ("SSL_read error"));
  506. return -1;
  507. }
  508. // ************************************************************
  509. // Perform SSL_write call if necessary and notify user
  510. // ************************************************************
  511. int
  512. ACE_SSL_Asynch_Stream::do_SSL_write (void)
  513. {
  514. if (this->ext_write_result_ == 0) // nothing to do
  515. {
  516. return 0;
  517. }
  518. if (this->flags_ & SF_REQ_SHUTDOWN)
  519. {
  520. this->notify_write (0, ERR_CANCELED);
  521. return -1;
  522. }
  523. ACE_Message_Block & mb = this->ext_write_result_->message_block ();
  524. size_t bytes_req = this->ext_write_result_->bytes_to_write ();
  525. ERR_clear_error ();
  526. const int bytes_trn =
  527. ::SSL_write (this->ssl_,
  528. mb.rd_ptr (),
  529. ACE_Utils::truncate_cast<int> (bytes_req));
  530. int const status = ::SSL_get_error (this->ssl_, bytes_trn);
  531. switch (status)
  532. {
  533. case SSL_ERROR_NONE:
  534. this->notify_write (bytes_trn, 0);
  535. return 1;
  536. case SSL_ERROR_WANT_READ:
  537. case SSL_ERROR_WANT_WRITE:
  538. return 0;
  539. case SSL_ERROR_ZERO_RETURN:
  540. this->notify_write (bytes_trn, 0);
  541. return 1;
  542. case SSL_ERROR_SYSCALL:
  543. default:
  544. break;
  545. }
  546. this->notify_write(0, EFAULT);
  547. this->print_error (status,
  548. ACE_TEXT ("SSL_write error"));
  549. return -1;
  550. }
  551. // ************************************************************
  552. // notify external user handler that
  553. // it is now to safe destroy stream
  554. // Return code looks like cancel() return code
  555. // 0 - notified NOTIFIED
  556. // 1 - nothing to notify ALLDONE
  557. // 2 - unable to notify NOT NOTIFIED
  558. // ************************************************************
  559. int
  560. ACE_SSL_Asynch_Stream::notify_close (void)
  561. {
  562. if (this->flags_ & SF_CLOSE_NTF_SENT) // already sent
  563. return 1;
  564. if ((this->flags_ & SF_SHUTDOWN_DONE) == 0) // only after shutdown
  565. return 2; // too early , we will do later
  566. if (this->pending_BIO_count () != 0) // wait for all internal IO
  567. return 2; // too early , we will do later
  568. // create result for future notification
  569. ACE_SSL_Asynch_Result * close_result = 0;
  570. ACE_NEW_RETURN (close_result,
  571. ACE_SSL_Asynch_Result (*this),
  572. 2);
  573. //@@ Not exception safe!
  574. int retval =
  575. close_result->post_completion (this->proactor_->implementation ());
  576. if (retval == 0)
  577. {
  578. this->flags_ |= SF_CLOSE_NTF_SENT;
  579. return 0;
  580. }
  581. delete close_result;
  582. return 2;
  583. }
  584. // ************************************************************
  585. // notify external user handler about user write completion
  586. // Return code looks like cancel() return code
  587. // 0 - notified NOTIFIED/CANCELED
  588. // 1 - nothing to notify ALLDONE
  589. // 2 - unable to notify NOT NOTIFIED/CANCELED
  590. // ************************************************************
  591. int
  592. ACE_SSL_Asynch_Stream::notify_read (int bytes_transferred,
  593. int error)
  594. {
  595. if (ext_read_result_ == 0) //nothing to notify
  596. return 1;
  597. this->ext_read_result_->set_bytes_transferred (bytes_transferred);
  598. this->ext_read_result_->set_error (error);
  599. int retval =
  600. this->ext_read_result_->post_completion (proactor_->implementation ());
  601. if (retval == 0)
  602. {
  603. this->ext_read_result_ = 0;
  604. return 0; // success
  605. }
  606. return 2; // unable to notify
  607. }
  608. // ************************************************************
  609. // notify external user handler about user write completion
  610. // Return code looks like cancel() return code
  611. // 0 - notified NOTIFIED/CANCELED
  612. // 1 - nothing to notify ALLDONE
  613. // 2 - unable to notify NOT NOTIFIED/CANCELED
  614. // ************************************************************
  615. int
  616. ACE_SSL_Asynch_Stream::notify_write (int bytes_transferred,
  617. int error)
  618. {
  619. if (this->ext_write_result_ == 0) //nothing to notify
  620. return 1;
  621. this->ext_write_result_->set_bytes_transferred (bytes_transferred);
  622. this->ext_write_result_->set_error (error);
  623. int retval =
  624. this->ext_write_result_->post_completion (
  625. this->proactor_->implementation ());
  626. if (retval == 0)
  627. {
  628. this->ext_write_result_ = 0;
  629. return 0; // success
  630. }
  631. return 2; // unable to notify
  632. }
  633. // ************************************************************
  634. // Print SSL errors
  635. // ************************************************************
  636. void
  637. ACE_SSL_Asynch_Stream::print_error (int err_ssl,
  638. const ACE_TCHAR * pText)
  639. {
  640. ACE_DEBUG ((LM_DEBUG,
  641. ACE_TEXT("SSL-error:%d %s\n"),
  642. err_ssl,
  643. pText));
  644. #if OPENSSL_VERSION_NUMBER >= 0x0090601fL
  645. // OpenSSL < 0.9.6a doesn't have ERR_error_string_n() function.
  646. unsigned long lerr = 0;
  647. char buf[1024];
  648. while ((lerr = ERR_get_error()) != 0)
  649. {
  650. ERR_error_string_n (lerr, buf, sizeof buf);
  651. ACE_DEBUG ((LM_DEBUG, "%C\n", buf));
  652. }
  653. #endif /* OPENSSL_VERSION_NUMBER */
  654. }
  655. // ************************************************************
  656. // BIO helper functions
  657. // SSL library will ask BIO to do raw I/O
  658. // BIO will call us to do this
  659. // ************************************************************
  660. int
  661. ACE_SSL_Asynch_Stream::ssl_bio_read (char * buf,
  662. size_t len,
  663. int & errval)
  664. {
  665. // We do not have to acquire mutex
  666. // as we called already with locked mutex
  667. // from do_SSL_state_machine()
  668. errval = 0;
  669. size_t cur_len = this->bio_inp_msg_.length ();
  670. if (cur_len > 0) // there are more data buffered
  671. {
  672. const char * rd_ptr = this->bio_inp_msg_.rd_ptr ();
  673. if (cur_len > len)
  674. {
  675. cur_len = len;
  676. }
  677. ACE_OS::memcpy (buf, rd_ptr, cur_len);
  678. this->bio_inp_msg_.rd_ptr (cur_len); // go ahead
  679. return ACE_Utils::truncate_cast<int> (cur_len);
  680. }
  681. if (this->bio_inp_errno_ != 0) // if was error - it is permanent !
  682. {
  683. errval = this->bio_inp_errno_;
  684. return -1;
  685. }
  686. if (this->bio_inp_flag_ & BF_EOS) // End of stream
  687. {
  688. return 0;
  689. }
  690. errval = EINPROGRESS; // SSL will try later
  691. if (this->bio_inp_flag_ & BF_AIO) // we are busy
  692. {
  693. return -1;
  694. }
  695. if (this->bio_inp_msg_.size (len) != 0)
  696. {
  697. ACE_ERROR
  698. ((LM_ERROR,
  699. ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
  700. ACE_TEXT ("error in ACE_Message_Block::size() ")
  701. ));
  702. errval = EINVAL;
  703. return -1;
  704. }
  705. char * base = this->bio_inp_msg_.base ();
  706. this->bio_inp_msg_.rd_ptr (base);
  707. this->bio_inp_msg_.wr_ptr (base);
  708. if (this->bio_istream_.read (
  709. bio_inp_msg_, // message block
  710. len, // priority
  711. 0, // act
  712. 0, // priority
  713. ACE_SIGRTMIN // default signal
  714. ) == -1)
  715. {
  716. ACE_ERROR
  717. ((LM_ERROR,
  718. ACE_TEXT ("%N:%l (%P|%t) ACE_SSL_Asynch_Stream %p\n"),
  719. ACE_TEXT ("attempt read failed")
  720. ));
  721. errval = EINVAL; // may be leave EINPROGRESS ??
  722. return -1; // to try later
  723. }
  724. this->bio_inp_flag_ |= BF_AIO; // AIO is active
  725. return -1;
  726. }
  727. int
  728. ACE_SSL_Asynch_Stream::ssl_bio_write (const char * buf,
  729. size_t len,
  730. int & errval)
  731. {
  732. // We do not have to acquire mutex
  733. // as we called already with locked mutex
  734. // from do_SSL_state_machine
  735. errval = 0;
  736. if (this->bio_out_flag_ & BF_AIO) // sorry, we are busy
  737. {
  738. errval = EINPROGRESS; // try later
  739. return -1;
  740. }
  741. if (this->bio_out_errno_ != 0) // no recovery
  742. {
  743. errval = this->bio_out_errno_;
  744. return -1;
  745. }
  746. if (this->bio_out_msg_.size (len) != 0)
  747. {
  748. ACE_ERROR
  749. ((LM_ERROR,
  750. ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
  751. ACE_TEXT ("error in ACE_Message_Block::size() ")
  752. ));
  753. errval = EINVAL;
  754. return -1;
  755. }
  756. char * base = this->bio_out_msg_.base ();
  757. this->bio_out_msg_.rd_ptr (base);
  758. this->bio_out_msg_.wr_ptr (base);
  759. if (this->bio_out_msg_.copy (buf, len) == -1)
  760. {
  761. ACE_ERROR
  762. ((LM_ERROR,
  763. ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
  764. ACE_TEXT ("error in ACE_Message_Block::copy() ")
  765. ));
  766. errval = EINVAL;
  767. return -1;
  768. }
  769. if (this->bio_ostream_.write (
  770. this->bio_out_msg_, // message block
  771. len, // priority
  772. 0, // act
  773. 0, // priority
  774. ACE_SIGRTMIN // default signal
  775. ) == -1)
  776. {
  777. ACE_ERROR
  778. ((LM_ERROR,
  779. ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
  780. ACE_TEXT ("attempt write failed")
  781. ));
  782. errval = EINVAL; // may be leave EINPROGRESS ??
  783. return -1; // to try later
  784. }
  785. this->bio_out_flag_ |= BF_AIO; // AIO is active
  786. errval = 0; // Ok, go ahead
  787. return ACE_Utils::truncate_cast<int> (len);
  788. }
  789. // ************************************************************
  790. // Internal IO handlers
  791. // virtual from ACE_Service_Handler
  792. // ************************************************************
  793. void
  794. ACE_SSL_Asynch_Stream::handle_write_stream (
  795. const ACE_Asynch_Write_Stream::Result &result)
  796. {
  797. ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
  798. this->bio_out_flag_ &= ~BF_AIO;
  799. ACE_Message_Block & mb = result.message_block ();
  800. size_t bytes_req = result.bytes_to_write ();
  801. size_t bytes_trn = result.bytes_transferred ();
  802. u_long errval = result.error ();
  803. size_t len = bytes_req - bytes_trn;
  804. if (errval != 0) // error ?
  805. this->bio_out_errno_ = errval; // save err code
  806. else if (len > 0) // TCP/IP overloaded ?
  807. { // continue, rd_ptr at right place
  808. if (this->bio_ostream_.write (
  809. mb, // message block
  810. len, // priority
  811. 0, // act
  812. 0, // priority
  813. ACE_SIGRTMIN // default signal
  814. ) == 0)
  815. {
  816. this->bio_out_flag_ |= BF_AIO;
  817. return;
  818. }
  819. ACE_ERROR
  820. ((LM_ERROR,
  821. ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
  822. ACE_TEXT ("attempt write failed")
  823. ));
  824. this->bio_out_errno_ = EINVAL;
  825. }
  826. this->do_SSL_state_machine ();
  827. return;
  828. }
  829. void
  830. ACE_SSL_Asynch_Stream::handle_read_stream (
  831. const ACE_Asynch_Read_Stream::Result &result)
  832. {
  833. ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
  834. this->bio_inp_flag_ &= ~BF_AIO;
  835. size_t bytes_trn = result.bytes_transferred ();
  836. u_long errval = result.error ();
  837. if (errval != 0) // error ?
  838. this->bio_inp_errno_ = errval; // save err code
  839. else if (bytes_trn == 0) // end of stream ?
  840. this->bio_inp_flag_ |= BF_EOS; // set flag EOS
  841. this->do_SSL_state_machine ();
  842. return;
  843. }
  844. void
  845. ACE_SSL_Asynch_Stream::handle_wakeup (void)
  846. {
  847. ACE_Handler * user_handler = 0;
  848. {
  849. ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_));
  850. this->flags_ |= SF_DELETE_ENABLE;
  851. user_handler = this->ext_handler_;
  852. }
  853. if (user_handler != 0)
  854. user_handler->handle_wakeup();
  855. }
  856. int
  857. ACE_SSL_Asynch_Stream::pending_BIO_count (void)
  858. {
  859. int ret = 0;
  860. if (this->bio_inp_flag_ & BF_AIO)
  861. ++ret;
  862. if (this->bio_out_flag_ & BF_AIO)
  863. ++ret;
  864. return ret;
  865. }
  866. ACE_END_VERSIONED_NAMESPACE_DECL
  867. #endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
  868. ACE_HAS_AIO_CALLS) */