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

Reply via email to