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

SSL_SOCK_Stream.i

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

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