ACE_SSL_SOCK_Stream Class Reference

Defines methods in the ACE_SSL_SOCK_Stream abstraction. More...

#include <SSL_SOCK_Stream.h>

Inheritance diagram for ACE_SSL_SOCK_Stream:

Inheritance graph
[legend]
Collaboration diagram for ACE_SSL_SOCK_Stream:

Collaboration graph
[legend]
List of all members.

Public Types

typedef ACE_INET_Addr PEER_ADDR
 Meta-type info.


Public Member Functions

 ACE_SSL_SOCK_Stream (ACE_SSL_Context *context=ACE_SSL_Context::instance())
 Constructor.

 ~ACE_SSL_SOCK_Stream (void)
 Destructor.

ssize_t send (const void *buf, size_t n, int flags) const
ssize_t recv (void *buf, size_t n, int flags) const
ssize_t send (const void *buf, size_t n) const
ssize_t recv (void *buf, size_t n) const
ssize_t sendv (const iovec iov[], size_t n, const ACE_Time_Value *timeout=0) const
 Send an iovec of size n to the ssl socket.

ssize_t recvv (iovec *io_vec, const ACE_Time_Value *timeout=0) const
ssize_t send (const void *buf, size_t n, int flags, const ACE_Time_Value *timeout) const
ssize_t recv (void *buf, size_t n, int flags, const ACE_Time_Value *timeout) const
ssize_t send (const void *buf, size_t n, const ACE_Time_Value *timeout) const
ssize_t recv (void *buf, size_t n, const ACE_Time_Value *timeout) const
ssize_t send (size_t n,...) const
 Send n varargs messages to the connected ssl socket.

ssize_t recv (size_t n,...) const
 Recv n varargs messages to the connected ssl socket.

ssize_t send_n (const void *buf, int n) const
 Send n bytes, keep trying until n are sent.

ssize_t recv_n (void *buf, int n) const
 Recv n bytes, keep trying until n are received.

ssize_t sendv_n (const iovec iov[], size_t n) const
ssize_t recvv_n (iovec iov[], size_t n) const
 Receive an iovec of size n to the connected socket.

int close (void)
 Close down the socket.

void set_handle (ACE_HANDLE fd)
 Overridden set_handle() method.

SSL * ssl (void) const
 Return a pointer to the underlying SSL structure.

int get_remote_addr (ACE_Addr &) const
ACE_SOCK_Streampeer (void)
 Return the underlying ACE_SOCK_Stream which ACE_SSL runs atop of.

ssize_t send_n (const void *buf, int n, int flags) const
 Send n bytes, keep trying until n are sent.

ssize_t recv_n (void *buf, int n, int flags) const
 Recv n bytes, keep trying until n are sent.

ssize_t send_n (const void *buf, size_t len, int flags, const ACE_Time_Value *timeout, size_t *bytes_transferred=0) const
ssize_t recv_n (void *buf, size_t len, int flags, const ACE_Time_Value *timeout, size_t *bytes_transferred=0) const
int close_reader (void)
 Close down the reader.

int close_writer (void)
 Close down the writer.


Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.


Protected Member Functions

ssize_t send_i (const void *buf, size_t n, int flags) const
ssize_t recv_i (void *buf, size_t n, int flags, const ACE_Time_Value *timeout) const

Private Attributes

ACE_UNIMPLEMENTED_FUNC(void
operator=(const ACE_SSL_SOCK_Stream
&)) ACE_UNIMPLEMENTED_FUNC(ACE_SSL_SOCK_Stream(const
ACE_SSL_SOCK_Stream &)) protected
ACE_SOCK_Stream 
stream_
 The stream which works under the ssl connection.


Detailed Description

Defines methods in the ACE_SSL_SOCK_Stream abstraction.

This class encapsulates the methods and functionality necessary to send and receive data over TLS/SSL.

Since SSL is record-oriented, some additional steps must be taken to make the ACE_SSL_SOCK_Stream interact properly with the Reactor (if one is used) when performing non-blocking IO. In particular, if ::SSL_pending (ssl), where "ssl" is a pointer to the SSL data structure returned from ACE_SSL_SOCK_Stream::ssl(), returns a non-zero value then the event handler that calls the IO methods in this class should return a value greater than zero to force the Reactor to invoke the event handler before polling for additional events (e.g. blocking on select()).
Note:
The user must currently ensure that only one thread services a given SSL session at any given time since underlying SSL implementations, such as OpenSSL, are not entirely thread-safe or reentrant.

Definition at line 62 of file SSL_SOCK_Stream.h.


Member Typedef Documentation

typedef ACE_INET_Addr ACE_SSL_SOCK_Stream::PEER_ADDR
 

Meta-type info.

Definition at line 253 of file SSL_SOCK_Stream.h.


Constructor & Destructor Documentation

ACE_SSL_SOCK_Stream::ACE_SSL_SOCK_Stream ACE_SSL_Context context = ACE_SSL_Context::instance()  ) 
 

Constructor.

Parameters:
context Pointer to ACE_SSL_Context instance containing the OpenSSL SSL data structure to be associated with this ACE_SSL_SOCK_Stream. The SSL data structure will be copied to make it at least logically independent of the supplied context.

ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream void   ) 
 

Destructor.

Definition at line 46 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE.

00047 {
00048   ACE_TRACE ("ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream");
00049 
00050   ::SSL_free (this->ssl_);
00051 
00052   // @@ Question: should we reference count the Context object or
00053   // leave that to the application developer? We do not reference
00054   // count reactors (for example) and following some simple rules
00055   // seems to work fine!
00056 }


Member Function Documentation

ACE_INLINE int ACE_SSL_SOCK_Stream::close void   ) 
 

Close down the socket.

Reimplemented from ACE_SOCK.

Definition at line 269 of file SSL_SOCK_Stream.inl.

References ACE_TRACE, EWOULDBLOCK, ACE_SSL_SOCK::get_handle(), ACE_SSL_Context::report_error(), and set_handle().

Referenced by ACE_SSL_SOCK_Acceptor::accept(), ACE_SSL_SOCK_Connector::complete(), and ACE_SSL_SOCK_Connector::connect().

00270 {
00271   ACE_TRACE ("ACE_SSL_SOCK_Stream::close");
00272 
00273   if (this->ssl_ == 0 || this->get_handle () == ACE_INVALID_HANDLE)
00274     return 0;  // SSL_SOCK_Stream was never opened.
00275 
00276   // SSL_shutdown() returns 1 on successful shutdown of the SSL
00277   // connection, not 0.
00278   const int status = ::SSL_shutdown (this->ssl_);
00279 
00280   switch (::SSL_get_error (this->ssl_, status))
00281     {
00282     case SSL_ERROR_NONE:
00283     case SSL_ERROR_SYSCALL:  // Ignore this error condition.
00284 
00285       // Reset the SSL object to allow another connection to be made
00286       // using this ACE_SSL_SOCK_Stream instance.  This prevents the
00287       // previous SSL session state from being associated with the new
00288       // SSL session/connection.
00289       (void) ::SSL_clear (this->ssl_);
00290       this->set_handle (ACE_INVALID_HANDLE);
00291       return this->stream_.close ();
00292 
00293     case SSL_ERROR_WANT_READ:
00294     case SSL_ERROR_WANT_WRITE:
00295       errno = EWOULDBLOCK;
00296       break;
00297 
00298     default:
00299       ACE_SSL_Context::report_error ();
00300 
00301       ACE_Errno_Guard error (errno);   // Save/restore errno
00302       (void) this->stream_.close ();
00303 
00304       return -1;
00305     }
00306 
00307   return -1;
00308 }

ACE_INLINE int ACE_SSL_SOCK_Stream::close_reader void   ) 
 

Close down the reader.

Selectively close endpoints.

Definition at line 255 of file SSL_SOCK_Stream.inl.

References ACE_TRACE.

00256 {
00257   ACE_TRACE ("ACE_SSL_SOCK_Stream::close_reader");
00258   return this->stream_.close_reader ();
00259 }

ACE_INLINE int ACE_SSL_SOCK_Stream::close_writer void   ) 
 

Close down the writer.

Definition at line 262 of file SSL_SOCK_Stream.inl.

References ACE_TRACE.

00263 {
00264   ACE_TRACE ("ACE_SSL_SOCK_Stream::close_writer");
00265   return this->stream_.close_writer ();
00266 }

int ACE_SSL_SOCK_Stream::get_remote_addr ACE_Addr  )  const
 

Return the address of the remotely connected peer (if there is one), in the referenced . Returns 0 if successful, else -1.

Note:
If the TCP connection has been completed but the SSL connection has not been completed yet, -1 will be returned.

Reimplemented from ACE_SOCK.

Definition at line 566 of file SSL_SOCK_Stream.cpp.

References ENOTCONN, ACE_SSL_SOCK::get_handle(), and ACE_SOCK::get_remote_addr().

00567 {
00568   // Some applications use get_remote_addr() as a way of determining
00569   // whether or not a connection has been established.  In SSL's case,
00570   // the remote addr will be available once the TCP handshake has been
00571   // complete.  Despite that fact, the SSL connection may not have
00572   // been completed.  In such a case, a successful return from
00573   // get_remote_addr() would be misleading.
00574 
00575   if (SSL_is_init_finished (this->ssl_))
00576     return this->ACE_SSL_SOCK::get_remote_addr (addr);
00577 
00578   if (this->get_handle () == ACE_INVALID_HANDLE)
00579     errno = EBADF;
00580   else
00581     errno = ENOTCONN;
00582 
00583   return -1;
00584 }

ACE_INLINE ACE_SOCK_Stream & ACE_SSL_SOCK_Stream::peer void   ) 
 

Return the underlying ACE_SOCK_Stream which ACE_SSL runs atop of.

Definition at line 311 of file SSL_SOCK_Stream.inl.

References ACE_TRACE.

Referenced by ACE_SSL_SOCK_Connector::complete(), and ACE_SSL_SOCK_Connector::connect().

00312 {
00313   ACE_TRACE ("ACE_SSL_SOCK_Stream::peer");
00314   return this->stream_;
00315 }

ssize_t ACE_SSL_SOCK_Stream::recv size_t  n,
... 
const
 

Recv n varargs messages to the connected ssl socket.

Definition at line 276 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, recv(), and ssize_t.

00277 {
00278   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00279 
00280   const size_t total_tuples = n / 2;
00281 
00282   va_list argp;
00283   va_start (argp, n);
00284 
00285   ssize_t bytes_recv = 0;
00286 
00287   for (size_t i = 0; i < total_tuples; ++i)
00288     {
00289       const ssize_t data_len = va_arg (argp, ssize_t);
00290       const ssize_t result = this->recv (va_arg (argp, char *),
00291                                          data_len);
00292 
00293       if (result == -1)
00294         {
00295           // There is a subtle difference in behaviour depending on
00296           // whether or not any data was received.  If no data was
00297           // received, then always return -1.  Otherwise return
00298           // bytes_received.  This gives the caller an opportunity to
00299           // keep track of which data was actually received.
00300           if (bytes_recv > 0)
00301             break;
00302           else
00303             {
00304               va_end (argp);
00305               return -1;
00306             }
00307         }
00308       else
00309         {
00310           bytes_recv += result;
00311 
00312           // Do not continue on to the next loop iteration if the
00313           // amount of data received was less than the amount of data
00314           // desired.  This avoids a subtle problem where "holes" in
00315           // the data stream would occur if partial receives of a
00316           // given buffer in the varargs occured.
00317           if (result < data_len)
00318             break;
00319 
00320         }
00321     }
00322 
00323   va_end (argp);
00324 
00325   return bytes_recv;
00326 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::recv void *  buf,
size_t  n,
const ACE_Time_Value timeout
const
 

Wait up to timeout amount of time to receive up to n bytes into buf (uses the recv() call). If recv() times out a -1 is returned with errno == ETIME. If it succeeds the number of bytes received is returned.

Definition at line 232 of file SSL_SOCK_Stream.inl.

References ACE_TRACE, and recv().

00235 {
00236   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00237   return this->recv (buf, n, 0, timeout);
00238 }

ssize_t ACE_SSL_SOCK_Stream::recv void *  buf,
size_t  n,
int  flags,
const ACE_Time_Value timeout
const
 

Wait up to timeout amount of time to receive up to n bytes into buf (uses the recv() call). If recv() times out -1 is returned with errno == ETIME. If it succeeds the number of bytes received is returned. MSG_PEEK is the only supported flag.

Definition at line 206 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, and recv_i().

00210 {
00211   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00212 
00213   return this->recv_i (buf, n, flags, timeout);
00214 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::recv void *  buf,
size_t  n
const
 

Recv an n byte buffer from the ssl socket using the semantics of read(2).

Definition at line 214 of file SSL_SOCK_Stream.inl.

References ACE_TRACE, and recv_i().

00216 {
00217   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00218 
00219   return this->recv_i (buf, n, 0, 0);
00220 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::recv void *  buf,
size_t  n,
int  flags
const
 

ACE_SSL supports MSG_PEEK, but no other flags at this time.

Definition at line 197 of file SSL_SOCK_Stream.inl.

References recv_i().

Referenced by recv(), recv_n(), and recvv().

00200 {
00201   return this->recv_i (buf, n, flags, 0);
00202 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::recv_i void *  buf,
size_t  n,
int  flags,
const ACE_Time_Value timeout
const [protected]
 

Underlying send() helper method common to all public send() methods.

Definition at line 96 of file SSL_SOCK_Stream.inl.

References ACE_BIT_ENABLED, ACE_NOTSUP_RETURN, ACE_TRACE, ACE::enter_recv_timedwait(), EWOULDBLOCK, ACE_SSL_SOCK::get_handle(), MSG_PEEK, ACE::record_and_set_non_blocking_mode(), ACE_SSL_Context::report_error(), ACE::restore_non_blocking_mode(), and ACE_OS::set_errno_to_last_error().

Referenced by recv().

00100 {
00101   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_i");
00102 
00103   // NOTE: Caller must provide thread-synchronization.
00104 
00105   int bytes_read = 0;
00106   const ACE_HANDLE handle = this->get_handle ();
00107 
00108   // Value for current I/O mode (blocking/non-blocking)
00109   int val = 0;
00110 
00111   if (timeout != 0)
00112     ACE::record_and_set_non_blocking_mode (handle,
00113                                            val);
00114 
00115   // Only block on select() with a timeout if no data in the
00116   // internal OpenSSL buffer is pending read completion for
00117   // the same reasons stated above, i.e. all data must be read
00118   // before blocking on select().
00119   if (timeout != 0
00120       && !::SSL_pending (this->ssl_))
00121     {
00122       if (ACE::enter_recv_timedwait (handle,
00123                                      timeout,
00124                                      val) == -1)
00125         return -1;
00126     }
00127 
00128   if (flags)
00129     {
00130       if (ACE_BIT_ENABLED (flags, MSG_PEEK))
00131         bytes_read = ::SSL_peek (this->ssl_,
00132                                  static_cast<char *> (buf),
00133                                  n);
00134       else
00135         ACE_NOTSUP_RETURN (-1);
00136     }
00137   else
00138     {
00139       bytes_read = ::SSL_read (this->ssl_,
00140                                static_cast<char *> (buf),
00141                                n);
00142     }
00143 
00144   const int status = ::SSL_get_error (this->ssl_, bytes_read);
00145   switch (status)
00146     {
00147     case SSL_ERROR_NONE:
00148       if (timeout != 0)
00149         ACE::restore_non_blocking_mode (handle, val);
00150 
00151       return bytes_read;
00152 
00153     case SSL_ERROR_WANT_READ:
00154     case SSL_ERROR_WANT_WRITE:
00155       errno = EWOULDBLOCK;
00156 
00157       return -1;
00158 
00159     case SSL_ERROR_ZERO_RETURN:
00160       if (timeout != 0)
00161         ACE::restore_non_blocking_mode (handle, val);
00162 
00163       // The peer has notified us that it is shutting down via the SSL
00164       // "close_notify" message so we need to shutdown, too.
00165       (void) ::SSL_shutdown (this->ssl_);
00166 
00167       return bytes_read;
00168 
00169     case SSL_ERROR_SYSCALL:
00170       if (bytes_read == 0)
00171         // An EOF occured but the SSL "close_notify" message was not
00172         // sent.  This is a protocol error, but we ignore it.
00173         return 0;
00174 
00175       // If not an EOF, then fall through to "default" case.
00176 
00177       // On some platforms (e.g. MS Windows) OpenSSL does not store
00178       // the last error in errno so explicitly do so.
00179       ACE_OS::set_errno_to_last_error ();
00180 
00181       break;
00182 
00183     default:
00184       // Reset errno to prevent previous values (e.g. EWOULDBLOCK)
00185       // from being associated with a fatal SSL error.
00186       errno = 0;
00187 
00188       ACE_SSL_Context::report_error ();
00189 
00190       break;
00191     }
00192 
00193   return -1;
00194 }

ssize_t ACE_SSL_SOCK_Stream::recv_n void *  buf,
size_t  len,
int  flags,
const ACE_Time_Value timeout,
size_t *  bytes_transferred = 0
const
 

Try to receive exactly len bytes into buf (uses the recv() call). The ACE_Time_Value indicates how long to blocking trying to receive. If timeout == 0, the caller will block until action is possible, else will wait until the relative time specified in timeout elapses). If recv() blocks for longer than timeout the number of bytes actually read is returned with errno == ETIME. If a timeout does not occur, recv_n return len (i.e., the number of bytes requested to be read).

Definition at line 377 of file SSL_SOCK_Stream.cpp.

References ACE_NOTSUP_RETURN, ACE_TRACE, EWOULDBLOCK, MSG_PEEK, recv(), and ssize_t.

00382 {
00383   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
00384 
00385   if (flags != 0)
00386     {
00387        if ((flags | MSG_PEEK) != MSG_PEEK)
00388         ACE_NOTSUP_RETURN (-1);
00389     }
00390 
00391   size_t temp = 0;
00392   size_t &bytes_transferred = ((bt == 0) ? temp : *bt);
00393 
00394   ssize_t n = 0;
00395 
00396   for (bytes_transferred = 0;
00397        bytes_transferred < len;
00398        bytes_transferred += n)
00399     {
00400       n = this->recv ((char*) buf + bytes_transferred,
00401                       len - bytes_transferred,
00402                       flags,
00403                       timeout);
00404 
00405       if (n < 0)
00406         {
00407           if (errno == EWOULDBLOCK)
00408             {
00409               // If blocked, try again.
00410               n = 0;
00411               continue;
00412             }
00413           else
00414             return -1;
00415         }
00416       else if (n == 0)
00417         break;
00418     }
00419 
00420   return bytes_transferred;
00421 }

ssize_t ACE_SSL_SOCK_Stream::recv_n void *  buf,
int  n,
int  flags
const
 

Recv n bytes, keep trying until n are sent.

Definition at line 424 of file SSL_SOCK_Stream.cpp.

References ACE_NOTSUP_RETURN, ACE_TRACE, EWOULDBLOCK, MSG_PEEK, recv(), and ssize_t.

00425 {
00426   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
00427 
00428   if (flags != 0)
00429     {
00430       if ((flags | MSG_PEEK) != MSG_PEEK)
00431         ACE_NOTSUP_RETURN (-1);
00432     }
00433 
00434   ssize_t bytes_transferred = 0;
00435   ssize_t n = 0;
00436 
00437   for (bytes_transferred = 0;
00438        bytes_transferred < len;
00439        bytes_transferred += n)
00440     {
00441       n = this->recv ((char*) buf + bytes_transferred,
00442                       len - bytes_transferred,
00443                       flags);
00444 
00445       if (n < 0)
00446         {
00447           if (errno == EWOULDBLOCK)
00448             {
00449               // If blocked, try again.
00450               n = 0;
00451               continue;
00452             }
00453           else
00454             return -1;
00455         }
00456       else if (n == 0)
00457         break;
00458     }
00459 
00460   return bytes_transferred;
00461 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::recv_n void *  buf,
int  n
const
 

Recv n bytes, keep trying until n are received.

Definition at line 241 of file SSL_SOCK_Stream.inl.

References ACE_TRACE.

Referenced by recvv_n().

00242 {
00243   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
00244   return this->recv_n (buf, buf_size, 0);
00245 }

ssize_t ACE_SSL_SOCK_Stream::recvv iovec *  io_vec,
const ACE_Time_Value timeout = 0
const
 

Allows a client to read from a socket without having to provide a buffer to read. This method determines how much data is in the socket, allocates a buffer of this size, reads in the data, and returns the number of bytes read. The caller is responsible for deleting the member in the iov_base field of io_vec using delete [] io_vec->iov_base.

Definition at line 124 of file SSL_SOCK_Stream.cpp.

References ACE_NEW_RETURN, ACE_NOTSUP_RETURN, ACE_TRACE, ETIME, ACE_OS::ioctl(), recv(), ACE_Handle_Set::reset(), ACE_OS::select(), and ACE_Handle_Set::set_bit().

00126 {
00127   ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv");
00128 
00129   // From ACE_SOCK_IO::recvv().
00130 #if defined (FIONREAD)
00131   ACE_Handle_Set handle_set;
00132   handle_set.reset ();
00133   handle_set.set_bit (this->get_handle ());
00134 
00135   io_vec->iov_base = 0;
00136 
00137   // Check the status of the current socket.
00138   switch (ACE_OS::select (int (this->get_handle ()) + 1,
00139                           handle_set,
00140                           0, 0,
00141                           timeout))
00142     {
00143     case -1:
00144       return -1;
00145       /* NOTREACHED */
00146     case 0:
00147       errno = ETIME;
00148       return -1;
00149       /* NOTREACHED */
00150     default:
00151       // Goes fine, fallthrough to get data
00152       break;
00153     }
00154 
00155   int inlen;
00156 
00157   if (ACE_OS::ioctl (this->get_handle (),
00158                      FIONREAD,
00159                      &inlen) == -1)
00160     return -1;
00161   else if (inlen > 0)
00162     {
00163       ACE_NEW_RETURN (io_vec->iov_base,
00164                       char[inlen],
00165                       -1);
00166       io_vec->iov_len = this->recv (io_vec->iov_base,
00167                                     inlen);
00168       return io_vec->iov_len;
00169     }
00170   else
00171     return 0;
00172 #else
00173   ACE_UNUSED_ARG (io_vec);
00174   ACE_UNUSED_ARG (timeout);
00175   ACE_NOTSUP_RETURN (-1);
00176 #endif /* FIONREAD */
00177 }

ssize_t ACE_SSL_SOCK_Stream::recvv_n iovec  iov[],
size_t  n
const
 

Receive an iovec of size n to the connected socket.

Definition at line 535 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, recv_n(), and ssize_t.

00536 {
00537   ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv_n");
00538 
00539   ssize_t bytes_read = 0;
00540 
00541   for (size_t i = 0; i < iovcnt; ++i)
00542     {
00543       ssize_t result = this->recv_n (iov[i].iov_base,
00544                                      iov[i].iov_len);
00545 
00546       if (result == -1)
00547         {
00548           // There is a subtle difference in behaviour depending on
00549           // whether or not any data was read.  If no data was read,
00550           // then always return -1.  Otherwise return bytes_read.
00551           // This gives the caller an opportunity to keep track of
00552           // which data was actually read.
00553           if (bytes_read > 0)
00554             break;
00555           else
00556             return -1;
00557         }
00558       else
00559         bytes_read += result;
00560     }
00561 
00562   return bytes_read;
00563 }

ssize_t ACE_SSL_SOCK_Stream::send size_t  n,
... 
const
 

Send n varargs messages to the connected ssl socket.

Definition at line 218 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, send(), and ssize_t.

00219 {
00220   ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
00221 
00222   const size_t total_tuples = n / 2;
00223 
00224   va_list argp;
00225   va_start (argp, n);
00226 
00227   ssize_t bytes_sent = 0;
00228 
00229   // NOTE: This method used to fill an IO vector (e.g. iovec) and then
00230   //       send it using a scatter write (sendv()).  However, it is
00231   //       not possible to emulate a non-blocking scatter write over
00232   //       SSL.  As such, there is no point in attempting to use
00233   //       scatter writes over SSL.
00234   for (size_t i = 0; i < total_tuples; ++i)
00235     {
00236       const ssize_t data_len = va_arg (argp, ssize_t);
00237       const ssize_t result = this->send (va_arg (argp, char *),
00238                                          data_len);
00239 
00240       if (result == -1)
00241         {
00242           // There is a subtle difference in behaviour depending on
00243           // whether or not any data was sent.  If no data was sent,
00244           // then always return -1.  Otherwise return bytes_sent.
00245           // This gives the caller an opportunity to keep track of
00246           // which data was actually sent.
00247           if (bytes_sent > 0)
00248             break;
00249           else
00250             {
00251               va_end (argp);
00252               return -1;
00253             }
00254         }
00255       else
00256         {
00257           bytes_sent += result;
00258 
00259           // Do not continue on to the next loop iteration if the
00260           // amount of data sent was less than the amount of data
00261           // given.  This avoids a subtle problem where "holes" in the
00262           // data stream would occur if partial sends of a given
00263           // buffer in the varargs occured.
00264           if (result < data_len)
00265             break;
00266 
00267         }
00268     }
00269 
00270   va_end (argp);
00271 
00272   return bytes_sent;
00273 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::send const void *  buf,
size_t  n,
const ACE_Time_Value timeout
const
 

Wait to to timeout amount of time to send up to n bytes into buf (uses the send() call). If send() times out a -1 is returned with errno == ETIME. If it succeeds the number of bytes sent is returned.

Definition at line 223 of file SSL_SOCK_Stream.inl.

References ACE_TRACE, and send().

00226 {
00227   ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
00228   return this->send (buf, len, 0, timeout);
00229 }

ssize_t ACE_SSL_SOCK_Stream::send const void *  buf,
size_t  n,
int  flags,
const ACE_Time_Value timeout
const
 

Wait to timeout amount of time to send up to n bytes into buf (uses the send() call). If send() times out -1 is returned with errno == ETIME. If it succeeds the number of bytes sent is returned. No flags are supported.

Definition at line 180 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, ACE::enter_send_timedwait(), ACE::restore_non_blocking_mode(), send(), and ssize_t.

00184 {
00185   ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
00186 
00187   // If SSL has data in the buffer, i.e. SSL_pending() returns a
00188   // non-zero value, then don't block on select().
00189   if (timeout == 0 || ::SSL_pending (this->ssl_))
00190     return this->send (buf, len, flags);
00191 
00192   int val = 0;
00193   if (ACE::enter_send_timedwait (this->get_handle (),
00194                                  timeout,
00195                                  val) == -1)
00196     return -1;
00197 
00198   ssize_t bytes_transferred = this->send (buf, len, flags);
00199 
00200   ACE::restore_non_blocking_mode (this->get_handle (), val);
00201 
00202   return bytes_transferred;
00203 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::send const void *  buf,
size_t  n
const
 

Send an n byte buffer to the ssl socket using the semantics of write(2).

Definition at line 205 of file SSL_SOCK_Stream.inl.

References ACE_TRACE, and send_i().

00207 {
00208   ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
00209 
00210   return this->send_i (buf, n, 0);
00211 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::send const void *  buf,
size_t  n,
int  flags
const
 

ACE_SSL supports no flags for sending at this time.

Definition at line 88 of file SSL_SOCK_Stream.inl.

References send_i().

Referenced by send(), send_n(), and sendv().

00091 {
00092   return this->send_i (buf, n, flags);
00093 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::send_i const void *  buf,
size_t  n,
int  flags
const [protected]
 

Underlying send() helper method common to all public send() methods.

Definition at line 26 of file SSL_SOCK_Stream.inl.

References ACE_NOTSUP_RETURN, ACE_TRACE, EWOULDBLOCK, ACE_SSL_Context::report_error(), and ACE_OS::set_errno_to_last_error().

Referenced by send().

00029 {
00030   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_i");
00031 
00032   // NOTE: Caller must provide thread-synchronization.
00033 
00034   // No send flags are supported in SSL.
00035   if (flags != 0)
00036     ACE_NOTSUP_RETURN (-1);
00037 
00038   const int bytes_sent = ::SSL_write (this->ssl_,
00039                                       static_cast<const char *> (buf),
00040                                       n);
00041 
00042   switch (::SSL_get_error (this->ssl_, bytes_sent))
00043     {
00044     case SSL_ERROR_NONE:
00045       return bytes_sent;
00046 
00047     case SSL_ERROR_WANT_READ:
00048     case SSL_ERROR_WANT_WRITE:
00049       errno = EWOULDBLOCK;
00050 
00051       return -1;
00052 
00053     case SSL_ERROR_ZERO_RETURN:
00054       // The peer has notified us that it is shutting down via the SSL
00055       // "close_notify" message so we need to shutdown, too.
00056       (void) ::SSL_shutdown (this->ssl_);
00057 
00058       return bytes_sent;
00059 
00060     case SSL_ERROR_SYSCALL:
00061       if (bytes_sent == 0)
00062         // An EOF occured but the SSL "close_notify" message was not
00063         // sent.  This is a protocol error, but we ignore it.
00064         return 0;
00065 
00066       // If not an EOF, then fall through to "default" case.
00067 
00068       // On some platforms (e.g. MS Windows) OpenSSL does not store
00069       // the last error in errno so explicitly do so.
00070       ACE_OS::set_errno_to_last_error ();
00071 
00072       break;
00073 
00074     default:
00075       // Reset errno to prevent previous values (e.g. EWOULDBLOCK)
00076       // from being associated with fatal SSL errors.
00077       errno = 0;
00078 
00079       ACE_SSL_Context::report_error ();
00080 
00081       break;
00082     }
00083 
00084   return -1;
00085 }

ssize_t ACE_SSL_SOCK_Stream::send_n const void *  buf,
size_t  len,
int  flags,
const ACE_Time_Value timeout,
size_t *  bytes_transferred = 0
const
 

Try to send exactly len bytes into buf (uses the send() call). If send() blocks for longer than timeout the number of bytes actually sent is returned with errno == ETIME. If a timeout does not occur, send_n() return len (i.e., the number of bytes requested to be sent).

Definition at line 329 of file SSL_SOCK_Stream.cpp.

References ACE_NOTSUP_RETURN, ACE_TRACE, EWOULDBLOCK, send(), and ssize_t.

00334 {
00335   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
00336 
00337   // No support for send flags in SSL.
00338   if (flags != 0)
00339     ACE_NOTSUP_RETURN (-1);
00340 
00341   /* This code mimics ACE::send_n */
00342   // Total number of bytes written.
00343   size_t temp = 0;
00344   size_t &bytes_transferred = ((bt == 0) ? temp : *bt);
00345 
00346   // Actual number of bytes written in each <send> attempt
00347   ssize_t n = 0;
00348 
00349   for (bytes_transferred = 0;
00350        bytes_transferred < len;
00351        bytes_transferred += n)
00352     {
00353       n = this->send ((const char*) buf + bytes_transferred,
00354                       len - bytes_transferred,
00355                       flags,
00356                       timeout);
00357 
00358       if (n < 0)
00359         {
00360           if (errno == EWOULDBLOCK)
00361             {
00362               // If blocked, try again.
00363               n = 0;
00364               continue;
00365             }
00366           else
00367             return -1;
00368         }
00369       else if (n == 0)
00370         break;
00371     }
00372 
00373   return bytes_transferred;
00374 }

ssize_t ACE_SSL_SOCK_Stream::send_n const void *  buf,
int  n,
int  flags
const
 

Send n bytes, keep trying until n are sent.

Note:
In the following four methods, only MSG_PEEK is supported for recv_n(), and no flags are supported for send_n().

Definition at line 464 of file SSL_SOCK_Stream.cpp.

References ACE_NOTSUP_RETURN, ACE_TRACE, EWOULDBLOCK, send(), and ssize_t.

00465 {
00466   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
00467 
00468   // Send flags are unsupported in SSL
00469   if (flags != 0)
00470     ACE_NOTSUP_RETURN (-1);
00471 
00472   /*  The following code mimics <ACE::send_n> */
00473   size_t bytes_transferred = 0;
00474   ssize_t n = 0;
00475 
00476   for (bytes_transferred = 0;
00477        bytes_transferred < (size_t) len;
00478        bytes_transferred += n)
00479     {
00480       n = this->send ((const char*) buf + bytes_transferred,
00481                       len - bytes_transferred,
00482                       flags);
00483 
00484       if (n < 0)
00485         {
00486           if (errno == EWOULDBLOCK)
00487             {
00488               // If blocked, try again.
00489               n = 0;
00490               continue;
00491             }
00492           else
00493             return -1;
00494         }
00495       else if (n == 0)
00496         break;
00497     }
00498 
00499   return bytes_transferred;
00500 }

ACE_INLINE ssize_t ACE_SSL_SOCK_Stream::send_n const void *  buf,
int  n
const
 

Send n bytes, keep trying until n are sent.

Definition at line 248 of file SSL_SOCK_Stream.inl.

References ACE_TRACE.

Referenced by sendv_n().

00249 {
00250   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
00251   return this->send_n (buf, len, 0);
00252 }

ssize_t ACE_SSL_SOCK_Stream::sendv const iovec  iov[],
size_t  n,
const ACE_Time_Value timeout = 0
const
 

Send an iovec of size n to the ssl socket.

Note that it is not possible to perform a "scattered" write with the underlying OpenSSL implementation. As such, the expected semantics are not fully reproduced with this implementation.

Definition at line 59 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, send(), ssize_t, and ACE_Countdown_Time::update().

00062 {
00063   ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv");
00064 
00065   // There is subtle problem in this method that occurs when using
00066   // non-blocking IO.  The semantics of a non-blocking scatter write
00067   // (sendv()) are not possible to retain with the emulation in this
00068   // method.
00069 
00070   ssize_t bytes_sent = 0;
00071 
00072   ACE_Time_Value t;
00073   ACE_Time_Value *timeout =
00074     const_cast<ACE_Time_Value *> (max_wait_time);
00075 
00076   if (max_wait_time != 0)
00077     {
00078       // Make a copy since ACE_Countdown_Time modifies the
00079       // ACE_Time_Value.
00080       t = *max_wait_time;
00081       timeout = &t;
00082     }
00083 
00084   // Take into account the time between each send.
00085   ACE_Countdown_Time countdown (timeout);
00086 
00087   for (size_t i = 0; i < n; ++i)
00088     {
00089       const ssize_t result = this->send (iov[i].iov_base,
00090                                          iov[i].iov_len,
00091                                          timeout);
00092 
00093       if (result == -1)
00094         {
00095           // There is a subtle difference in behaviour depending on
00096           // whether or not any data was sent.  If no data was sent,
00097           // then always return -1.  Otherwise return bytes_sent.
00098           // This gives the caller an opportunity to keep track of
00099           if (bytes_sent > 0)
00100             break;
00101           else
00102             return -1;
00103         }
00104       else
00105         {
00106           bytes_sent += result;
00107 
00108           // Do not continue on to the next loop iteration if the
00109           // amount of data sent was less than the amount data given.
00110           // This avoids a subtle problem where "holes" in the data
00111           // stream would occur if partial sends of a given buffer in
00112           // the iovec array occured.
00113           if (static_cast<size_t> (result) < static_cast<size_t> (iov[i].iov_len))
00114             break;
00115         }
00116 
00117       (void) countdown.update ();
00118     }
00119 
00120   return bytes_sent;
00121 }

ssize_t ACE_SSL_SOCK_Stream::sendv_n const iovec  iov[],
size_t  n
const
 

Send an iovec of size n to the connected socket. Will block until all bytes are sent or an error occurs.

Definition at line 503 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, send_n(), and ssize_t.

00504 {
00505   ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv_n");
00506 
00507   ssize_t bytes_sent = 0;
00508 
00509   for (size_t i = 0; i < iovcnt; ++i)
00510     {
00511       ssize_t result = this->send_n (iov[i].iov_base,
00512                                      iov[i].iov_len);
00513 
00514 
00515       if (result == -1)
00516         {
00517           // There is a subtle difference in behaviour depending on
00518           // whether or not any data was sent.  If no data was sent,
00519           // then always return -1.  Otherwise return bytes_sent.
00520           // This gives the caller an opportunity to keep track of
00521           // which data was actually sent.
00522           if (bytes_sent > 0)
00523             break;
00524           else
00525             return -1;
00526         }
00527       else
00528         bytes_sent += result;
00529     }
00530 
00531   return bytes_sent;
00532 }

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE void ACE_SSL_SOCK_Stream::set_handle ACE_HANDLE  fd  ) 
 

Overridden set_handle() method.

Only an ACE_SSL_SOCK_Acceptor or ACE_SSL_SOCK_Connector should access this method since some state in the underlying "ssl_" data structure is set during SSL connection establishment.

Reimplemented from ACE_SSL_SOCK.

Definition at line 10 of file SSL_SOCK_Stream.inl.

References ACE_SSL_SOCK::set_handle().

Referenced by ACE_SSL_SOCK_Acceptor::accept(), close(), and ACE_SSL_SOCK_Connector::connect().

00011 {
00012   if (this->ssl_ == 0 || fd == ACE_INVALID_HANDLE)
00013     {
00014       this->ACE_SSL_SOCK::set_handle (ACE_INVALID_HANDLE);
00015       return;
00016     }
00017   else
00018     {
00019       (void) ::SSL_set_fd (this->ssl_, (int) fd);
00020       this->ACE_SSL_SOCK::set_handle (fd);
00021       this->stream_.set_handle (fd);
00022     }
00023 }

ACE_INLINE SSL * ACE_SSL_SOCK_Stream::ssl void   )  const
 

Return a pointer to the underlying SSL structure.

Definition at line 318 of file SSL_SOCK_Stream.inl.

Referenced by ACE_SSL_SOCK_Acceptor::ssl_accept(), and ACE_SSL_SOCK_Connector::ssl_connect().

00319 {
00320   return this->ssl_;
00321 }


Member Data Documentation

ACE_SSL_SOCK_Stream::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Reimplemented from ACE_SOCK.

Definition at line 256 of file SSL_SOCK_Stream.h.

ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_SSL_SOCK_Stream &)) ACE_UNIMPLEMENTED_FUNC (ACE_SSL_SOCK_Stream ( const ACE_SSL_SOCK_Stream &)) protected ACE_SOCK_Stream ACE_SSL_SOCK_Stream::stream_ [private]
 

The stream which works under the ssl connection.

Definition at line 300 of file SSL_SOCK_Stream.h.


The documentation for this class was generated from the following files:
Generated on Sun Jan 27 13:03:29 2008 for ACE_SSL by doxygen 1.3.6