diff options
Diffstat (limited to 'ACE/ace/SSL/SSL_SOCK_Stream.cpp')
-rw-r--r-- | ACE/ace/SSL/SSL_SOCK_Stream.cpp | 583 |
1 files changed, 0 insertions, 583 deletions
diff --git a/ACE/ace/SSL/SSL_SOCK_Stream.cpp b/ACE/ace/SSL/SSL_SOCK_Stream.cpp deleted file mode 100644 index 46130a79fc7..00000000000 --- a/ACE/ace/SSL/SSL_SOCK_Stream.cpp +++ /dev/null @@ -1,583 +0,0 @@ -// $Id$ - -#include "ace/Handle_Set.h" -#include "ace/Log_Msg.h" -#include "ace/Countdown_Time.h" -#include "ace/OS_NS_string.h" -#include "ace/OS_NS_sys_select.h" -#include "ace/OS_Memory.h" - -#include <openssl/err.h> - -#include "SSL_SOCK_Stream.h" - -#if !defined (__ACE_INLINE__) -#include "SSL_SOCK_Stream.inl" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID (ACE_SSL, - SSL_SOCK_Stream, - "$Id$") - -ACE_BEGIN_VERSIONED_NAMESPACE_DECL - -ACE_ALLOC_HOOK_DEFINE(ACE_SSL_SOCK_Stream) - -ACE_SSL_SOCK_Stream::ACE_SSL_SOCK_Stream (ACE_SSL_Context *context) - : ssl_ (0), - stream_ () -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::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, - "(%P|%t) ACE_SSL_SOCK_Stream " - "- cannot allocate new SSL structure %p\n", - ACE_TEXT (""))); - } -} - -ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream (void) -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream"); - - ::SSL_free (this->ssl_); - - // @@ 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! -} - -ssize_t -ACE_SSL_SOCK_Stream::sendv (const iovec iov[], - size_t n, - const ACE_Time_Value *max_wait_time) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv"); - - // There is subtle problem in this method that occurs when using - // non-blocking IO. The semantics of a non-blocking scatter write - // (sendv()) are not possible to retain with the emulation in this - // method. - - ssize_t bytes_sent = 0; - - ACE_Time_Value t; - ACE_Time_Value *timeout = const_cast<ACE_Time_Value *> (max_wait_time); - - if (max_wait_time != 0) - { - // Make a copy since ACE_Countdown_Time modifies the - // ACE_Time_Value. - t = *max_wait_time; - timeout = &t; - } - - // Take into account the time between each send. - ACE_Countdown_Time countdown (timeout); - - for (size_t i = 0; i < n; ++i) - { - ssize_t const result = this->send (iov[i].iov_base, - iov[i].iov_len, - timeout); - - if (result == -1) - { - // There is a subtle difference in behaviour depending on - // whether or not any data was sent. If no data was sent, - // then always return -1. Otherwise return bytes_sent. - // This gives the caller an opportunity to keep track of - if (bytes_sent > 0) - break; - else - return -1; - } - else - { - bytes_sent += result; - - // Do not continue on to the next loop iteration if the - // amount of data sent was less than the amount data given. - // This avoids a subtle problem where "holes" in the data - // stream would occur if partial sends of a given buffer in - // the iovec array occured. - if (static_cast<size_t> (result) < static_cast<size_t> (iov[i].iov_len)) - break; - } - - (void) countdown.update (); - } - - return bytes_sent; -} - -ssize_t -ACE_SSL_SOCK_Stream::recvv (iovec *io_vec, - const ACE_Time_Value *timeout) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv"); - - // From ACE_SOCK_IO::recvv(). -#if defined (FIONREAD) - ACE_Handle_Set handle_set; - handle_set.reset (); - handle_set.set_bit (this->get_handle ()); - - io_vec->iov_base = 0; - - // Check the status of the current socket. - switch (ACE_OS::select (int (this->get_handle ()) + 1, - handle_set, - 0, 0, - timeout)) - { - case -1: - return -1; - /* NOTREACHED */ - case 0: - errno = ETIME; - return -1; - /* NOTREACHED */ - default: - // Goes fine, fallthrough to get data - break; - } - - int inlen; - - if (ACE_OS::ioctl (this->get_handle (), - FIONREAD, - &inlen) == -1) - return -1; - else if (inlen > 0) - { - ACE_NEW_RETURN (io_vec->iov_base, - char[inlen], - -1); - io_vec->iov_len = this->recv (io_vec->iov_base, - inlen); - return io_vec->iov_len; - } - else - return 0; -#else - ACE_UNUSED_ARG (io_vec); - ACE_UNUSED_ARG (timeout); - ACE_NOTSUP_RETURN (-1); -#endif /* FIONREAD */ -} - -ssize_t -ACE_SSL_SOCK_Stream::send (const void *buf, - size_t len, - int flags, - const ACE_Time_Value *timeout) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::send"); - - // If SSL has data in the buffer, i.e. SSL_pending() returns a - // non-zero value, then don't block on select(). - if (timeout == 0 || ::SSL_pending (this->ssl_)) - return this->send (buf, len, flags); - - int val = 0; - if (ACE::enter_send_timedwait (this->get_handle (), - timeout, - val) == -1) - return -1; - - ssize_t const bytes_transferred = this->send (buf, len, flags); - - ACE::restore_non_blocking_mode (this->get_handle (), val); - - return bytes_transferred; -} - -ssize_t -ACE_SSL_SOCK_Stream::recv (void *buf, - size_t n, - int flags, - const ACE_Time_Value *timeout) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::recv"); - - return this->recv_i (buf, n, flags, timeout); -} - - -ssize_t -ACE_SSL_SOCK_Stream::send (size_t n, ...) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::send"); - - size_t const total_tuples = n / 2; - - va_list argp; - va_start (argp, n); - - ssize_t bytes_sent = 0; - - // NOTE: This method used to fill an IO vector (e.g. iovec) and then - // send it using a scatter write (sendv()). However, it is - // not possible to emulate a non-blocking scatter write over - // SSL. As such, there is no point in attempting to use - // scatter writes over SSL. - for (size_t i = 0; i < total_tuples; ++i) - { - ssize_t const data_len = va_arg (argp, ssize_t); - ssize_t const result = this->send (va_arg (argp, char *), data_len); - - if (result == -1) - { - // There is a subtle difference in behaviour depending on - // whether or not any data was sent. If no data was sent, - // then always return -1. Otherwise return bytes_sent. - // This gives the caller an opportunity to keep track of - // which data was actually sent. - if (bytes_sent > 0) - break; - else - { - va_end (argp); - return -1; - } - } - else - { - bytes_sent += result; - - // Do not continue on to the next loop iteration if the - // amount of data sent was less than the amount of data - // given. This avoids a subtle problem where "holes" in the - // data stream would occur if partial sends of a given - // buffer in the varargs occured. - if (result < data_len) - break; - - } - } - - va_end (argp); - - return bytes_sent; -} - -ssize_t -ACE_SSL_SOCK_Stream::recv (size_t n, ...) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::recv"); - - size_t const total_tuples = n / 2; - - va_list argp; - va_start (argp, n); - - ssize_t bytes_recv = 0; - - for (size_t i = 0; i < total_tuples; ++i) - { - ssize_t const data_len = va_arg (argp, ssize_t); - ssize_t const result = this->recv (va_arg (argp, char *), data_len); - - if (result == -1) - { - // There is a subtle difference in behaviour depending on - // whether or not any data was received. If no data was - // received, then always return -1. Otherwise return - // bytes_received. This gives the caller an opportunity to - // keep track of which data was actually received. - if (bytes_recv > 0) - break; - else - { - va_end (argp); - return -1; - } - } - else - { - bytes_recv += result; - - // Do not continue on to the next loop iteration if the - // amount of data received was less than the amount of data - // desired. This avoids a subtle problem where "holes" in - // the data stream would occur if partial receives of a - // given buffer in the varargs occured. - if (result < data_len) - break; - - } - } - - va_end (argp); - - return bytes_recv; -} - -ssize_t -ACE_SSL_SOCK_Stream::send_n (const void *buf, - size_t len, - int flags, - const ACE_Time_Value *timeout, - size_t *bt) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n"); - - // No support for send flags in SSL. - if (flags != 0) - ACE_NOTSUP_RETURN (-1); - - /* This code mimics ACE::send_n */ - // Total number of bytes written. - size_t temp = 0; - size_t &bytes_transferred = ((bt == 0) ? temp : *bt); - - // Actual number of bytes written in each <send> attempt - ssize_t n = 0; - - for (bytes_transferred = 0; - bytes_transferred < len; - bytes_transferred += n) - { - n = this->send ((const char*) buf + bytes_transferred, - len - bytes_transferred, - flags, - timeout); - - if (n < 0) - { - if (errno == EWOULDBLOCK) - { - // If blocked, try again. - n = 0; - continue; - } - else - return -1; - } - else if (n == 0) - break; - } - - return bytes_transferred; -} - -ssize_t -ACE_SSL_SOCK_Stream::recv_n (void *buf, - size_t len, - int flags, - const ACE_Time_Value *timeout, - size_t *bt) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n"); - - if (flags != 0) - { - if ((flags | MSG_PEEK) != MSG_PEEK) - ACE_NOTSUP_RETURN (-1); - } - - size_t temp = 0; - size_t &bytes_transferred = ((bt == 0) ? temp : *bt); - - ssize_t n = 0; - - for (bytes_transferred = 0; - bytes_transferred < len; - bytes_transferred += n) - { - n = this->recv ((char*) buf + bytes_transferred, - len - bytes_transferred, - flags, - timeout); - - if (n < 0) - { - if (errno == EWOULDBLOCK) - { - // If blocked, try again. - n = 0; - continue; - } - else - return -1; - } - else if (n == 0) - break; - } - - return bytes_transferred; -} - -ssize_t -ACE_SSL_SOCK_Stream::recv_n (void *buf, int len, int flags) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n"); - - if (flags != 0) - { - if ((flags | MSG_PEEK) != MSG_PEEK) - ACE_NOTSUP_RETURN (-1); - } - - ssize_t bytes_transferred = 0; - ssize_t n = 0; - - for (bytes_transferred = 0; - bytes_transferred < len; - bytes_transferred += n) - { - n = this->recv ((char*) buf + bytes_transferred, - len - bytes_transferred, - flags); - - if (n < 0) - { - if (errno == EWOULDBLOCK) - { - // If blocked, try again. - n = 0; - continue; - } - else - return -1; - } - else if (n == 0) - break; - } - - return bytes_transferred; -} - -ssize_t -ACE_SSL_SOCK_Stream::send_n (const void *buf, int len, int flags) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n"); - - // Send flags are unsupported in SSL - if (flags != 0) - ACE_NOTSUP_RETURN (-1); - - /* The following code mimics <ACE::send_n> */ - size_t bytes_transferred = 0; - ssize_t n = 0; - - for (bytes_transferred = 0; - bytes_transferred < (size_t) len; - bytes_transferred += n) - { - n = this->send ((const char*) buf + bytes_transferred, - len - bytes_transferred, - flags); - - if (n < 0) - { - if (errno == EWOULDBLOCK) - { - // If blocked, try again. - n = 0; - continue; - } - else - return -1; - } - else if (n == 0) - break; - } - - return bytes_transferred; -} - -ssize_t -ACE_SSL_SOCK_Stream::sendv_n (const iovec iov[], size_t iovcnt) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv_n"); - - ssize_t bytes_sent = 0; - - for (size_t i = 0; i < iovcnt; ++i) - { - ssize_t result = this->send_n (iov[i].iov_base, - iov[i].iov_len); - - - if (result == -1) - { - // There is a subtle difference in behaviour depending on - // whether or not any data was sent. If no data was sent, - // then always return -1. Otherwise return bytes_sent. - // This gives the caller an opportunity to keep track of - // which data was actually sent. - if (bytes_sent > 0) - break; - else - return -1; - } - else - bytes_sent += result; - } - - return bytes_sent; -} - -ssize_t -ACE_SSL_SOCK_Stream::recvv_n (iovec iov[], size_t iovcnt) const -{ - ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv_n"); - - ssize_t bytes_read = 0; - - for (size_t i = 0; i < iovcnt; ++i) - { - ssize_t const result = this->recv_n (iov[i].iov_base, - iov[i].iov_len); - - if (result == -1) - { - // There is a subtle difference in behaviour depending on - // whether or not any data was read. If no data was read, - // then always return -1. Otherwise return bytes_read. - // This gives the caller an opportunity to keep track of - // which data was actually read. - if (bytes_read > 0) - break; - else - return -1; - } - else - bytes_read += result; - } - - return bytes_read; -} - -int -ACE_SSL_SOCK_Stream::get_remote_addr (ACE_Addr &addr) const -{ - // Some applications use get_remote_addr() as a way of determining - // whether or not a connection has been established. In SSL's case, - // the remote addr will be available once the TCP handshake has been - // complete. Despite that fact, the SSL connection may not have - // been completed. In such a case, a successful return from - // get_remote_addr() would be misleading. - - if (SSL_is_init_finished (this->ssl_)) - return this->ACE_SSL_SOCK::get_remote_addr (addr); - - if (this->get_handle () == ACE_INVALID_HANDLE) - errno = EBADF; - else - errno = ENOTCONN; - - return -1; -} - -ACE_END_VERSIONED_NAMESPACE_DECL |