SSL_SOCK_Stream.i

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // SSL_SOCK_Stream.i,v 1.47 2005/10/28 16:14:56 ossama Exp
00004 
00005 #include "ace/OS_NS_errno.h"
00006 
00007 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00008 
00009 ACE_INLINE void
00010 ACE_SSL_SOCK_Stream::set_handle (ACE_HANDLE fd)
00011 {
00012   if (this->ssl_ == 0 || fd == ACE_INVALID_HANDLE)
00013     {
00014       this->ACE_SSL_SOCK::set_handle (ACE_INVALID_HANDLE);
00015       return;
00016     }
00017   else
00018     {
00019       (void) ::SSL_set_fd (this->ssl_, (int) fd);
00020       this->ACE_SSL_SOCK::set_handle (fd);
00021       this->stream_.set_handle (fd);
00022     }
00023 }
00024 
00025 ACE_INLINE ssize_t
00026 ACE_SSL_SOCK_Stream::send_i (const void *buf,
00027                              size_t n,
00028                              int flags) const
00029 {
00030   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_i");
00031 
00032   // NOTE: Caller must provide thread-synchronization.
00033 
00034   // No send flags are supported in SSL.
00035   if (flags != 0)
00036     ACE_NOTSUP_RETURN (-1);
00037 
00038   const int bytes_sent = ::SSL_write (this->ssl_,
00039                                       static_cast<const char *> (buf),
00040                                       n);
00041 
00042   switch (::SSL_get_error (this->ssl_, bytes_sent))
00043     {
00044     case SSL_ERROR_NONE:
00045       return bytes_sent;
00046 
00047     case SSL_ERROR_WANT_READ:
00048     case SSL_ERROR_WANT_WRITE:
00049       errno = EWOULDBLOCK;
00050 
00051       return -1;
00052 
00053     case SSL_ERROR_ZERO_RETURN:
00054       // The peer has notified us that it is shutting down via the SSL
00055       // "close_notify" message so we need to shutdown, too.
00056       (void) ::SSL_shutdown (this->ssl_);
00057 
00058       return bytes_sent;
00059 
00060     case SSL_ERROR_SYSCALL:
00061       if (bytes_sent == 0)
00062         // An EOF occured but the SSL "close_notify" message was not
00063         // sent.  This is a protocol error, but we ignore it.
00064         return 0;
00065 
00066       // If not an EOF, then fall through to "default" case.
00067 
00068       // On some platforms (e.g. MS Windows) OpenSSL does not store
00069       // the last error in errno so explicitly do so.
00070       ACE_OS::set_errno_to_last_error ();
00071 
00072       break;
00073 
00074     default:
00075       // Reset errno to prevent previous values (e.g. EWOULDBLOCK)
00076       // from being associated with fatal SSL errors.
00077       errno = 0;
00078 
00079       ACE_SSL_Context::report_error ();
00080 
00081       break;
00082     }
00083 
00084   return -1;
00085 }
00086 
00087 ACE_INLINE ssize_t
00088 ACE_SSL_SOCK_Stream::send (const void *buf,
00089                            size_t n,
00090                            int flags) const
00091 {
00092   return this->send_i (buf, n, flags);
00093 }
00094 
00095 ACE_INLINE ssize_t
00096 ACE_SSL_SOCK_Stream::recv_i (void *buf,
00097                              size_t n,
00098                              int flags,
00099                              const ACE_Time_Value *timeout) const
00100 {
00101   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_i");
00102 
00103   // NOTE: Caller must provide thread-synchronization.
00104 
00105   int bytes_read = 0;
00106   const ACE_HANDLE handle = this->get_handle ();
00107 
00108   // Value for current I/O mode (blocking/non-blocking)
00109   int val = 0;
00110 
00111   if (timeout != 0)
00112     ACE::record_and_set_non_blocking_mode (handle,
00113                                            val);
00114 
00115   // Only block on select() with a timeout if no data in the
00116   // internal OpenSSL buffer is pending read completion for
00117   // the same reasons stated above, i.e. all data must be read
00118   // before blocking on select().
00119   if (timeout != 0
00120       && !::SSL_pending (this->ssl_))
00121     {
00122       if (ACE::enter_recv_timedwait (handle,
00123                                      timeout,
00124                                      val) == -1)
00125         return -1;
00126     }
00127 
00128   if (flags)
00129     {
00130       if (ACE_BIT_ENABLED (flags, MSG_PEEK))
00131         bytes_read = ::SSL_peek (this->ssl_,
00132                                  static_cast<char *> (buf),
00133                                  n);
00134       else
00135         ACE_NOTSUP_RETURN (-1);
00136     }
00137   else
00138     {
00139       bytes_read = ::SSL_read (this->ssl_,
00140                                static_cast<char *> (buf),
00141                                n);
00142     }
00143 
00144   const int status = ::SSL_get_error (this->ssl_, bytes_read);
00145   switch (status)
00146     {
00147     case SSL_ERROR_NONE:
00148       if (timeout != 0)
00149         ACE::restore_non_blocking_mode (handle, val);
00150 
00151       return bytes_read;
00152 
00153     case SSL_ERROR_WANT_READ:
00154     case SSL_ERROR_WANT_WRITE:
00155       errno = EWOULDBLOCK;
00156 
00157       return -1;
00158 
00159     case SSL_ERROR_ZERO_RETURN:
00160       if (timeout != 0)
00161         ACE::restore_non_blocking_mode (handle, val);
00162 
00163       // The peer has notified us that it is shutting down via the SSL
00164       // "close_notify" message so we need to shutdown, too.
00165       (void) ::SSL_shutdown (this->ssl_);
00166 
00167       return bytes_read;
00168 
00169     case SSL_ERROR_SYSCALL:
00170       if (bytes_read == 0)
00171         // An EOF occured but the SSL "close_notify" message was not
00172         // sent.  This is a protocol error, but we ignore it.
00173         return 0;
00174 
00175       // If not an EOF, then fall through to "default" case.
00176 
00177       // On some platforms (e.g. MS Windows) OpenSSL does not store
00178       // the last error in errno so explicitly do so.
00179       ACE_OS::set_errno_to_last_error ();
00180 
00181       break;
00182 
00183     default:
00184       // Reset errno to prevent previous values (e.g. EWOULDBLOCK)
00185       // from being associated with a fatal SSL error.
00186       errno = 0;
00187 
00188       ACE_SSL_Context::report_error ();
00189 
00190       break;
00191     }
00192 
00193   return -1;
00194 }
00195 
00196 ACE_INLINE ssize_t
00197 ACE_SSL_SOCK_Stream::recv (void *buf,
00198                            size_t n,
00199                            int flags) const
00200 {
00201   return this->recv_i (buf, n, flags, 0);
00202 }
00203 
00204 ACE_INLINE ssize_t
00205 ACE_SSL_SOCK_Stream::send (const void *buf,
00206                            size_t n) const
00207 {
00208   ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
00209 
00210   return this->send_i (buf, n, 0);
00211 }
00212 
00213 ACE_INLINE ssize_t
00214 ACE_SSL_SOCK_Stream::recv (void *buf,
00215                            size_t n) const
00216 {
00217   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00218 
00219   return this->recv_i (buf, n, 0, 0);
00220 }
00221 
00222 ACE_INLINE ssize_t
00223 ACE_SSL_SOCK_Stream::send (const void *buf,
00224                            size_t len,
00225                            const ACE_Time_Value *timeout) const
00226 {
00227   ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
00228   return this->send (buf, len, 0, timeout);
00229 }
00230 
00231 ACE_INLINE ssize_t
00232 ACE_SSL_SOCK_Stream::recv (void *buf,
00233                            size_t n,
00234                            const ACE_Time_Value *timeout) const
00235 {
00236   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
00237   return this->recv (buf, n, 0, timeout);
00238 }
00239 
00240 ACE_INLINE ssize_t
00241 ACE_SSL_SOCK_Stream::recv_n (void *buf, int buf_size) const
00242 {
00243   ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
00244   return this->recv_n (buf, buf_size, 0);
00245 }
00246 
00247 ACE_INLINE ssize_t
00248 ACE_SSL_SOCK_Stream::send_n (const void *buf, int len) const
00249 {
00250   ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
00251   return this->send_n (buf, len, 0);
00252 }
00253 
00254 ACE_INLINE int
00255 ACE_SSL_SOCK_Stream::close_reader (void)
00256 {
00257   ACE_TRACE ("ACE_SSL_SOCK_Stream::close_reader");
00258   return this->stream_.close_reader ();
00259 }
00260 
00261 ACE_INLINE int
00262 ACE_SSL_SOCK_Stream::close_writer (void)
00263 {
00264   ACE_TRACE ("ACE_SSL_SOCK_Stream::close_writer");
00265   return this->stream_.close_writer ();
00266 }
00267 
00268 ACE_INLINE int
00269 ACE_SSL_SOCK_Stream::close (void)
00270 {
00271   ACE_TRACE ("ACE_SSL_SOCK_Stream::close");
00272 
00273   if (this->ssl_ == 0 || this->get_handle () == ACE_INVALID_HANDLE)
00274     return 0;  // SSL_SOCK_Stream was never opened.
00275 
00276   // SSL_shutdown() returns 1 on successful shutdown of the SSL
00277   // connection, not 0.
00278   const int status = ::SSL_shutdown (this->ssl_);
00279 
00280   switch (::SSL_get_error (this->ssl_, status))
00281     {
00282     case SSL_ERROR_NONE:
00283     case SSL_ERROR_SYSCALL:  // Ignore this error condition.
00284 
00285       // Reset the SSL object to allow another connection to be made
00286       // using this ACE_SSL_SOCK_Stream instance.  This prevents the
00287       // previous SSL session state from being associated with the new
00288       // SSL session/connection.
00289       (void) ::SSL_clear (this->ssl_);
00290       this->set_handle (ACE_INVALID_HANDLE);
00291       return this->stream_.close ();
00292 
00293     case SSL_ERROR_WANT_READ:
00294     case SSL_ERROR_WANT_WRITE:
00295       errno = EWOULDBLOCK;
00296       break;
00297 
00298     default:
00299       ACE_SSL_Context::report_error ();
00300 
00301       ACE_Errno_Guard error (errno);   // Save/restore errno
00302       (void) this->stream_.close ();
00303 
00304       return -1;
00305     }
00306 
00307   return -1;
00308 }
00309 
00310 ACE_INLINE ACE_SOCK_Stream &
00311 ACE_SSL_SOCK_Stream::peer (void)
00312 {
00313   ACE_TRACE ("ACE_SSL_SOCK_Stream::peer");
00314   return this->stream_;
00315 }
00316 
00317 ACE_INLINE SSL *
00318 ACE_SSL_SOCK_Stream::ssl (void) const
00319 {
00320   return this->ssl_;
00321 }
00322 
00323 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 11:41:56 2006 for ACE_SSL by doxygen 1.3.6