ACE_SSL_SOCK_Acceptor Class Reference

Defines a factory that creates new ACE_SSL_SOCK_Stream objects passively. More...

#include <SSL_SOCK_Acceptor.h>

Inheritance diagram for ACE_SSL_SOCK_Acceptor:

Inheritance graph
[legend]
Collaboration diagram for ACE_SSL_SOCK_Acceptor:

Collaboration graph
[legend]
List of all members.

Public Types

typedef ACE_INET_Addr PEER_ADDR
typedef ACE_SSL_SOCK_Stream PEER_STREAM

Public Member Functions

 ACE_SSL_SOCK_Acceptor (void)
 Default constructor.

 ~ACE_SSL_SOCK_Acceptor (void)
 Default destructor.

 ACE_SSL_SOCK_Acceptor (const ACE_Addr &local_sap, int reuse_addr=0, int protocol_family=PF_UNSPEC, int backlog=ACE_DEFAULT_BACKLOG, int protocol=0)
 ACE_SSL_SOCK_Acceptor (const ACE_Addr &local_sap, ACE_Protocol_Info *protocolinfo, ACE_SOCK_GROUP g, u_long flags, int reuse_addr, int protocol_family=PF_UNSPEC, int backlog=ACE_DEFAULT_BACKLOG, int protocol=0)
int open (const ACE_Addr &local_sap, int reuse_addr=0, int protocol_family=PF_UNSPEC, int backlog=ACE_DEFAULT_BACKLOG, int protocol=0)
int close (void)
 Close the listening socket.

Passive Connection "accept" Methods
These are the canonical methods exposed by the Acceptor pattern.

int accept (ACE_SSL_SOCK_Stream &new_stream, ACE_Addr *remote_addr=0, ACE_Time_Value *timeout=0, int restart=1, int reset_new_handle=0) const
int accept (ACE_SSL_SOCK_Stream &new_stream, ACE_Accept_QoS_Params qos_params, ACE_Addr *remote_addr=0, ACE_Time_Value *timeout=0, int restart=1, int reset_new_handle=0) const

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.


Protected Member Functions

int ssl_accept (ACE_SSL_SOCK_Stream &new_stream, ACE_Time_Value *timeout) const
 Complete SSL passive connection establishment.


Private Attributes

ACE_SOCK_Acceptor acceptor_
 The BSD-socket workhorse.


Detailed Description

Defines a factory that creates new ACE_SSL_SOCK_Stream objects passively.

The ACE_SSL_SOCK_Acceptor has its own ACE_SOCK_Acceptor which handles the basic socket acceptance. This class is a wrapper which adds the SSL acceptance handshake handling. Since SSL is record oriented, some additional steps must be taken after the basic socket acceptance to complete the SSL handshake that takes place at session establishment.

Note:
The user must currently ensure that only one thread services a given SSL session at any given time since some underlying SSL implementations, such as OpenSSL, are not entirely thread-safe or reentrant.

Definition at line 52 of file SSL_SOCK_Acceptor.h.


Member Typedef Documentation

typedef ACE_INET_Addr ACE_SSL_SOCK_Acceptor::PEER_ADDR
 

Definition at line 170 of file SSL_SOCK_Acceptor.h.

typedef ACE_SSL_SOCK_Stream ACE_SSL_SOCK_Acceptor::PEER_STREAM
 

Definition at line 171 of file SSL_SOCK_Acceptor.h.


Constructor & Destructor Documentation

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor void   ) 
 

Default constructor.

Definition at line 8 of file SSL_SOCK_Acceptor.inl.

References ACE_TRACE.

00009   : acceptor_ ()
00010 {
00011   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor");
00012 }

ACE_SSL_SOCK_Acceptor::~ACE_SSL_SOCK_Acceptor void   ) 
 

Default destructor.

ACE_INLINE ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor const ACE_Addr local_sap,
int  reuse_addr = 0,
int  protocol_family = PF_UNSPEC,
int  backlog = ACE_DEFAULT_BACKLOG,
int  protocol = 0
 

Initiate a passive mode SSL/BSD-style acceptor socket.

Parameters:
local_sap The address that we're going to listen for connections on. If this is ACE_Addr::sap_any, this socket listens on an the "any" IP address and selects an unused port. To find out what port was selected, call this object's ACE_SOCK::get_local_addr(ACE_Addr&) method upon return.

Definition at line 15 of file SSL_SOCK_Acceptor.inl.

References ACE_TRACE, and ACE_SSL_SOCK::set_handle().

00020   : acceptor_ (local_sap,
00021                reuse_addr,
00022                protocol_family,
00023                backlog,
00024                protocol)
00025 {
00026   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor");
00027 
00028   this->set_handle (this->acceptor_.get_handle ());
00029 }

ACE_INLINE ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor const ACE_Addr local_sap,
ACE_Protocol_Info protocolinfo,
ACE_SOCK_GROUP  g,
u_long  flags,
int  reuse_addr,
int  protocol_family = PF_UNSPEC,
int  backlog = ACE_DEFAULT_BACKLOG,
int  protocol = 0
 

Initiate a passive-mode QoS-enabled acceptor socket.

Parameters:
local_sap The address that we're going to listen for connections on. If this is ACE_Addr::sap_any, this socket listens on an the "any" IP address and selects an unused port. To find out what port was selected, call this object's ACE_SOCK::get_local_addr(ACE_Addr&) method upon return.

Definition at line 32 of file SSL_SOCK_Acceptor.inl.

References ACE_TRACE, and ACE_SSL_SOCK::set_handle().

00040   : acceptor_ (local_sap,
00041                protocolinfo,
00042                g,
00043                flags,
00044                reuse_addr,
00045                protocol_family,
00046                backlog,
00047                protocol)
00048 {
00049   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor");
00050 
00051   this->set_handle (this->acceptor_.get_handle ());
00052 }


Member Function Documentation

int ACE_SSL_SOCK_Acceptor::accept ACE_SSL_SOCK_Stream new_stream,
ACE_Accept_QoS_Params  qos_params,
ACE_Addr remote_addr = 0,
ACE_Time_Value timeout = 0,
int  restart = 1,
int  reset_new_handle = 0
const
 

Accept a new ACE_SSL_SOCK_Stream connection using the RVSP QoS information in qos_params.

Parameters:
new_stream The ACE_SSL_SOCK_Stream object that will receive the new SSL socket.
remote_addr Pointer to an ACE_INET_Addr object that will receive the address of the peer that connected.
timeout The maximum time to wait for the combined socket acceptance and handshake completion. 0 means block forever, a timeout of {0, 0} means poll.
restart 1 means "restart if interrupted," that is, if errno == EINTR.
Returns:
0 if success; -1 for failure (errno contains error code).

Definition at line 212 of file SSL_SOCK_Acceptor.cpp.

References ACE_SOCK_Acceptor::accept(), ACE_TRACE, ACE_SSL_SOCK_Stream::close(), ACE_IPC_SAP::get_handle(), ACE_IPC_SAP::set_handle(), ACE_SSL_SOCK_Stream::set_handle(), ssl_accept(), and ACE_Countdown_Time::update().

00218 {
00219   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::accept");
00220 
00221   // Take into account the time to complete the basic TCP handshake
00222   // and the SSL handshake.
00223   ACE_Countdown_Time countdown (timeout);
00224 
00225   ACE_SOCK_Stream temp_stream;
00226   if (-1 == this->acceptor_.accept (temp_stream,
00227                                     qos_params,
00228                                     remote_addr,
00229                                     timeout,
00230                                     restart,
00231                                     reset_new_handle))
00232     return -1;
00233 
00234   (void) countdown.update ();
00235 
00236   new_stream.set_handle (temp_stream.get_handle ());
00237   temp_stream.set_handle (ACE_INVALID_HANDLE);
00238 
00239   if (this->ssl_accept (new_stream, timeout) == -1)
00240     {
00241       new_stream.close ();
00242       new_stream.set_handle (ACE_INVALID_HANDLE);
00243       return -1;
00244     }
00245 
00246   return 0;
00247 }

int ACE_SSL_SOCK_Acceptor::accept ACE_SSL_SOCK_Stream new_stream,
ACE_Addr remote_addr = 0,
ACE_Time_Value timeout = 0,
int  restart = 1,
int  reset_new_handle = 0
const
 

Accept a new ACE_SSL_SOCK_Stream connection. On successful return, the socket has been accepted and the SSL handshake has been completed.

Parameters:
new_stream The ACE_SSL_SOCK_Stream object that will receive the new SSL socket.
remote_addr Pointer to an ACE_INET_Addr object that will receive the address of the peer that connected.
timeout The maximum time to wait for the combined socket acceptance and handshake completion. 0 means block forever, a timeout of {0, 0} means poll.
restart 1 means "restart if interrupted," that is, if errno == EINTR.
Returns:
0 if success; -1 for failure (errno contains error code).

Definition at line 175 of file SSL_SOCK_Acceptor.cpp.

References ACE_SOCK_Acceptor::accept(), ACE_TRACE, ACE_SSL_SOCK_Stream::close(), ACE_IPC_SAP::get_handle(), ACE_IPC_SAP::set_handle(), ACE_SSL_SOCK_Stream::set_handle(), ssl_accept(), and ACE_Countdown_Time::update().

00180 {
00181   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::accept");
00182 
00183   // Take into account the time to complete the basic TCP handshake
00184   // and the SSL handshake.
00185   ACE_Countdown_Time countdown (timeout);
00186 
00187   ACE_SOCK_Stream temp_stream;
00188   if (-1 == this->acceptor_.accept (temp_stream,
00189                                     remote_addr,
00190                                     timeout,
00191                                     restart,
00192                                     reset_new_handle))
00193     return -1;
00194 
00195   (void) countdown.update ();
00196 
00197   new_stream.set_handle (temp_stream.get_handle ());
00198   temp_stream.set_handle (ACE_INVALID_HANDLE);
00199 
00200   if (this->ssl_accept (new_stream, timeout) == -1)
00201     {
00202       new_stream.close ();
00203       new_stream.set_handle (ACE_INVALID_HANDLE);
00204       return -1;
00205     }
00206 
00207   return 0;
00208 
00209 }

ACE_INLINE int ACE_SSL_SOCK_Acceptor::close void   ) 
 

Close the listening socket.

Reimplemented from ACE_SOCK.

Definition at line 75 of file SSL_SOCK_Acceptor.inl.

References ACE_TRACE, ACE_SOCK_Acceptor::close(), and ACE_SSL_SOCK::set_handle().

00076 {
00077   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::close ()");
00078 
00079   int result = this->acceptor_.close ();
00080   this->set_handle (ACE_INVALID_HANDLE);
00081 
00082   return result;
00083 }

ACE_INLINE int ACE_SSL_SOCK_Acceptor::open const ACE_Addr local_sap,
int  reuse_addr = 0,
int  protocol_family = PF_UNSPEC,
int  backlog = ACE_DEFAULT_BACKLOG,
int  protocol = 0
 

Initiate a passive mode SSL/BSD-style acceptor socket.

Parameters:
local_sap The address that we're going to listen for connections on. If this is ACE_Addr::sap_any, this socket listens on an the "any" IP address and selects an unused port. To find out what port was selected, call this object's ACE_SOCK::get_local_addr(ACE_Addr&) method upon return.
Returns:
0 if success; -1 for failure (errno contains error code).

Definition at line 55 of file SSL_SOCK_Acceptor.inl.

References ACE_TRACE, ACE_SOCK_Acceptor::open(), and ACE_SSL_SOCK::set_handle().

00060 {
00061   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::open");
00062   if (this->acceptor_.open (local_sap,
00063                             reuse_addr,
00064                             protocol_family,
00065                             backlog,
00066                             protocol) != 0)
00067     return -1;
00068   else
00069     this->set_handle (this->acceptor_.get_handle ());
00070 
00071   return 0;
00072 }

int ACE_SSL_SOCK_Acceptor::ssl_accept ACE_SSL_SOCK_Stream new_stream,
ACE_Time_Value timeout
const [protected]
 

Complete SSL passive connection establishment.

Definition at line 34 of file SSL_SOCK_Acceptor.cpp.

References ACE_ASSERT, ACE_BIT_DISABLED, ACE_NONBLOCK, ACE::clr_flags(), EWOULDBLOCK, ACE_SSL_SOCK::get_handle(), ACE_Handle_Set::num_set(), ACE_SSL_Context::report_error(), ACE::select(), ACE_Handle_Set::set_bit(), ACE_OS::set_errno_to_last_error(), ACE::set_flags(), ACE_SSL_SOCK_Stream::ssl(), and ACE_Countdown_Time::update().

Referenced by accept().

00036 {
00037   SSL *ssl = new_stream.ssl ();
00038 
00039   if (SSL_is_init_finished (ssl))
00040     return 0;
00041 
00042   if (!SSL_in_accept_init (ssl))
00043     ::SSL_set_accept_state (ssl);
00044 
00045   ACE_HANDLE handle = new_stream.get_handle ();
00046 
00047   // We're going to call SSL_accept, optionally doing ACE::select and
00048   // retrying the SSL_accept, until the SSL handshake is done or
00049   // it fails.
00050   // To get the timeout affect, set the socket to nonblocking mode
00051   // before beginning if there is a timeout specified. If the timeout
00052   // is 0 (wait as long as it takes) then don't worry about the blocking
00053   // status; we'll block in SSL_accept if the socket is blocking, and
00054   // block in ACE::select if not.
00055   int reset_blocking_mode = 0;
00056   if (timeout != 0)
00057     {
00058       reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
00059                                               ACE_NONBLOCK);
00060           // Set the handle into non-blocking mode if it's not already
00061           // in it.
00062           if (reset_blocking_mode
00063               && ACE::set_flags (handle,
00064                                  ACE_NONBLOCK) == -1)
00065             return -1;
00066     }
00067 
00068   // Take into account the time between each select() call below.
00069   ACE_Countdown_Time countdown (timeout);
00070 
00071   int status;
00072   do
00073     {
00074       // These handle sets are used to set up for whatever SSL_accept
00075       // says it wants next. They're reset on each pass around the loop.
00076       ACE_Handle_Set rd_handle;
00077       ACE_Handle_Set wr_handle;
00078 
00079       status = ::SSL_accept (ssl);
00080       switch (::SSL_get_error (ssl, status))
00081         {
00082         case SSL_ERROR_NONE:
00083           status = 0;               // To tell caller about success
00084           break;                    // Done
00085 
00086         case SSL_ERROR_WANT_WRITE:
00087           wr_handle.set_bit (handle);
00088           status = 1;               // Wait for more activity
00089           break;
00090 
00091         case SSL_ERROR_WANT_READ:
00092           rd_handle.set_bit (handle);
00093           status = 1;               // Wait for more activity
00094           break;
00095 
00096         case SSL_ERROR_ZERO_RETURN:
00097           // The peer has notified us that it is shutting down via
00098           // the SSL "close_notify" message so we need to
00099           // shutdown, too.
00100           status = -1;
00101           break;
00102 
00103         case SSL_ERROR_SYSCALL:
00104           // On some platforms (e.g. MS Windows) OpenSSL does not
00105           // store the last error in errno so explicitly do so.
00106           //
00107           // Explicitly check for EWOULDBLOCK since it doesn't get
00108           // converted to an SSL_ERROR_WANT_{READ,WRITE} on some
00109           // platforms. If SSL_accept failed outright, though, don't
00110           // bother checking more. This can happen if the socket gets
00111           // closed during the handshake.
00112           if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK &&
00113               status == -1)
00114             {
00115               // Although the SSL_ERROR_WANT_READ/WRITE isn't getting
00116               // set correctly, the read/write state should be valid.
00117               // Use that to decide what to do.
00118               status = 1;               // Wait for more activity
00119               if (SSL_want_write (ssl))
00120                 wr_handle.set_bit (handle);
00121               else if (SSL_want_read (ssl))
00122                 rd_handle.set_bit (handle);
00123               else
00124                 status = -1;            // Doesn't want anything - bail out
00125             }
00126           else
00127             status = -1;
00128           break;
00129 
00130         default:
00131           ACE_SSL_Context::report_error ();
00132           status = -1;
00133           break;
00134         }
00135 
00136       if (status == 1)
00137         {
00138           // Must have at least one handle to wait for at this point.
00139           ACE_ASSERT (rd_handle.num_set() == 1 || wr_handle.num_set () == 1);
00140           status = ACE::select (int (handle) + 1,
00141                                 &rd_handle,
00142                                 &wr_handle,
00143                                 0,
00144                                 timeout);
00145 
00146           (void) countdown.update ();
00147 
00148           // 0 is timeout, so we're done.
00149           // -1 is error, so we're done.
00150           // Could be both handles set (same handle in both masks) so
00151           // set to 1.
00152           if (status >= 1)
00153             status = 1;
00154           else                   // Timeout or failure
00155             status = -1;
00156         }
00157 
00158     } while (status == 1 && !SSL_is_init_finished (ssl));
00159 
00160   if (reset_blocking_mode)
00161     {
00162       ACE_Errno_Guard eguard (errno);
00163       ACE::clr_flags (handle, ACE_NONBLOCK);
00164     }
00165 
00166   return (status == -1 ? -1 : 0);
00167 
00168 }


Member Data Documentation

ACE_SOCK_Acceptor ACE_SSL_SOCK_Acceptor::acceptor_ [private]
 

The BSD-socket workhorse.

Definition at line 186 of file SSL_SOCK_Acceptor.h.

ACE_SSL_SOCK_Acceptor::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Reimplemented from ACE_SOCK.

Definition at line 175 of file SSL_SOCK_Acceptor.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