11 #ifndef ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP 12 #define ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 19 #include <boost/function.hpp> 20 #include <boost/bind.hpp> 39 typedef boost::function<void (const asio::error_code&, int)>
47 static const int NET_BUF_SIZE = 16*1024 + 256;
49 unsigned char buf_[NET_BUF_SIZE];
50 unsigned char* data_start_;
51 unsigned char* data_end_;
56 data_start_ = data_end_ = buf_;
65 data_end_ = data_end_ > (buf_ + NET_BUF_SIZE)?
66 (buf_ + NET_BUF_SIZE):
72 if (data_start_ >= data_end_)
reset();
74 void reset() { data_start_ = buf_; data_end_ = buf_; }
75 bool has_data() {
return (data_start_ < data_end_); }
82 template <
typename Stream>
96 : primitive_(primitive)
97 , user_handler_(handler)
105 &openssl_operation::do_async_write,
106 this, boost::arg<1>(), boost::arg<2>()
109 &openssl_operation::do_async_read,
113 &openssl_operation::async_user_handler,
114 this, boost::arg<1>(), boost::arg<2>()
124 : primitive_(primitive)
126 , recv_buf_(recv_buf)
132 &openssl_operation::do_sync_write,
133 this, boost::arg<1>(), boost::arg<2>()
136 &openssl_operation::do_sync_read,
140 &openssl_operation::sync_user_handler,
141 this, boost::arg<1>(), boost::arg<2>()
150 int rc = primitive_( session_ );
152 bool is_operation_done = (rc > 0);
159 ::SSL_get_error( session_, rc ) :
161 int sys_error_code = ERR_get_error();
163 if (error_code == SSL_ERROR_SSL)
167 bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
168 bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
169 ::BIO_ctrl_pending( ssl_bio_ ));
170 bool is_shut_down_received =
171 ((::SSL_get_shutdown( session_ ) & SSL_RECEIVED_SHUTDOWN) ==
172 SSL_RECEIVED_SHUTDOWN);
173 bool is_shut_down_sent =
174 ((::SSL_get_shutdown( session_ ) & SSL_SENT_SHUTDOWN) ==
177 if (is_shut_down_sent && is_shut_down_received
178 && is_operation_done && !is_write_needed)
182 if (is_shut_down_received && !is_operation_done)
187 if (!is_operation_done && !is_read_needed && !is_write_needed
188 && !is_shut_down_sent)
192 if (error_code == SSL_ERROR_SYSCALL)
195 sys_error_code, asio::error::system_category), rc);
204 if (!is_operation_done && !is_write_needed)
207 if (recv_buf_.get_data_len() > 0)
210 int written = ::BIO_write
213 recv_buf_.get_data_start(),
214 recv_buf_.get_data_len()
219 recv_buf_.data_removed(written);
221 else if (written < 0)
223 if (!BIO_should_retry(ssl_bio_))
232 else if (is_read_needed || (is_shut_down_sent && !is_shut_down_received))
239 return write_(is_operation_done, rc);
244 typedef boost::function<int (const asio::error_code&, int)>
246 typedef boost::function<int (bool, int)> write_func;
247 typedef boost::function<int ()> read_func;
249 ssl_primitive_func primitive_;
254 int_handler_func handler_;
286 user_handler_(error, rc);
291 int do_async_write(
bool is_operation_done,
int rc)
293 int len = ::BIO_ctrl_pending( ssl_bio_ );
325 &openssl_operation::async_write_handler,
329 asio::placeholders::error,
330 asio::placeholders::bytes_transferred
337 else if (!BIO_should_retry(ssl_bio_))
346 if (is_operation_done)
368 if (is_operation_done)
382 socket_.async_read_some
390 &openssl_operation::async_read_handler,
392 asio::placeholders::error,
393 asio::placeholders::bytes_transferred
408 int written = ::BIO_write
419 else if (written < 0)
421 if (!BIO_should_retry(ssl_bio_))
441 int do_sync_write(
bool is_operation_done,
int rc)
443 int len = ::BIO_ctrl_pending( ssl_bio_ );
464 else if (!BIO_should_retry(ssl_bio_))
472 if (is_operation_done)
482 size_t len = socket_.read_some
492 int written = ::BIO_write
503 else if (written < 0)
505 if (!BIO_should_retry(ssl_bio_))
524 #endif // ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP
void data_removed(size_t count)
#define ASIO_ASSERT(expr)
openssl_operation(ssl_primitive_func primitive, Stream &socket, net_buffer &recv_buf, SSL *session, BIO *ssl_bio, user_handler_func handler, asio::io_service::strand &strand)
socket_type socket(int af, int type, int protocol, asio::error_code &ec)
void async_write_handler(const asio::error_code &e, size_t bytes_transferred, size_t expected_bytes_transferred, bool *called)
std::size_t write(SyncWriteStream &s, const ConstBufferSequence &buffers, CompletionCondition completion_condition, asio::error_code &ec)
Write a certain amount of data to a stream before returning.
mutable_buffers_1 buffer(const mutable_buffer &b)
Create a new modifiable buffer from an existing buffer.
Provides serialised handler execution.
unsigned char * get_unused_start()
ASIO_DECL const asio::error_category & get_ssl_category()
unsigned char * get_data_start()
void data_added(size_t count)
boost::function< int(::SSL *)> ssl_primitive_func
int bind(socket_type s, const socket_addr_type *addr, std::size_t addrlen, asio::error_code &ec)
Class to represent an error code value.
A non-recoverable error occurred.
boost::function< void(const asio::error_code &, int)> user_handler_func
detail::wrapped_handler< strand, Handler, detail::is_continuation_if_running > wrap(Handler handler)
void async_read_handler(const asio::error_code &e, size_t bytes_transferred, size_t expected_bytes_transferred, bool *called)
openssl_operation(ssl_primitive_func primitive, Stream &socket, net_buffer &recv_buf, SSL *session, BIO *ssl_bio)
Cannot send after transport endpoint shutdown.