Update of /cvsroot/boost/boost/boost/asio/ssl/detail
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv2133/detail
Modified Files:
openssl_operation.hpp openssl_stream_service.hpp
Log Message:
Fix two problems in the SSL implementation:
- A read operation should check the read buffer first to see if there's any
data present and use that first, before issuing a new read from the
socket.
- The read buffer was a member of the openssl_operation class, and a new
openssl_operation object is created for each read or write initiated by
the application. This meant that any surplus data from a previous read is
lost. Changed the buffer to be a member of the stream object.
Index: openssl_operation.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/asio/ssl/detail/openssl_operation.hpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- openssl_operation.hpp 14 Jun 2006 22:26:31 -0000 1.1
+++ openssl_operation.hpp 26 Jul 2006 11:14:12 -0000 1.2
@@ -83,12 +83,14 @@
// Constructor for asynchronous operations
openssl_operation(ssl_primitive_func primitive,
Stream& socket,
+ net_buffer& recv_buf,
SSL* session,
BIO* ssl_bio,
user_handler_func handler
)
: primitive_(primitive)
, user_handler_(handler)
+ , recv_buf_(recv_buf)
, socket_(socket)
, ssl_bio_(ssl_bio)
, session_(session)
@@ -106,9 +108,11 @@
// Constructor for synchronous operations
openssl_operation(ssl_primitive_func primitive,
Stream& socket,
+ net_buffer& recv_buf,
SSL* session,
BIO* ssl_bio)
: primitive_(primitive)
+ , recv_buf_(recv_buf)
, socket_(socket)
, ssl_bio_(ssl_bio)
, session_(session)
@@ -166,6 +170,36 @@
// not want network communication nor does want to send shutdown out...
return handler_(boost::asio::error(error_code), rc);
+ if (!is_operation_done && !is_write_needed)
+ {
+ // We may have left over data that we can pass to SSL immediately
+ if (recv_buf_.get_data_len() > 0)
+ {
+ // Pass the buffered data to SSL
+ int written = ::BIO_write
+ (
+ ssl_bio_,
+ recv_buf_.get_data_start(),
+ recv_buf_.get_data_len()
+ );
+
+ if (written > 0)
+ {
+ recv_buf_.data_removed(written);
+ }
+ else if (written < 0)
+ {
+ if (!BIO_should_retry(ssl_bio_))
+ {
+ // Some serios error with BIO....
+ return
handler_(boost::asio::error(boost::asio::error::no_recovery), 0);
+ }
+ }
+
+ return start();
+ }
+ }
+
// Continue with operation, flush any SSL data out to network...
return write_(is_operation_done, rc);
}
@@ -182,7 +216,12 @@
int_handler_func handler_;
net_buffer send_buf_; // buffers for network IO
- net_buffer recv_buf_;
+
+ // The recv buffer is owned by the stream, not the operation, since there can
+ // be left over bytes after passing the data up to the application, and these
+ // bytes need to be kept around for the next read operation issued by the
+ // application.
+ net_buffer& recv_buf_;
Stream& socket_;
BIO* ssl_bio_;
@@ -215,9 +254,11 @@
send_buf_.get_unused_len();
if (len == 0)
+ {
// In case our send buffer is full, we have just to wait until
// previous send to complete...
return 0;
+ }
// Read outgoing data from bio
len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len);
@@ -226,7 +267,7 @@
{
unsigned char *data_start = send_buf_.get_unused_start();
send_buf_.data_added(len);
-
+
boost::asio::async_write
(
socket_,
Index: openssl_stream_service.hpp
===================================================================
RCS file:
/cvsroot/boost/boost/boost/asio/ssl/detail/openssl_stream_service.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- openssl_stream_service.hpp 18 Jun 2006 07:58:02 -0000 1.2
+++ openssl_stream_service.hpp 26 Jul 2006 11:14:12 -0000 1.3
@@ -153,6 +153,7 @@
{
::SSL* ssl;
::BIO* ext_bio;
+ net_buffer recv_buf;
} * impl_type;
// Construct a new stream socket service for the specified io_service.
@@ -180,6 +181,7 @@
impl = new impl_struct;
impl->ssl = ::SSL_new(context.impl());
::SSL_set_mode(impl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
+ ::SSL_set_mode(impl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
::BIO* int_bio = 0;
impl->ext_bio = 0;
::BIO_new_bio_pair(&int_bio, 8192, &impl->ext_bio, 8192);
@@ -211,6 +213,7 @@
&ssl_wrap<mutex_type>::SSL_connect:
&ssl_wrap<mutex_type>::SSL_accept,
next_layer,
+ impl->recv_buf,
impl->ssl,
impl->ext_bio);
op.start();
@@ -241,6 +244,7 @@
&ssl_wrap<mutex_type>::SSL_connect:
&ssl_wrap<mutex_type>::SSL_accept,
next_layer,
+ impl->recv_buf,
impl->ssl,
impl->ext_bio,
boost::bind
@@ -266,6 +270,7 @@
openssl_operation<Stream> op(
&ssl_wrap<mutex_type>::SSL_shutdown,
next_layer,
+ impl->recv_buf,
impl->ssl,
impl->ext_bio);
op.start();
@@ -293,6 +298,7 @@
(
&ssl_wrap<mutex_type>::SSL_shutdown,
next_layer,
+ impl->recv_buf,
impl->ssl,
impl->ext_bio,
boost::bind
@@ -323,6 +329,7 @@
openssl_operation<Stream> op(
send_func,
next_layer,
+ impl->recv_buf,
impl->ssl,
impl->ext_bio
);
@@ -357,6 +364,7 @@
(
send_func,
next_layer,
+ impl->recv_buf,
impl->ssl,
impl->ext_bio,
boost::bind
@@ -386,6 +394,7 @@
boost::asio::buffer_size(*buffers.begin()));
openssl_operation<Stream> op(recv_func,
next_layer,
+ impl->recv_buf,
impl->ssl,
impl->ext_bio
);
@@ -421,6 +430,7 @@
(
recv_func,
next_layer,
+ impl->recv_buf,
impl->ssl,
impl->ext_bio,
boost::bind
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs