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

/dep/acelite/ace/SSL/SSL_SOCK_Stream.cpp

https://bitbucket.org/CatrinaEmu/core/
C++ | 630 lines | 450 code | 101 blank | 79 comment | 83 complexity | cd64d6d3a2b4bae2bed7e7a726948c09 MD5 | raw file
Possible License(s): GPL-2.0
  1. // $Id: SSL_SOCK_Stream.cpp 82577 2008-08-09 17:43:11Z mitza $
  2. #include "ace/Handle_Set.h"
  3. #include "ace/Log_Msg.h"
  4. #include "ace/Countdown_Time.h"
  5. #include "ace/OS_NS_string.h"
  6. #include "ace/OS_NS_sys_select.h"
  7. #include "ace/OS_Memory.h"
  8. #include <openssl/err.h>
  9. #include "SSL_SOCK_Stream.h"
  10. #if !defined (__ACE_INLINE__)
  11. #include "SSL_SOCK_Stream.inl"
  12. #endif /* __ACE_INLINE__ */
  13. ACE_RCSID (ACE_SSL,
  14. SSL_SOCK_Stream,
  15. "$Id: SSL_SOCK_Stream.cpp 82577 2008-08-09 17:43:11Z mitza $")
  16. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  17. ACE_ALLOC_HOOK_DEFINE(ACE_SSL_SOCK_Stream)
  18. ACE_SSL_SOCK_Stream::ACE_SSL_SOCK_Stream (ACE_SSL_Context *context)
  19. : ssl_ (0),
  20. stream_ ()
  21. {
  22. ACE_TRACE ("ACE_SSL_SOCK_Stream::ACE_SSL_SOCK_Stream");
  23. ACE_SSL_Context * ctx =
  24. (context == 0 ? ACE_SSL_Context::instance () : context);
  25. this->ssl_ = ::SSL_new (ctx->context ());
  26. if (this->ssl_ == 0)
  27. {
  28. ACE_ERROR ((LM_ERROR,
  29. "(%P|%t) ACE_SSL_SOCK_Stream "
  30. "- cannot allocate new SSL structure %p\n",
  31. ACE_TEXT ("")));
  32. }
  33. }
  34. ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream (void)
  35. {
  36. ACE_TRACE ("ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream");
  37. ::SSL_free (this->ssl_);
  38. // @@ Question: should we reference count the Context object or
  39. // leave that to the application developer? We do not reference
  40. // count reactors (for example) and following some simple rules
  41. // seems to work fine!
  42. }
  43. ssize_t
  44. ACE_SSL_SOCK_Stream::sendv (const iovec iov[],
  45. size_t n,
  46. const ACE_Time_Value *max_wait_time) const
  47. {
  48. ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv");
  49. // There is subtle problem in this method that occurs when using
  50. // non-blocking IO. The semantics of a non-blocking scatter write
  51. // (sendv()) are not possible to retain with the emulation in this
  52. // method.
  53. ssize_t bytes_sent = 0;
  54. ACE_Time_Value t;
  55. ACE_Time_Value *timeout = const_cast<ACE_Time_Value *> (max_wait_time);
  56. if (max_wait_time != 0)
  57. {
  58. // Make a copy since ACE_Countdown_Time modifies the
  59. // ACE_Time_Value.
  60. t = *max_wait_time;
  61. timeout = &t;
  62. }
  63. // Take into account the time between each send.
  64. ACE_Countdown_Time countdown (timeout);
  65. for (size_t i = 0; i < n; ++i)
  66. {
  67. ssize_t const result = this->send (iov[i].iov_base,
  68. iov[i].iov_len,
  69. timeout);
  70. if (result == -1)
  71. {
  72. // There is a subtle difference in behaviour depending on
  73. // whether or not any data was sent. If no data was sent,
  74. // then always return -1. Otherwise return bytes_sent.
  75. // This gives the caller an opportunity to keep track of
  76. if (bytes_sent > 0)
  77. break;
  78. else
  79. return -1;
  80. }
  81. else
  82. {
  83. bytes_sent += result;
  84. // Do not continue on to the next loop iteration if the
  85. // amount of data sent was less than the amount data given.
  86. // This avoids a subtle problem where "holes" in the data
  87. // stream would occur if partial sends of a given buffer in
  88. // the iovec array occured.
  89. if (static_cast<size_t> (result) < static_cast<size_t> (iov[i].iov_len))
  90. break;
  91. }
  92. (void) countdown.update ();
  93. }
  94. return bytes_sent;
  95. }
  96. ssize_t
  97. ACE_SSL_SOCK_Stream::recvv (iovec *io_vec,
  98. const ACE_Time_Value *timeout) const
  99. {
  100. ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv");
  101. // From ACE_SOCK_IO::recvv().
  102. #if defined (FIONREAD)
  103. ACE_Handle_Set handle_set;
  104. handle_set.reset ();
  105. handle_set.set_bit (this->get_handle ());
  106. io_vec->iov_base = 0;
  107. // Check the status of the current socket.
  108. switch (
  109. ACE_OS::select (int (this->get_handle ()) + 1,
  110. handle_set,
  111. 0,
  112. 0,
  113. timeout))
  114. {
  115. case -1:
  116. return -1;
  117. /* NOTREACHED */
  118. case 0:
  119. errno = ETIME;
  120. return -1;
  121. /* NOTREACHED */
  122. default:
  123. // Goes fine, fallthrough to get data
  124. break;
  125. }
  126. int inlen;
  127. if (ACE_OS::ioctl (this->get_handle (),
  128. FIONREAD,
  129. &inlen) == -1)
  130. return -1;
  131. else if (inlen > 0)
  132. {
  133. ACE_NEW_RETURN (io_vec->iov_base,
  134. char[inlen],
  135. -1);
  136. io_vec->iov_len = this->recv (io_vec->iov_base,
  137. inlen);
  138. return io_vec->iov_len;
  139. }
  140. else
  141. return 0;
  142. #else
  143. ACE_UNUSED_ARG (io_vec);
  144. ACE_UNUSED_ARG (timeout);
  145. ACE_NOTSUP_RETURN (-1);
  146. #endif /* FIONREAD */
  147. }
  148. ssize_t
  149. ACE_SSL_SOCK_Stream::send (const void *buf,
  150. size_t len,
  151. int flags,
  152. const ACE_Time_Value *timeout) const
  153. {
  154. ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
  155. // If SSL has data in the buffer, i.e. SSL_pending() returns a
  156. // non-zero value, then don't block on select().
  157. if (timeout == 0 || ::SSL_pending (this->ssl_))
  158. return this->send (buf, len, flags);
  159. int val = 0;
  160. if (ACE::enter_send_timedwait (this->get_handle (),
  161. timeout,
  162. val) == -1)
  163. return -1;
  164. ssize_t const bytes_transferred = this->send (buf, len, flags);
  165. ACE::restore_non_blocking_mode (this->get_handle (), val);
  166. return bytes_transferred;
  167. }
  168. ssize_t
  169. ACE_SSL_SOCK_Stream::recv (void *buf,
  170. size_t n,
  171. int flags,
  172. const ACE_Time_Value *timeout) const
  173. {
  174. ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
  175. return this->recv_i (buf, n, flags, timeout);
  176. }
  177. ssize_t
  178. ACE_SSL_SOCK_Stream::send (size_t n, ...) const
  179. {
  180. ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
  181. size_t const total_tuples = n / 2;
  182. va_list argp;
  183. va_start (argp, n);
  184. ssize_t bytes_sent = 0;
  185. // NOTE: This method used to fill an IO vector (e.g. iovec) and then
  186. // send it using a scatter write (sendv()). However, it is
  187. // not possible to emulate a non-blocking scatter write over
  188. // SSL. As such, there is no point in attempting to use
  189. // scatter writes over SSL.
  190. for (size_t i = 0; i < total_tuples; ++i)
  191. {
  192. ssize_t const data_len = va_arg (argp, ssize_t);
  193. ssize_t const result = this->send (va_arg (argp, char *), data_len);
  194. if (result == -1)
  195. {
  196. // There is a subtle difference in behaviour depending on
  197. // whether or not any data was sent. If no data was sent,
  198. // then always return -1. Otherwise return bytes_sent.
  199. // This gives the caller an opportunity to keep track of
  200. // which data was actually sent.
  201. if (bytes_sent > 0)
  202. break;
  203. else
  204. {
  205. va_end (argp);
  206. return -1;
  207. }
  208. }
  209. else
  210. {
  211. bytes_sent += result;
  212. // Do not continue on to the next loop iteration if the
  213. // amount of data sent was less than the amount of data
  214. // given. This avoids a subtle problem where "holes" in the
  215. // data stream would occur if partial sends of a given
  216. // buffer in the varargs occured.
  217. if (result < data_len)
  218. break;
  219. }
  220. }
  221. va_end (argp);
  222. return bytes_sent;
  223. }
  224. ssize_t
  225. ACE_SSL_SOCK_Stream::recv (size_t n, ...) const
  226. {
  227. ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
  228. size_t const total_tuples = n / 2;
  229. va_list argp;
  230. va_start (argp, n);
  231. ssize_t bytes_recv = 0;
  232. for (size_t i = 0; i < total_tuples; ++i)
  233. {
  234. ssize_t const data_len = va_arg (argp, ssize_t);
  235. ssize_t const result = this->recv (va_arg (argp, char *), data_len);
  236. if (result == -1)
  237. {
  238. // There is a subtle difference in behaviour depending on
  239. // whether or not any data was received. If no data was
  240. // received, then always return -1. Otherwise return
  241. // bytes_received. This gives the caller an opportunity to
  242. // keep track of which data was actually received.
  243. if (bytes_recv > 0)
  244. {
  245. break;
  246. }
  247. else
  248. {
  249. va_end (argp);
  250. return -1;
  251. }
  252. }
  253. else
  254. {
  255. bytes_recv += result;
  256. // Do not continue on to the next loop iteration if the
  257. // amount of data received was less than the amount of data
  258. // desired. This avoids a subtle problem where "holes" in
  259. // the data stream would occur if partial receives of a
  260. // given buffer in the varargs occured.
  261. if (result < data_len)
  262. {
  263. break;
  264. }
  265. }
  266. }
  267. va_end (argp);
  268. return bytes_recv;
  269. }
  270. ssize_t
  271. ACE_SSL_SOCK_Stream::send_n (const void *buf,
  272. size_t len,
  273. int flags,
  274. const ACE_Time_Value *timeout,
  275. size_t *bt) const
  276. {
  277. ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
  278. // No support for send flags in SSL.
  279. if (flags != 0)
  280. {
  281. ACE_NOTSUP_RETURN (-1);
  282. }
  283. /* This code mimics ACE::send_n */
  284. // Total number of bytes written.
  285. size_t temp = 0;
  286. size_t &bytes_transferred = ((bt == 0) ? temp : *bt);
  287. // Actual number of bytes written in each <send> attempt
  288. ssize_t n = 0;
  289. for (bytes_transferred = 0;
  290. bytes_transferred < len;
  291. bytes_transferred += n)
  292. {
  293. n = this->send ((const char*) buf + bytes_transferred,
  294. len - bytes_transferred,
  295. flags,
  296. timeout);
  297. if (n < 0)
  298. {
  299. if (errno == EWOULDBLOCK)
  300. {
  301. // If blocked, try again.
  302. n = 0;
  303. continue;
  304. }
  305. else
  306. {
  307. return -1;
  308. }
  309. }
  310. else if (n == 0)
  311. {
  312. break;
  313. }
  314. }
  315. return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);
  316. }
  317. ssize_t
  318. ACE_SSL_SOCK_Stream::recv_n (void *buf,
  319. size_t len,
  320. int flags,
  321. const ACE_Time_Value *timeout,
  322. size_t *bt) const
  323. {
  324. ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
  325. if (flags != 0)
  326. {
  327. if ((flags | MSG_PEEK) != MSG_PEEK)
  328. {
  329. ACE_NOTSUP_RETURN (-1);
  330. }
  331. }
  332. size_t temp = 0;
  333. size_t &bytes_transferred = ((bt == 0) ? temp : *bt);
  334. ssize_t n = 0;
  335. for (bytes_transferred = 0;
  336. bytes_transferred < len;
  337. bytes_transferred += n)
  338. {
  339. n = this->recv ((char*) buf + bytes_transferred,
  340. len - bytes_transferred,
  341. flags,
  342. timeout);
  343. if (n < 0)
  344. {
  345. if (errno == EWOULDBLOCK)
  346. {
  347. // If blocked, try again.
  348. n = 0;
  349. continue;
  350. }
  351. else
  352. {
  353. return -1;
  354. }
  355. }
  356. else if (n == 0)
  357. {
  358. break;
  359. }
  360. }
  361. return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);
  362. }
  363. ssize_t
  364. ACE_SSL_SOCK_Stream::recv_n (void *buf, int len, int flags) const
  365. {
  366. ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
  367. if (flags != 0)
  368. {
  369. if ((flags | MSG_PEEK) != MSG_PEEK)
  370. {
  371. ACE_NOTSUP_RETURN (-1);
  372. }
  373. }
  374. ssize_t bytes_transferred = 0;
  375. ssize_t n = 0;
  376. for (bytes_transferred = 0;
  377. bytes_transferred < len;
  378. bytes_transferred += n)
  379. {
  380. n = this->recv ((char*) buf + bytes_transferred,
  381. len - bytes_transferred,
  382. flags);
  383. if (n < 0)
  384. {
  385. if (errno == EWOULDBLOCK)
  386. {
  387. // If blocked, try again.
  388. n = 0;
  389. continue;
  390. }
  391. else
  392. {
  393. return -1;
  394. }
  395. }
  396. else if (n == 0)
  397. {
  398. break;
  399. }
  400. }
  401. return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);
  402. }
  403. ssize_t
  404. ACE_SSL_SOCK_Stream::send_n (const void *buf, int len, int flags) const
  405. {
  406. ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
  407. // Send flags are unsupported in SSL
  408. if (flags != 0)
  409. {
  410. ACE_NOTSUP_RETURN (-1);
  411. }
  412. /* The following code mimics <ACE::send_n> */
  413. size_t bytes_transferred = 0;
  414. ssize_t n = 0;
  415. for (bytes_transferred = 0;
  416. bytes_transferred < (size_t) len;
  417. bytes_transferred += n)
  418. {
  419. n = this->send ((const char*) buf + bytes_transferred,
  420. len - bytes_transferred,
  421. flags);
  422. if (n < 0)
  423. {
  424. if (errno == EWOULDBLOCK)
  425. {
  426. // If blocked, try again.
  427. n = 0;
  428. continue;
  429. }
  430. else
  431. {
  432. return -1;
  433. }
  434. }
  435. else if (n == 0)
  436. {
  437. break;
  438. }
  439. }
  440. return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);
  441. }
  442. ssize_t
  443. ACE_SSL_SOCK_Stream::sendv_n (const iovec iov[], size_t iovcnt) const
  444. {
  445. ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv_n");
  446. ssize_t bytes_sent = 0;
  447. for (size_t i = 0; i < iovcnt; ++i)
  448. {
  449. ssize_t result = this->send_n (iov[i].iov_base,
  450. iov[i].iov_len);
  451. if (result == -1)
  452. {
  453. // There is a subtle difference in behaviour depending on
  454. // whether or not any data was sent. If no data was sent,
  455. // then always return -1. Otherwise return bytes_sent.
  456. // This gives the caller an opportunity to keep track of
  457. // which data was actually sent.
  458. if (bytes_sent > 0)
  459. {
  460. break;
  461. }
  462. else
  463. {
  464. return -1;
  465. }
  466. }
  467. else
  468. {
  469. bytes_sent += result;
  470. }
  471. }
  472. return bytes_sent;
  473. }
  474. ssize_t
  475. ACE_SSL_SOCK_Stream::recvv_n (iovec iov[], size_t iovcnt) const
  476. {
  477. ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv_n");
  478. ssize_t bytes_read = 0;
  479. for (size_t i = 0; i < iovcnt; ++i)
  480. {
  481. ssize_t const result = this->recv_n (iov[i].iov_base,
  482. iov[i].iov_len);
  483. if (result == -1)
  484. {
  485. // There is a subtle difference in behaviour depending on
  486. // whether or not any data was read. If no data was read,
  487. // then always return -1. Otherwise return bytes_read.
  488. // This gives the caller an opportunity to keep track of
  489. // which data was actually read.
  490. if (bytes_read > 0)
  491. {
  492. break;
  493. }
  494. else
  495. {
  496. return -1;
  497. }
  498. }
  499. else
  500. {
  501. bytes_read += result;
  502. }
  503. }
  504. return bytes_read;
  505. }
  506. int
  507. ACE_SSL_SOCK_Stream::get_remote_addr (ACE_Addr &addr) const
  508. {
  509. // Some applications use get_remote_addr() as a way of determining
  510. // whether or not a connection has been established. In SSL's case,
  511. // the remote addr will be available once the TCP handshake has been
  512. // complete. Despite that fact, the SSL connection may not have
  513. // been completed. In such a case, a successful return from
  514. // get_remote_addr() would be misleading.
  515. if (SSL_is_init_finished (this->ssl_))
  516. {
  517. return this->ACE_SSL_SOCK::get_remote_addr (addr);
  518. }
  519. if (this->get_handle () == ACE_INVALID_HANDLE)
  520. {
  521. errno = EBADF;
  522. }
  523. else
  524. {
  525. errno = ENOTCONN;
  526. }
  527. return -1;
  528. }
  529. ACE_END_VERSIONED_NAMESPACE_DECL