Defines a factory that creates new <ACE_SSL_SOCK_Stream>s actively. More...
#include <SSL_SOCK_Connector.h>
Public Types | |
typedef ACE_INET_Addr | PEER_ADDR |
Meta-type info. | |
typedef ACE_SSL_SOCK_Stream | PEER_STREAM |
Meta-type info. | |
Public Member Functions | |
ACE_SSL_SOCK_Connector (void) | |
Default constructor. | |
ACE_SSL_SOCK_Connector (ACE_SSL_SOCK_Stream &new_stream, const ACE_Addr &remote_sap, const ACE_Time_Value *timeout=0, const ACE_Addr &local_sap=ACE_Addr::sap_any, int reuse_addr=0, int flags=0, int perms=0) | |
ACE_SSL_SOCK_Connector (ACE_SSL_SOCK_Stream &new_stream, const ACE_Addr &remote_sap, ACE_QoS_Params qos_params, const ACE_Time_Value *timeout=0, const ACE_Addr &local_sap=ACE_Addr::sap_any, ACE_Protocol_Info *protocolinfo=0, ACE_SOCK_GROUP g=0, u_long flags=0, int reuse_addr=0, int perms=0) | |
~ACE_SSL_SOCK_Connector (void) | |
Default dtor. | |
int | connect (ACE_SSL_SOCK_Stream &new_stream, const ACE_Addr &remote_sap, const ACE_Time_Value *timeout=0, const ACE_Addr &local_sap=ACE_Addr::sap_any, int reuse_addr=0, int flags=0, int perms=0) |
int | connect (ACE_SSL_SOCK_Stream &new_stream, const ACE_Addr &remote_sap, ACE_QoS_Params qos_params, const ACE_Time_Value *timeout=0, const ACE_Addr &local_sap=ACE_Addr::sap_any, ACE_Protocol_Info *protocolinfo=0, ACE_SOCK_GROUP g=0, u_long flags=0, int reuse_addr=0, int perms=0) |
int | complete (ACE_SSL_SOCK_Stream &new_stream, ACE_Addr *remote_sap=0, const ACE_Time_Value *timeout=0) |
bool | reset_new_handle (ACE_HANDLE handle) |
Resets any event associations on this handle. | |
void | dump (void) const |
Dump the state of an object. | |
Public Attributes | |
ACE_ALLOC_HOOK_DECLARE | |
Declare the dynamic allocation hooks. | |
Protected Member Functions | |
int | ssl_connect (ACE_SSL_SOCK_Stream &new_stream, const ACE_Time_Value *timeout) |
Complete non-blocking SSL active connection. | |
Private Attributes | |
ACE_SOCK_Connector | connector_ |
Defines a factory that creates new <ACE_SSL_SOCK_Stream>s actively.
The ACE_SSL_SOCK_Connector doesn't have a socket of its own, i.e., it simply "borrows" the one from the ACE_SSL_SOCK_Stream that's being connected. The reason for this is that the underlying socket API doesn't use a "factory" socket to connect "data-mode" sockets. Therefore, there's no need to inherit ACE_SSL_SOCK_Connector from ACE_SSL_SOCK.
Since SSL is record-oriented, some additional work is done after the plain socket is connected.
Definition at line 56 of file SSL_SOCK_Connector.h.
Meta-type info.
Definition at line 286 of file SSL_SOCK_Connector.h.
Meta-type info.
Definition at line 287 of file SSL_SOCK_Connector.h.
ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector | ( | void | ) |
Default constructor.
Definition at line 8 of file SSL_SOCK_Connector.inl.
: connector_ () { ACE_TRACE ("ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector"); }
ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector | ( | ACE_SSL_SOCK_Stream & | new_stream, | |
const ACE_Addr & | remote_sap, | |||
const ACE_Time_Value * | timeout = 0 , |
|||
const ACE_Addr & | local_sap = ACE_Addr::sap_any , |
|||
int | reuse_addr = 0 , |
|||
int | flags = 0 , |
|||
int | perms = 0 | |||
) |
Actively connect to a peer, producing a connected ACE_SSL_SOCK_Stream
object if the connection succeeds. This method performs both the initial socket connect and the SSL handshake.
new_stream | The ACE_SSL_SOCK_Stream object that will be connected to the peer. | |
remote_sap | The address that we are trying to connect to. The protocol family of remote_sap is used for the connected socket. That is, if remote_sap contains an IPv6 address, a socket with family PF_INET6 will be used, else it will be PF_INET. | |
timeout | Pointer to an ACE_Time_Value object with amount of time to wait to connect. If the pointer is 0 then the call blocks until the connection attempt is complete, whether it succeeds or fails. If *timeout == {0, 0} then the connection is done using nonblocking mode. In this case, if the connection can't be made immediately, this method returns -1 and errno == EWOULDBLOCK. If *timeout > {0, 0} then this is the maximum amount of time to wait before timing out; if the specified amount of time passes before the connection is made, this method returns -1 and errno == ETIME. Note the difference between this case and when a blocking connect is attempted that TCP times out - in the latter case, errno will be ETIMEDOUT. | |
local_sap | (optional) The local address to bind to. If it's the default value of ACE_Addr::sap_any then the OS will choose an unused port. | |
reuse_addr | (optional) If the value is 1, the local address (local_sap ) is reused, even if it hasn't been cleaned up yet. | |
flags | Ignored. | |
perms | Ignored. |
Definition at line 378 of file SSL_SOCK_Connector.cpp.
: connector_ () { ACE_TRACE ("ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector"); this->connect (new_stream, remote_sap, timeout, local_sap, reuse_addr, flags, perms); }
ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector | ( | ACE_SSL_SOCK_Stream & | new_stream, | |
const ACE_Addr & | remote_sap, | |||
ACE_QoS_Params | qos_params, | |||
const ACE_Time_Value * | timeout = 0 , |
|||
const ACE_Addr & | local_sap = ACE_Addr::sap_any , |
|||
ACE_Protocol_Info * | protocolinfo = 0 , |
|||
ACE_SOCK_GROUP | g = 0 , |
|||
u_long | flags = 0 , |
|||
int | reuse_addr = 0 , |
|||
int | perms = 0 | |||
) |
Actively connect to a peer, producing a connected ACE_SSL_SOCK_Stream
object if the connection succeeds. This method performs both the initial socket connect and the SSL handshake.
new_stream | The ACE_SSL_SOCK_Stream object that will be connected to the peer. | |
remote_sap | The address that we are trying to connect to. The protocol family of remote_sap is used for the connected socket. That is, if remote_sap contains an IPv6 address, a socket with family PF_INET6 will be used, else it will be PF_INET. | |
qos_params | Contains QoS parameters that are passed to the IntServ (RSVP) and DiffServ protocols. |
timeout | Pointer to an ACE_Time_Value object with amount of time to wait to connect. If the pointer is 0 then the call blocks until the connection attempt is complete, whether it succeeds or fails. If *timeout == {0, 0} then the connection is done using nonblocking mode. In this case, if the connection can't be made immediately, this method returns -1 and errno == EWOULDBLOCK. If *timeout > {0, 0} then this is the maximum amount of time to wait before timing out; if the specified amount of time passes before the connection is made, this method returns -1 and errno == ETIME. Note the difference between this case and when a blocking connect is attempted that TCP times out - in the latter case, errno will be ETIMEDOUT. | |
local_sap | (optional) The local address to bind to. If it's the default value of ACE_Addr::sap_any then the OS will choose an unused port. | |
reuse_addr | (optional) If the value is 1, the local address (local_sap ) is reused, even if it hasn't been cleaned up yet. | |
flags | Ignored. | |
perms | Ignored. |
Definition at line 398 of file SSL_SOCK_Connector.cpp.
: connector_ () { ACE_TRACE ("ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector"); this->connect (new_stream, remote_sap, qos_params, timeout, local_sap, protocolinfo, g, flags, reuse_addr, perms); }
ACE_SSL_SOCK_Connector::~ACE_SSL_SOCK_Connector | ( | void | ) |
Default dtor.
int ACE_SSL_SOCK_Connector::complete | ( | ACE_SSL_SOCK_Stream & | new_stream, | |
ACE_Addr * | remote_sap = 0 , |
|||
const ACE_Time_Value * | timeout = 0 | |||
) |
Try to complete a non-blocking connection. If connection completion is successful then <new_stream> contains the connected ACE_SSL_SOCK_Stream. If <remote_sap> is non-NULL then it will contain the address of the connected peer.
Definition at line 330 of file SSL_SOCK_Connector.cpp.
{ ACE_TRACE ("ACE_SSL_SOCK_Connector::complete"); // Take into account the time to complete the basic TCP handshake // and the SSL handshake. ACE_Time_Value time_copy; ACE_Countdown_Time countdown (&time_copy); if (tv != 0) { time_copy += *tv; countdown.start (); } // Only attempt to complete the TCP connection if it that hasn't // already been done. ACE_INET_Addr raddr; if (new_stream.peer ().get_remote_addr (raddr) != 0 && this->connector_.complete (new_stream.peer (), remote_sap, tv) == -1) return -1; // The handle in the SSL_SOCK_Stream should have already been set in // the connect() method. // If using a timeout, update the countdown timer to reflect the time // spent on the connect itself, then pass the remaining time to // ssl_connect to bound the time on the handshake. if (tv != 0) { countdown.update (); tv = &time_copy; } if (this->ssl_connect (new_stream, tv) == -1) { new_stream.close (); return -1; } return 0; }
int ACE_SSL_SOCK_Connector::connect | ( | ACE_SSL_SOCK_Stream & | new_stream, | |
const ACE_Addr & | remote_sap, | |||
ACE_QoS_Params | qos_params, | |||
const ACE_Time_Value * | timeout = 0 , |
|||
const ACE_Addr & | local_sap = ACE_Addr::sap_any , |
|||
ACE_Protocol_Info * | protocolinfo = 0 , |
|||
ACE_SOCK_GROUP | g = 0 , |
|||
u_long | flags = 0 , |
|||
int | reuse_addr = 0 , |
|||
int | perms = 0 | |||
) |
Actively connect to a peer, producing a connected ACE_SSL_SOCK_Stream
object if the connection succeeds. This method performs both the initial socket connect and the SSL handshake.
new_stream | The ACE_SSL_SOCK_Stream object that will be connected to the peer. | |
remote_sap | The address that we are trying to connect to. The protocol family of remote_sap is used for the connected socket. That is, if remote_sap contains an IPv6 address, a socket with family PF_INET6 will be used, else it will be PF_INET. | |
qos_params | Contains QoS parameters that are passed to the IntServ (RSVP) and DiffServ protocols. |
timeout | Pointer to an ACE_Time_Value object with amount of time to wait to connect. If the pointer is 0 then the call blocks until the connection attempt is complete, whether it succeeds or fails. If *timeout == {0, 0} then the connection is done using nonblocking mode. In this case, if the connection can't be made immediately, this method returns -1 and errno == EWOULDBLOCK. If *timeout > {0, 0} then this is the maximum amount of time to wait before timing out; if the specified amount of time passes before the connection is made, this method returns -1 and errno == ETIME. Note the difference between this case and when a blocking connect is attempted that TCP times out - in the latter case, errno will be ETIMEDOUT. | |
local_sap | (optional) The local address to bind to. If it's the default value of ACE_Addr::sap_any then the OS will choose an unused port. | |
reuse_addr | (optional) If the value is 1, the local address (local_sap ) is reused, even if it hasn't been cleaned up yet. | |
flags | Ignored. | |
perms | Ignored. |
Definition at line 258 of file SSL_SOCK_Connector.cpp.
{ ACE_TRACE ("ACE_SSL_SOCK_Connector::connect"); // Take into account the time to complete the basic TCP handshake // and the SSL handshake. ACE_Time_Value time_copy; ACE_Countdown_Time countdown (&time_copy); if (timeout != 0) { time_copy += *timeout; countdown.start (); } int result = this->connector_.connect (new_stream.peer (), remote_sap, qos_params, timeout, local_sap, protocolinfo, g, flags, reuse_addr, perms); int error = 0; if (result == -1) error = errno; // Save us some TSS accesses. // Obtain the handle from the underlying SOCK_Stream and set it in // the SSL_SOCK_Stream. Note that the case where a connection is in // progress is also handled. In that case, the handle must also be // set in the SSL_SOCK_Stream so that the correct handle is returned // when performing non-blocking connect()s. if (new_stream.get_handle () == ACE_INVALID_HANDLE && (result == 0 || (result == -1 && (error == EWOULDBLOCK || error == EINPROGRESS)))) new_stream.set_handle (new_stream.peer ().get_handle ()); if (result == -1) return result; // If using a timeout, update the countdown timer to reflect the time // spent on the connect itself, then pass the remaining time to // ssl_connect to bound the time on the handshake. if (timeout != 0) { countdown.update (); timeout = &time_copy; } result = this->ssl_connect (new_stream, timeout); if (result == -1) new_stream.close (); return result; }
int ACE_SSL_SOCK_Connector::connect | ( | ACE_SSL_SOCK_Stream & | new_stream, | |
const ACE_Addr & | remote_sap, | |||
const ACE_Time_Value * | timeout = 0 , |
|||
const ACE_Addr & | local_sap = ACE_Addr::sap_any , |
|||
int | reuse_addr = 0 , |
|||
int | flags = 0 , |
|||
int | perms = 0 | |||
) |
Actively connect to a peer, producing a connected ACE_SSL_SOCK_Stream
object if the connection succeeds. This method performs both the initial socket connect and the SSL handshake.
new_stream | The ACE_SSL_SOCK_Stream object that will be connected to the peer. | |
remote_sap | The address that we are trying to connect to. The protocol family of remote_sap is used for the connected socket. That is, if remote_sap contains an IPv6 address, a socket with family PF_INET6 will be used, else it will be PF_INET. | |
timeout | Pointer to an ACE_Time_Value object with amount of time to wait to connect. If the pointer is 0 then the call blocks until the connection attempt is complete, whether it succeeds or fails. If *timeout == {0, 0} then the connection is done using nonblocking mode. In this case, if the connection can't be made immediately, this method returns -1 and errno == EWOULDBLOCK. If *timeout > {0, 0} then this is the maximum amount of time to wait before timing out; if the specified amount of time passes before the connection is made, this method returns -1 and errno == ETIME. Note the difference between this case and when a blocking connect is attempted that TCP times out - in the latter case, errno will be ETIMEDOUT. | |
local_sap | (optional) The local address to bind to. If it's the default value of ACE_Addr::sap_any then the OS will choose an unused port. | |
reuse_addr | (optional) If the value is 1, the local address (local_sap ) is reused, even if it hasn't been cleaned up yet. | |
flags | Ignored. | |
perms | Ignored. |
Definition at line 193 of file SSL_SOCK_Connector.cpp.
{ ACE_TRACE ("ACE_SSL_SOCK_Connector::connect"); // Take into account the time to complete the basic TCP handshake // and the SSL handshake. ACE_Time_Value time_copy; ACE_Countdown_Time countdown (&time_copy); if (timeout != 0) { time_copy += *timeout; countdown.start (); } int result = this->connector_.connect (new_stream.peer (), remote_sap, timeout, local_sap, reuse_addr, flags, perms); int error = 0; if (result == -1) error = errno; // Save us some TSS accesses. // Obtain the handle from the underlying SOCK_Stream and set it in // the SSL_SOCK_Stream. Note that the case where a connection is in // progress is also handled. In that case, the handle must also be // set in the SSL_SOCK_Stream so that the correct handle is returned // when performing non-blocking connect()s. if (new_stream.get_handle () == ACE_INVALID_HANDLE && (result == 0 || (result == -1 && (error == EWOULDBLOCK || error == EINPROGRESS)))) new_stream.set_handle (new_stream.peer ().get_handle ()); if (result == -1) return result; // If using a timeout, update the countdown timer to reflect the time // spent on the connect itself, then pass the remaining time to // ssl_connect to bound the time on the handshake. if (timeout != 0) { countdown.update (); timeout = &time_copy; } result = this->ssl_connect (new_stream, timeout); if (result == -1) new_stream.close (); return result; }
void ACE_SSL_SOCK_Connector::dump | ( | void | ) | const |
Dump the state of an object.
Definition at line 22 of file SSL_SOCK_Connector.inl.
{ ACE_TRACE ("ACE_SSL_SOCK_Connector::dump"); this->connector_.dump (); }
bool ACE_SSL_SOCK_Connector::reset_new_handle | ( | ACE_HANDLE | handle | ) |
Resets any event associations on this handle.
Definition at line 15 of file SSL_SOCK_Connector.inl.
{ ACE_TRACE ("ACE_SSL_SOCK_Connector::reset_new_handle"); return this->connector_.reset_new_handle (handle); }
int ACE_SSL_SOCK_Connector::ssl_connect | ( | ACE_SSL_SOCK_Stream & | new_stream, | |
const ACE_Time_Value * | timeout | |||
) | [protected] |
Complete non-blocking SSL active connection.
Definition at line 34 of file SSL_SOCK_Connector.cpp.
{ SSL *ssl = new_stream.ssl (); if (SSL_is_init_finished (ssl)) return 0; // Check if a connection is already pending for the given SSL // structure. if (!SSL_in_connect_init (ssl)) ::SSL_set_connect_state (ssl); ACE_HANDLE handle = new_stream.get_handle (); // We're going to call SSL_connect, optionally doing ACE::select and // retrying the SSL_connect, until the SSL handshake is done or // it fails. // To get the timeout affect, set the socket to nonblocking mode // before beginning if there is a timeout specified. If the timeout // is 0 (wait as long as it takes) then don't worry about the blocking // status; we'll block in SSL_connect if the socket is blocking, and // block in ACE::select if not. int reset_blocking_mode = 0; if (timeout != 0) { reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle), ACE_NONBLOCK); // Set the handle into non-blocking mode if it's not already // in it. if (reset_blocking_mode && ACE::set_flags (handle, ACE_NONBLOCK) == -1) return -1; } ACE_Time_Value t; if (timeout != 0) t = *timeout; // Need a non-const copy. // Take into account the time between each select() call below. ACE_Countdown_Time countdown ((timeout == 0 ? 0 : &t)); int status; do { // These handle sets are used to set up for whatever SSL_connect // says it wants next. They're reset on each pass around the loop. ACE_Handle_Set rd_handle; ACE_Handle_Set wr_handle; status = ::SSL_connect (ssl); switch (::SSL_get_error (ssl, status)) { case SSL_ERROR_NONE: // Start out with non-blocking disabled on the SSL stream. new_stream.disable (ACE_NONBLOCK); status = 0; // To tell caller about success break; // Done case SSL_ERROR_WANT_WRITE: wr_handle.set_bit (handle); status = 1; // Wait for more activity break; case SSL_ERROR_WANT_READ: rd_handle.set_bit (handle); status = 1; // Wait for more activity break; case SSL_ERROR_ZERO_RETURN: // The peer has notified us that it is shutting down via // the SSL "close_notify" message so we need to // shutdown, too. status = -1; break; case SSL_ERROR_SYSCALL: // On some platforms (e.g. MS Windows) OpenSSL does not // store the last error in errno so explicitly do so. // // Explicitly check for EWOULDBLOCK since it doesn't get // converted to an SSL_ERROR_WANT_{READ,WRITE} on some // platforms. If SSL_connect failed outright, though, don't // bother checking more. This can happen if the socket gets // closed during the handshake. if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK && status == -1) { // Although the SSL_ERROR_WANT_READ/WRITE isn't getting // set correctly, the read/write state should be valid. // Use that to decide what to do. status = 1; // Wait for more activity if (SSL_want_write (ssl)) { wr_handle.set_bit (handle); } else if (SSL_want_read (ssl)) { rd_handle.set_bit (handle); } else { status = -1; // Doesn't want anything - bail out } } else { status = -1; } break; default: ACE_SSL_Context::report_error (); status = -1; break; } if (status == 1) { // Must have at least one handle to wait for at this point. ACE_ASSERT (rd_handle.num_set () == 1 || wr_handle.num_set () == 1); // Block indefinitely if timeout pointer is zero. status = ACE::select (int (handle) + 1, &rd_handle, &wr_handle, 0, (timeout == 0 ? 0 : &t)); (void) countdown.update (); // 0 is timeout, so we're done. // -1 is error, so we're done. // Could be both handles set (same handle in both masks) so set to 1. if (status >= 1) { status = 1; } else // Timeout or socket failure { status = -1; } } } while (status == 1 && !SSL_is_init_finished (ssl)); if (reset_blocking_mode) { ACE_Errno_Guard eguard (errno); ACE::clr_flags (handle, ACE_NONBLOCK); } return (status == -1 ? -1 : 0); }
Declare the dynamic allocation hooks.
Definition at line 294 of file SSL_SOCK_Connector.h.
The class that does all of the non-secure socket connection. It is default contructed, and subsequently used by connect().
Definition at line 306 of file SSL_SOCK_Connector.h.