Public Member Functions | Protected Member Functions

ACE::INet::SSL_Proxy_Connector Class Reference

#include <SSL_Proxy_Connector.h>

List of all members.

Public Member Functions

 SSL_Proxy_Connector ()
 ~SSL_Proxy_Connector ()
int connect (ACE_SSL_SOCK_Stream &new_stream, ACE_HANDLE proxy_handle, const ACE_Time_Value *timeout=0)

Protected Member Functions

int ssl_connect (ACE_SSL_SOCK_Stream &new_stream, const ACE_Time_Value *timeout)
 Complete non-blocking SSL active connection.

Detailed Description

Definition at line 33 of file SSL_Proxy_Connector.h.


Constructor & Destructor Documentation

ACE::INet::SSL_Proxy_Connector::SSL_Proxy_Connector (  ) 

Definition at line 21 of file SSL_Proxy_Connector.cpp.

{}

ACE::INet::SSL_Proxy_Connector::~SSL_Proxy_Connector (  ) 

Definition at line 23 of file SSL_Proxy_Connector.cpp.

{}


Member Function Documentation

int ACE::INet::SSL_Proxy_Connector::connect ( ACE_SSL_SOCK_Stream new_stream,
ACE_HANDLE  proxy_handle,
const ACE_Time_Value timeout = 0 
)

Actively connect to an already connected proxy peer, producing a connected ACE_SSL_SOCK_Stream object if the connection succeeds. This method uses the provided connection (socket) handle to initialize the ACE_SSL_SOCK_Stream object and than finalizes the connection by performing the SSL handshake.

Definition at line 187 of file SSL_Proxy_Connector.cpp.

      {
        INET_TRACE ("SSL_Proxy_Connector::connect");

        if (new_stream.get_handle () != ACE_INVALID_HANDLE)
          return -1;    // SSL already connected, somebody made a mistake here

        // Set the handle from the established proxy connection in the
        // SSL_SOCK_Stream.
        new_stream.set_handle (proxy_handle);

        // Finalize the connection by performing the SSL handshake
        int result = this->ssl_connect (new_stream, timeout);

        if (result == -1)
          new_stream.close ();

        return result;
      }

int ACE::INet::SSL_Proxy_Connector::ssl_connect ( ACE_SSL_SOCK_Stream new_stream,
const ACE_Time_Value timeout 
) [protected]

Complete non-blocking SSL active connection.

Definition at line 29 of file SSL_Proxy_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);
      }


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines