Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

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. More...


Public Methods

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

 ~ACE_SSL_SOCK_Stream (void)
 Destructor. More...

ssize_t send (const void *buf, size_t n, int flags) const
 Send an n byte buffer to the ssl socket using the semantics of send(3n). More...

ssize_t recv (void *buf, size_t n, int flags) const
 Recv an n byte buffer from the ssl socket using the semantics of recv(3n). More...

ssize_t send (const void *buf, size_t n) const
 Send an n byte buffer to the ssl socket using the semantics of write(2). More...

ssize_t recv (void *buf, size_t n) const
 Recv an n byte buffer from the ssl socket using the semantics of read(2). More...

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. More...

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. More...

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

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

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

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. More...

int close (void)
 Close down the socket. More...

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

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

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

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

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

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. More...

int close_writer (void)
 Close down the writer. More...


Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks. More...


Protected Methods

ssize_t send_i (const void *buf, size_t n, int flags) const
 Underlying send() helper method common to all public send() methods. More...

ssize_t recv_i (void *buf, size_t n, int flags, const ACE_Time_Value *timeout) const
 Underlying send() helper method common to all public send() methods. More...


Friends

class ACE_SSL_SOCK_Connector
class ACE_SSL_SOCK_Acceptor

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 58 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 245 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.

ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream void   
 

Destructor.

Definition at line 48 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE.

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


Member Function Documentation

ASYS_INLINE int ACE_SSL_SOCK_Stream::close void   
 

Close down the socket.

Reimplemented from ACE_SOCK.

Definition at line 265 of file SSL_SOCK_Stream.i.

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.

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

ASYS_INLINE int ACE_SSL_SOCK_Stream::close_reader void   
 

Close down the reader.

Selectively close endpoints.

Definition at line 251 of file SSL_SOCK_Stream.i.

References ACE_TRACE.

00252 {
00253   ACE_TRACE ("ACE_SSL_SOCK_Stream::close_reader");
00254   return this->stream_.close_reader ();
00255 }

ASYS_INLINE int ACE_SSL_SOCK_Stream::close_writer void   
 

Close down the writer.

Definition at line 258 of file SSL_SOCK_Stream.i.

References ACE_TRACE.

00259 {
00260   ACE_TRACE ("ACE_SSL_SOCK_Stream::close_writer");
00261   return this->stream_.close_writer ();
00262 }

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 <ACE_Addr>. 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 547 of file SSL_SOCK_Stream.cpp.

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

00548 {
00549   // Some applications use get_remote_addr() as a way of determining
00550   // whether or not a connection has been established.  In SSL's case,
00551   // the remote addr will be available once the TCP handshake has been
00552   // complete.  Despite that fact, the SSL connection may not have
00553   // been completed.  In such a case, a successful return from
00554   // get_remote_addr() would be misleading.
00555 
00556   if (SSL_is_init_finished (this->ssl_))
00557     return this->ACE_SOCK::get_remote_addr (addr);
00558 
00559   if (this->get_handle () == ACE_INVALID_HANDLE)
00560     errno = EBADF;
00561   else
00562     errno = ENOTCONN;
00563 
00564   return -1;
00565 }

ASYS_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 307 of file SSL_SOCK_Stream.i.

References ACE_TRACE.

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

00308 {
00309   ACE_TRACE ("ACE_SSL_SOCK_Stream::peer");
00310   return this->stream_;
00311 }

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

Recv n varargs messages to the connected ssl socket.

Definition at line 269 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, recv, and ssize_t.

00270 {
00271   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00272 
00273   size_t total_tuples = n / 2;
00274 
00275   va_list argp;
00276   va_start (argp, n);
00277 
00278   ssize_t bytes_recv = 0;
00279 
00280   for (size_t i = 0; i < total_tuples; ++i)
00281     {
00282       ssize_t result = this->recv (va_arg (argp, char *),
00283                                    va_arg (argp, ssize_t));
00284 
00285       if (result == -1)
00286         {
00287           // There is a subtle difference in behaviour depending on
00288           // whether or not any data was received.  If no data was
00289           // received, then always return -1.  Otherwise return
00290           // bytes_received.  This gives the caller an opportunity to
00291           // keep track of which data was actually received.
00292           if (bytes_recv > 0)
00293             break;
00294           else
00295             {
00296               va_end (argp);
00297               return -1;
00298             }
00299         }
00300       else
00301         bytes_recv += result;
00302     }
00303 
00304   va_end (argp);
00305 
00306   return bytes_recv;
00307 }

ASYS_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 228 of file SSL_SOCK_Stream.i.

References ACE_TRACE, and recv.

00231 {
00232   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00233   return this->recv (buf, n, 0, timeout);
00234 }

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 211 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, and recv_i.

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

ASYS_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 210 of file SSL_SOCK_Stream.i.

References ACE_TRACE, and recv_i.

00212 {
00213   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00214 
00215   return this->recv_i (buf, n, 0, 0);
00216 }

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

Recv an n byte buffer from the ssl socket using the semantics of recv(3n).

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

Definition at line 193 of file SSL_SOCK_Stream.i.

References recv_i.

Referenced by recv, recv_n, and recvv.

00196 {
00197   return this->recv_i (buf, n, flags, 0);
00198 }

ASYS_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 92 of file SSL_SOCK_Stream.i.

References ACE_BIT_ENABLED, ACE_TRACE, ACE::enter_recv_timedwait, EWOULDBLOCK, ACE_SSL_SOCK::get_handle, 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.

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

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 358 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, EWOULDBLOCK, recv, and ssize_t.

00363 {
00364   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
00365 
00366   if (flags != 0)
00367     {
00368        if ((flags | MSG_PEEK) != MSG_PEEK)
00369         ACE_NOTSUP_RETURN (-1);
00370     }
00371 
00372   size_t temp = 0;
00373   size_t &bytes_transferred = ((bt == 0) ? temp : *bt);
00374 
00375   ssize_t n = 0;
00376 
00377   for (bytes_transferred = 0;
00378        bytes_transferred < len;
00379        bytes_transferred += n)
00380     {
00381       n = this->recv ((char*) buf + bytes_transferred,
00382                       len - bytes_transferred,
00383                       flags,
00384                       timeout);
00385 
00386       if (n < 0)
00387         {
00388           if (errno == EWOULDBLOCK)
00389             {
00390               // If blocked, try again.
00391               n = 0;
00392               continue;
00393             }
00394           else
00395             return -1;
00396         }
00397       else if (n == 0)
00398         break;
00399     }
00400 
00401   return bytes_transferred;
00402 }

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 405 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, EWOULDBLOCK, recv, and ssize_t.

00406 {
00407   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
00408 
00409   if (flags != 0)
00410     {
00411       if ((flags | MSG_PEEK) != MSG_PEEK)
00412         ACE_NOTSUP_RETURN (-1);
00413     }
00414 
00415   ssize_t bytes_transferred = 0;
00416   ssize_t n = 0;
00417 
00418   for (bytes_transferred = 0;
00419        bytes_transferred < len;
00420        bytes_transferred += n)
00421     {
00422       n = this->recv ((char*) buf + bytes_transferred,
00423                       len - bytes_transferred,
00424                       flags);
00425 
00426       if (n < 0)
00427         {
00428           if (errno == EWOULDBLOCK)
00429             {
00430               // If blocked, try again.
00431               n = 0;
00432               continue;
00433             }
00434           else
00435             return -1;
00436         }
00437       else if (n == 0)
00438         break;
00439     }
00440 
00441   return bytes_transferred;
00442 }

ASYS_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 237 of file SSL_SOCK_Stream.i.

References ACE_TRACE.

Referenced by recvv_n.

00238 {
00239   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
00240   return this->recv_n (buf, buf_size, 0);
00241 }

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 128 of file SSL_SOCK_Stream.cpp.

References ACE_NEW_RETURN, ACE_TRACE, ETIME, ACE_OS::ioctl, iovec::iov_base, iovec::iov_len, recv, ACE_Handle_Set::reset, ACE_OS::select, and ACE_Handle_Set::set_bit.

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

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 516 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, recv_n, and ssize_t.

00517 {
00518   ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv_n");
00519 
00520   ssize_t bytes_read = 0;
00521 
00522   for (size_t i = 0; i < iovcnt; ++i)
00523     {
00524       ssize_t result = this->recv_n (iov[i].iov_base,
00525                                      iov[i].iov_len);
00526 
00527       if (result == -1)
00528         {
00529           // There is a subtle difference in behaviour depending on
00530           // whether or not any data was read.  If no data was read,
00531           // then always return -1.  Otherwise return bytes_read.
00532           // This gives the caller an opportunity to keep track of
00533           // which data was actually read.
00534           if (bytes_read > 0)
00535             break;
00536           else
00537             return -1;
00538         }
00539       else
00540         bytes_read += result;
00541     }
00542 
00543   return bytes_read;
00544 }

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

Send n varargs messages to the connected ssl socket.

Definition at line 223 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, send, and ssize_t.

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

ASYS_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 219 of file SSL_SOCK_Stream.i.

References ACE_TRACE, and send.

00222 {
00223   ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
00224   return this->send (buf, len, 0, timeout);
00225 }

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 185 of file SSL_SOCK_Stream.cpp.

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

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

ASYS_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 201 of file SSL_SOCK_Stream.i.

References ACE_TRACE, and send_i.

00203 {
00204   ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
00205 
00206   return this->send_i (buf, n, 0);
00207 }

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

Send an n byte buffer to the ssl socket using the semantics of send(3n).

ACE_SSL supports no flags for sending at this time.

Definition at line 84 of file SSL_SOCK_Stream.i.

References send_i.

Referenced by send, send_n, and sendv.

00087 {
00088   return this->send_i (buf, n, flags);
00089 }

ASYS_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 22 of file SSL_SOCK_Stream.i.

References ACE_TRACE, EWOULDBLOCK, ACE_SSL_Context::report_error, and ACE_OS::set_errno_to_last_error.

Referenced by send.

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

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 310 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, EWOULDBLOCK, send, and ssize_t.

00315 {
00316   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
00317 
00318   // No support for send flags in SSL.
00319   if (flags != 0)
00320     ACE_NOTSUP_RETURN (-1);
00321 
00322   /* This code mimics ACE::send_n */
00323   // Total number of bytes written.
00324   size_t temp = 0;
00325   size_t &bytes_transferred = ((bt == 0) ? temp : *bt);
00326 
00327   // Actual number of bytes written in each <send> attempt
00328   ssize_t n = 0;
00329 
00330   for (bytes_transferred = 0;
00331        bytes_transferred < len;
00332        bytes_transferred += n)
00333     {
00334       n = this->send ((const char*) buf + bytes_transferred,
00335                       len - bytes_transferred,
00336                       flags,
00337                       timeout);
00338 
00339       if (n < 0)
00340         {
00341           if (errno == EWOULDBLOCK)
00342             {
00343               // If blocked, try again.
00344               n = 0;
00345               continue;
00346             }
00347           else
00348             return -1;
00349         }
00350       else if (n == 0)
00351         break;
00352     }
00353 
00354   return bytes_transferred;
00355 }

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 445 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, EWOULDBLOCK, send, and ssize_t.

00446 {
00447   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
00448 
00449   // Send flags are unsupported in SSL
00450   if (flags != 0)
00451     ACE_NOTSUP_RETURN (-1);
00452 
00453   /*  The following code mimics <ACE::send_n> */
00454   size_t bytes_transferred = 0;
00455   ssize_t n = 0;
00456 
00457   for (bytes_transferred = 0;
00458        bytes_transferred < (size_t) len;
00459        bytes_transferred += n)
00460     {
00461       n = this->send ((const char*) buf + bytes_transferred,
00462                       len - bytes_transferred,
00463                       flags);
00464 
00465       if (n < 0)
00466         {
00467           if (errno == EWOULDBLOCK)
00468             {
00469               // If blocked, try again.
00470               n = 0;
00471               continue;
00472             }
00473           else
00474             return -1;
00475         }
00476       else if (n == 0)
00477         break;
00478     }
00479 
00480   return bytes_transferred;
00481 }

ASYS_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 244 of file SSL_SOCK_Stream.i.

References ACE_TRACE.

Referenced by sendv_n.

00245 {
00246   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
00247   return this->send_n (buf, len, 0);
00248 }

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 62 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, iovec::iov_len, send, ssize_t, and ACE_Countdown_Time::update.

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

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 484 of file SSL_SOCK_Stream.cpp.

References ACE_TRACE, send_n, and ssize_t.

00485 {
00486   ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv_n");
00487 
00488   ssize_t bytes_sent = 0;
00489 
00490   for (size_t i = 0; i < iovcnt; ++i)
00491     {
00492       ssize_t result = this->send_n (iov[i].iov_base,
00493                                      iov[i].iov_len);
00494 
00495 
00496       if (result == -1)
00497         {
00498           // There is a subtle difference in behaviour depending on
00499           // whether or not any data was sent.  If no data was sent,
00500           // then always return -1.  Otherwise return bytes_sent.
00501           // This gives the caller an opportunity to keep track of
00502           // which data was actually sent.
00503           if (bytes_sent > 0)
00504             break;
00505           else
00506             return -1;
00507         }
00508       else
00509         bytes_sent += result;
00510     }
00511 
00512   return bytes_sent;
00513 }

ASYS_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 6 of file SSL_SOCK_Stream.i.

References ACE_SSL_SOCK::set_handle.

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

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

ASYS_INLINE SSL * ACE_SSL_SOCK_Stream::ssl void    const
 

Return a pointer to the underlying SSL structure.

Definition at line 314 of file SSL_SOCK_Stream.i.

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

00315 {
00316   return this->ssl_;
00317 }


Friends And Related Function Documentation

friend class ACE_SSL_SOCK_Acceptor [friend]
 

Definition at line 61 of file SSL_SOCK_Stream.h.

friend class ACE_SSL_SOCK_Connector [friend]
 

Definition at line 60 of file SSL_SOCK_Stream.h.


Member Data Documentation

ACE_SSL_SOCK_Stream::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Reimplemented from ACE_SOCK.

Definition at line 248 of file SSL_SOCK_Stream.h.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 13:16:21 2003 for ACE_SSL by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002