2 #include "ace/OS_NS_errno.h"
3 #include "ace/Truncate.h"
5 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
8 ACE_SSL_SOCK_Stream::set_handle (ACE_HANDLE fd)
10 if (this->ssl_ == 0 || fd == ACE_INVALID_HANDLE)
12 this->ACE_SSL_SOCK::set_handle (ACE_INVALID_HANDLE);
17 (void) ::SSL_set_fd (this->ssl_, (int) fd);
18 this->ACE_SSL_SOCK::set_handle (fd);
19 this->stream_.set_handle (fd);
24 ACE_SSL_SOCK_Stream::send_i (const void *buf,
28 ACE_TRACE ("ACE_SSL_SOCK_Stream::send_i");
30 // NOTE: Caller must provide thread-synchronization.
32 // No send flags are supported in SSL.
35 ACE_NOTSUP_RETURN (-1);
38 int const bytes_sent = ::SSL_write (this->ssl_,
39 static_cast<const char *> (buf),
40 ACE_Utils::truncate_cast<int> (n));
42 switch (::SSL_get_error (this->ssl_, bytes_sent))
47 case SSL_ERROR_WANT_READ:
48 case SSL_ERROR_WANT_WRITE:
53 case SSL_ERROR_ZERO_RETURN:
54 // The peer has notified us that it is shutting down via the SSL
55 // "close_notify" message so we need to shutdown, too.
56 (void) ::SSL_shutdown (this->ssl_);
60 case SSL_ERROR_SYSCALL:
62 // An EOF occurred but the SSL "close_notify" message was not
63 // sent. This is a protocol error, but we ignore it.
66 // If not an EOF, then fall through to "default" case.
68 // On some platforms (e.g. MS Windows) OpenSSL does not store
69 // the last error in errno so explicitly do so.
70 ACE_OS::set_errno_to_last_error ();
75 // Reset errno to prevent previous values (e.g. EWOULDBLOCK)
76 // from being associated with fatal SSL errors.
79 ACE_SSL_Context::report_error ();
88 ACE_SSL_SOCK_Stream::send (const void *buf,
92 return this->send_i (buf, n, flags);
96 ACE_SSL_SOCK_Stream::recv_i (void *buf,
99 const ACE_Time_Value *timeout) const
101 ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_i");
103 // NOTE: Caller must provide thread-synchronization.
105 ACE_HANDLE const handle = this->get_handle ();
107 // Value for current I/O mode (blocking/non-blocking)
111 ACE::record_and_set_non_blocking_mode (handle,
114 // Only block to wait for I/O ready with a timeout if all on-hand data
115 // has been consumed. If there is remaining data in the SSL buffers
116 // the socket won't "select" even though SSL_read would complete.
117 // See "SSL and TLS" by Rescorla section 8.9 for more info.
118 bool peeking = false;
122 if (ACE_BIT_ENABLED (flags, MSG_PEEK))
128 ACE_NOTSUP_RETURN (-1);
137 bytes_read = ::SSL_peek (this->ssl_,
138 static_cast<char *> (buf),
139 ACE_Utils::truncate_cast<int> (n));
143 bytes_read = ::SSL_read (this->ssl_,
144 static_cast<char *> (buf),
145 ACE_Utils::truncate_cast<int> (n));
148 int const status = ::SSL_get_error (this->ssl_, bytes_read);
155 case SSL_ERROR_WANT_READ:
156 case SSL_ERROR_WANT_WRITE:
163 substat = ACE::handle_ready (handle,
165 status == SSL_ERROR_WANT_READ,
166 status == SSL_ERROR_WANT_WRITE,
168 if (substat == 1) // Now ready to proceed
178 case SSL_ERROR_ZERO_RETURN:
181 // The peer has notified us that it is shutting down via the SSL
182 // "close_notify" message so we need to shutdown, too.
183 (void) ::SSL_shutdown (this->ssl_);
187 case SSL_ERROR_SYSCALL:
189 // An EOF occurred but the SSL "close_notify" message was not
190 // sent. This is a protocol error, but we ignore it.
193 // On some platforms (e.g. MS Windows) OpenSSL does not store
194 // the last error in errno so explicitly do so.
195 ACE_OS::set_errno_to_last_error ();
200 // Reset errno to prevent previous values (e.g. EWOULDBLOCK)
201 // from being associated with a fatal SSL error.
205 ACE_SSL_Context::report_error ();
212 ACE::restore_non_blocking_mode (handle, val);
217 ACE_SSL_SOCK_Stream::recv (void *buf,
221 return this->recv_i (buf, n, flags, 0);
225 ACE_SSL_SOCK_Stream::send (const void *buf,
228 ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
230 return this->send_i (buf, n, 0);
234 ACE_SSL_SOCK_Stream::recv (void *buf,
237 ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
239 return this->recv_i (buf, n, 0, 0);
243 ACE_SSL_SOCK_Stream::send (const void *buf,
245 const ACE_Time_Value *timeout) const
247 ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
248 return this->send (buf, len, 0, timeout);
252 ACE_SSL_SOCK_Stream::recv (void *buf,
254 const ACE_Time_Value *timeout) const
256 ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
257 return this->recv (buf, n, 0, timeout);
261 ACE_SSL_SOCK_Stream::recv_n (void *buf, int buf_size) const
263 ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
264 return this->recv_n (buf, buf_size, 0);
268 ACE_SSL_SOCK_Stream::recv_n (void *buf,
270 const ACE_Time_Value *timeout,
271 size_t *bytes_transferred) const
273 ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
274 return this->recv_n (buf, len, 0, timeout, bytes_transferred);
278 ACE_SSL_SOCK_Stream::send_n (const void *buf, int len) const
280 ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
281 return this->send_n (buf, len, 0);
285 ACE_SSL_SOCK_Stream::send_n (const void *buf,
287 const ACE_Time_Value *timeout,
288 size_t *bytes_transferred) const
290 ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
291 return this->send_n (buf, len, 0, timeout, bytes_transferred);
295 ACE_SSL_SOCK_Stream::close_reader ()
297 ACE_TRACE ("ACE_SSL_SOCK_Stream::close_reader");
298 return this->stream_.close_reader ();
302 ACE_SSL_SOCK_Stream::close_writer ()
304 ACE_TRACE ("ACE_SSL_SOCK_Stream::close_writer");
305 return this->stream_.close_writer ();
309 ACE_SSL_SOCK_Stream::close ()
311 ACE_TRACE ("ACE_SSL_SOCK_Stream::close");
313 if (this->ssl_ == 0 || this->get_handle () == ACE_INVALID_HANDLE)
314 return 0; // SSL_SOCK_Stream was never opened.
316 // SSL_shutdown() returns 1 on successful shutdown of the SSL
317 // connection, not 0.
318 int const status = ::SSL_shutdown (this->ssl_);
320 switch (::SSL_get_error (this->ssl_, status))
323 case SSL_ERROR_SYSCALL: // Ignore this error condition.
325 // Reset the SSL object to allow another connection to be made
326 // using this ACE_SSL_SOCK_Stream instance. This prevents the
327 // previous SSL session state from being associated with the new
328 // SSL session/connection.
329 (void) ::SSL_clear (this->ssl_);
330 this->set_handle (ACE_INVALID_HANDLE);
331 return this->stream_.close ();
333 case SSL_ERROR_WANT_READ:
334 case SSL_ERROR_WANT_WRITE:
339 ACE_SSL_Context::report_error ();
341 ACE_Errno_Guard error (errno); // Save/restore errno
342 (void) this->stream_.close ();
350 ACE_INLINE ACE_SOCK_Stream &
351 ACE_SSL_SOCK_Stream::peer ()
353 ACE_TRACE ("ACE_SSL_SOCK_Stream::peer");
354 return this->stream_;
358 ACE_SSL_SOCK_Stream::ssl () const
363 ACE_END_VERSIONED_NAMESPACE_DECL