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

SSL_SOCK_Acceptor.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // $Id: SSL_SOCK_Acceptor.cpp,v 1.1.1.2 2003/02/21 18:36:32 chad Exp $
00004 
00005 
00006 #include "SSL_SOCK_Acceptor.h"
00007 
00008 #include "ace/Handle_Set.h"
00009 #include "ace/OS_Errno.h"
00010 #include "ace/Log_Msg.h"
00011 
00012 ACE_ALLOC_HOOK_DEFINE(ACE_SSL_SOCK_Acceptor)
00013 
00014 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
00015 #include "SSL_SOCK_Acceptor.i"
00016 #endif /* ACE_LACKS_INLINE_FUNCTIONS */
00017 
00018 ACE_RCSID (ACE_SSL,
00019            SSL_SOCK_Acceptor,
00020            "$Id: SSL_SOCK_Acceptor.cpp,v 1.1.1.2 2003/02/21 18:36:32 chad Exp $")
00021 
00022 ACE_SSL_SOCK_Acceptor::~ACE_SSL_SOCK_Acceptor (void)
00023 {
00024   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::~ACE_SSL_SOCK_Acceptor");
00025 }
00026 
00027 
00028 int
00029 ACE_SSL_SOCK_Acceptor::ssl_accept (ACE_SSL_SOCK_Stream &new_stream,
00030                                    ACE_Time_Value *timeout) const
00031 {
00032   SSL *ssl = new_stream.ssl ();
00033 
00034   if (SSL_is_init_finished (ssl))
00035     return 0;
00036 
00037   if (!SSL_in_accept_init (ssl))
00038     ::SSL_set_accept_state (ssl);
00039 
00040   ACE_HANDLE handle = new_stream.get_handle ();
00041 
00042   // We're going to call SSL_accept, optionally doing ACE::select and
00043   // retrying the SSL_accept, until the SSL handshake is done or
00044   // it fails.
00045   // To get the timeout affect, set the socket to nonblocking mode
00046   // before beginning if there is a timeout specified. If the timeout
00047   // is 0 (wait as long as it takes) then don't worry about the blocking
00048   // status; we'll block in SSL_accept if the socket is blocking, and
00049   // block in ACE::select if not.
00050   int reset_blocking_mode = 0;
00051   if (timeout != 0)
00052     {
00053       reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
00054                                               ACE_NONBLOCK);
00055           // Set the handle into non-blocking mode if it's not already
00056           // in it.
00057           if (reset_blocking_mode
00058               && ACE::set_flags (handle,
00059                                  ACE_NONBLOCK) == -1)
00060             return -1;
00061     }
00062 
00063   // Take into account the time between each select() call below.
00064   ACE_Countdown_Time countdown (timeout);
00065 
00066   int status;
00067   do
00068     {
00069       // These handle sets are used to set up for whatever SSL_accept
00070       // says it wants next. They're reset on each pass around the loop.
00071       ACE_Handle_Set rd_handle;
00072       ACE_Handle_Set wr_handle;
00073 
00074       status = ::SSL_accept (ssl);
00075       switch (::SSL_get_error (ssl, status))
00076         {
00077         case SSL_ERROR_NONE:
00078           status = 0;               // To tell caller about success
00079           break;                    // Done
00080 
00081         case SSL_ERROR_WANT_WRITE:
00082           wr_handle.set_bit (handle);
00083           status = 1;               // Wait for more activity
00084           break;
00085 
00086         case SSL_ERROR_WANT_READ:
00087           rd_handle.set_bit (handle);
00088           status = 1;               // Wait for more activity
00089           break;
00090 
00091         case SSL_ERROR_ZERO_RETURN:
00092           // The peer has notified us that it is shutting down via
00093           // the SSL "close_notify" message so we need to
00094           // shutdown, too.
00095           status = -1;
00096           break;
00097 
00098         case SSL_ERROR_SYSCALL:
00099           // On some platforms (e.g. MS Windows) OpenSSL does not
00100           // store the last error in errno so explicitly do so.
00101           //
00102           // Explicitly check for EWOULDBLOCK since it doesn't get
00103           // converted to an SSL_ERROR_WANT_{READ,WRITE} on some
00104           // platforms. If SSL_accept failed outright, though, don't
00105           // bother checking more. This can happen if the socket gets
00106           // closed during the handshake.
00107           if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK &&
00108               status == -1)
00109             {
00110               // Although the SSL_ERROR_WANT_READ/WRITE isn't getting
00111               // set correctly, the read/write state should be valid.
00112               // Use that to decide what to do.
00113               status = 1;               // Wait for more activity
00114               if (SSL_want_write (ssl))
00115                 wr_handle.set_bit (handle);
00116               else if (SSL_want_read (ssl))
00117                 rd_handle.set_bit (handle);
00118               else
00119                 status = -1;            // Doesn't want anything - bail out
00120             }
00121           else
00122             status = -1;
00123           break;
00124 
00125         default:
00126           ACE_SSL_Context::report_error ();
00127           status = -1;
00128           break;
00129         }
00130 
00131       if (status == 1)
00132         {
00133           // Must have at least one handle to wait for at this point.
00134           ACE_ASSERT (rd_handle.num_set() == 1 || wr_handle.num_set () == 1);
00135           status = ACE::select (int (handle) + 1,
00136                                 &rd_handle,
00137                                 &wr_handle,
00138                                 0,
00139                                 timeout);
00140 
00141           (void) countdown.update ();
00142 
00143           // 0 is timeout, so we're done.
00144           // -1 is error, so we're done.
00145           // Could be both handles set (same handle in both masks) so
00146           // set to 1.
00147           if (status >= 1)
00148             status = 1;
00149           else                   // Timeout or failure
00150             status = -1;
00151         }
00152 
00153     } while (status == 1 && !SSL_is_init_finished (ssl));
00154 
00155   if (reset_blocking_mode)
00156     {
00157       ACE_Errno_Guard eguard (errno);
00158       ACE::clr_flags (handle, ACE_NONBLOCK);
00159     }
00160 
00161   return (status == -1 ? -1 : 0);
00162 
00163 }
00164 
00165 // General purpose routine for accepting new connections.
00166 // Since our underlying acceptor is of the plain old ACE_SOCK_Acceptor
00167 // variety, get the basic socket setup done with it, then take care of
00168 // the SSL handshake if the socket is accepted.
00169 int
00170 ACE_SSL_SOCK_Acceptor::accept (ACE_SSL_SOCK_Stream &new_stream,
00171                                ACE_Addr *remote_addr,
00172                                ACE_Time_Value *timeout,
00173                                int restart,
00174                                int reset_new_handle) const
00175 {
00176   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::accept");
00177 
00178   // Take into account the time to complete the basic TCP handshake
00179   // and the SSL handshake.
00180   ACE_Countdown_Time countdown (timeout);
00181 
00182   ACE_SOCK_Stream temp_stream;
00183   if (-1 == this->acceptor_.accept (temp_stream,
00184                                     remote_addr,
00185                                     timeout,
00186                                     restart,
00187                                     reset_new_handle))
00188     return -1;
00189 
00190   (void) countdown.update ();
00191 
00192   new_stream.set_handle (temp_stream.get_handle ());
00193   temp_stream.set_handle (ACE_INVALID_HANDLE);
00194 
00195   if (this->ssl_accept (new_stream, timeout) == -1)
00196     {
00197       new_stream.close ();
00198       new_stream.set_handle (ACE_INVALID_HANDLE);
00199       return -1;
00200     }
00201 
00202   return 0;
00203 
00204 }
00205 
00206 int
00207 ACE_SSL_SOCK_Acceptor::accept (ACE_SSL_SOCK_Stream &new_stream,
00208                                ACE_Accept_QoS_Params qos_params,
00209                                ACE_Addr *remote_addr,
00210                                ACE_Time_Value *timeout,
00211                                int restart,
00212                                int reset_new_handle) const
00213 {
00214   ACE_TRACE ("ACE_SSL_SOCK_Acceptor::accept");
00215 
00216   // Take into account the time to complete the basic TCP handshake
00217   // and the SSL handshake.
00218   ACE_Countdown_Time countdown (timeout);
00219 
00220   ACE_SOCK_Stream temp_stream;
00221   if (-1 == this->acceptor_.accept (temp_stream,
00222                                     qos_params,
00223                                     remote_addr,
00224                                     timeout,
00225                                     restart,
00226                                     reset_new_handle))
00227     return -1;
00228 
00229   (void) countdown.update ();
00230 
00231   new_stream.set_handle (temp_stream.get_handle ());
00232   temp_stream.set_handle (ACE_INVALID_HANDLE);
00233 
00234   if (this->ssl_accept (new_stream, timeout) == -1)
00235     {
00236       new_stream.close ();
00237       new_stream.set_handle (ACE_INVALID_HANDLE);
00238       return -1;
00239     }
00240 
00241   return 0;
00242 
00243 }

Generated on Mon Jun 16 13:15:55 2003 for ACE_SSL by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002