$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: chris_at_[hidden]
Date: 2008-01-14 08:29:09
Author: chris_kohlhoff
Date: 2008-01-14 08:29:08 EST (Mon, 14 Jan 2008)
New Revision: 42759
URL: http://svn.boost.org/trac/boost/changeset/42759
Log:
Check for truncation when converting buffer size from size_t to openssl's
int argument.
Try to fix possible thread-safety issues in SSL wrapper.
Text files modified: 
   trunk/boost/asio/ssl/detail/openssl_operation.hpp      |    43 +++++++++++++++++++++-----------        
   trunk/boost/asio/ssl/detail/openssl_stream_service.hpp |    53 ++++++++++++++++++++++++++++++--------- 
   2 files changed, 68 insertions(+), 28 deletions(-)
Modified: trunk/boost/asio/ssl/detail/openssl_operation.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_operation.hpp	(original)
+++ trunk/boost/asio/ssl/detail/openssl_operation.hpp	2008-01-14 08:29:08 EST (Mon, 14 Jan 2008)
@@ -19,6 +19,7 @@
 
 #include <boost/asio/detail/push_options.hpp>
 #include <boost/function.hpp>
+#include <boost/assert.hpp>
 #include <boost/bind.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
@@ -88,10 +89,12 @@
                     net_buffer& recv_buf,
                     SSL* session,
                     BIO* ssl_bio,
-                    user_handler_func  handler
+                    user_handler_func  handler,
+                    boost::asio::io_service::strand& strand
                     )
     : primitive_(primitive)
     , user_handler_(handler)
+    , strand_(&strand)
     , recv_buf_(recv_buf)
     , socket_(socket)
     , ssl_bio_(ssl_bio)
@@ -118,6 +121,7 @@
                     SSL* session,
                     BIO* ssl_bio)
     : primitive_(primitive)
+    , strand_(0)
     , recv_buf_(recv_buf)
     , socket_(socket)
     , ssl_bio_(ssl_bio)
@@ -241,6 +245,7 @@
 
   ssl_primitive_func  primitive_;
   user_handler_func  user_handler_;
+  boost::asio::io_service::strand* strand_;
   write_func  write_;
   read_func  read_;
   int_handler_func handler_;
@@ -304,19 +309,23 @@
       {
         unsigned char *data_start = send_buf_.get_unused_start();
         send_buf_.data_added(len);
-  
+ 
+        BOOST_ASSERT(strand_); 
         boost::asio::async_write
         ( 
           socket_, 
           boost::asio::buffer(data_start, len),
-          boost::bind
+          strand_->wrap
           (
-            &openssl_operation::async_write_handler, 
-            this, 
-            is_operation_done,
-            rc, 
-            boost::asio::placeholders::error, 
-            boost::asio::placeholders::bytes_transferred
+            boost::bind
+            (
+              &openssl_operation::async_write_handler, 
+              this, 
+              is_operation_done,
+              rc, 
+              boost::asio::placeholders::error, 
+              boost::asio::placeholders::bytes_transferred
+            )
           )
         );
                   
@@ -366,17 +375,21 @@
   int do_async_read()
   {
     // Wait for new data
+    BOOST_ASSERT(strand_);
     socket_.async_read_some
     ( 
       boost::asio::buffer(recv_buf_.get_unused_start(),
         recv_buf_.get_unused_len()),
-      boost::bind
+      strand_->wrap
       (
-        &openssl_operation::async_read_handler, 
-        this, 
-        boost::asio::placeholders::error, 
-        boost::asio::placeholders::bytes_transferred
-      ) 
+        boost::bind
+        (
+          &openssl_operation::async_read_handler, 
+          this, 
+          boost::asio::placeholders::error, 
+          boost::asio::placeholders::bytes_transferred
+        )
+      )
     );
     return 0;
   }
Modified: trunk/boost/asio/ssl/detail/openssl_stream_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_stream_service.hpp	(original)
+++ trunk/boost/asio/ssl/detail/openssl_stream_service.hpp	2008-01-14 08:29:08 EST (Mon, 14 Jan 2008)
@@ -20,6 +20,7 @@
 
 #include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
+#include <climits>
 #include <boost/config.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/function.hpp>
@@ -28,6 +29,7 @@
 
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
+#include <boost/asio/strand.hpp>
 #include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/ssl/basic_context.hpp>
 #include <boost/asio/ssl/stream_base.hpp>
@@ -43,6 +45,8 @@
   : public boost::asio::detail::service_base<openssl_stream_service>
 {
 private:
+  enum { max_buffer_size = INT_MAX };
+
   //Base handler for asyncrhonous operations
   template <typename Stream>
   class base_handler
@@ -161,7 +165,8 @@
 
   // Construct a new stream socket service for the specified io_service.
   explicit openssl_stream_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<openssl_stream_service>(io_service)
+    : boost::asio::detail::service_base<openssl_stream_service>(io_service),
+      strand_(io_service)
   {
   }
 
@@ -256,11 +261,12 @@
         local_handler,
         boost::arg<1>(),
         boost::arg<2>()
-      )
+      ),
+      strand_
     );
     local_handler->set_operation(op);
 
-    get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
+    strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
   }
 
   // Shut down SSL on the stream.
@@ -310,11 +316,12 @@
         local_handler, 
         boost::arg<1>(),
         boost::arg<2>()
-      )
+      ),
+      strand_
     );
     local_handler->set_operation(op);
 
-    get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));        
+    strand_.post(boost::bind(&openssl_operation<Stream>::start, op));        
   }
 
   // Write some data to the stream.
@@ -325,10 +332,14 @@
     size_t bytes_transferred = 0;
     try
     {
+      std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin());
+      if (buffer_size > max_buffer_size)
+        buffer_size = max_buffer_size;
+
       boost::function<int (SSL*)> send_func =
         boost::bind(&::SSL_write, boost::arg<1>(),  
             boost::asio::buffer_cast<const void*>(*buffers.begin()),
-            static_cast<int>(boost::asio::buffer_size(*buffers.begin())));
+            static_cast<int>(buffer_size));
       openssl_operation<Stream> op(
         send_func,
         next_layer,
@@ -357,10 +368,14 @@
 
     send_handler* local_handler = new send_handler(handler, get_io_service());
 
+    std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin());
+    if (buffer_size > max_buffer_size)
+      buffer_size = max_buffer_size;
+
     boost::function<int (SSL*)> send_func =
       boost::bind(&::SSL_write, boost::arg<1>(),
           boost::asio::buffer_cast<const void*>(*buffers.begin()),
-          static_cast<int>(boost::asio::buffer_size(*buffers.begin())));
+          static_cast<int>(buffer_size));
 
     openssl_operation<Stream>* op = new openssl_operation<Stream>
     (
@@ -375,11 +390,12 @@
         local_handler, 
         boost::arg<1>(),
         boost::arg<2>()
-      )
+      ),
+      strand_
     );
     local_handler->set_operation(op);
 
-    get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));        
+    strand_.post(boost::bind(&openssl_operation<Stream>::start, op));        
   }
 
   // Read some data from the stream.
@@ -390,10 +406,14 @@
     size_t bytes_transferred = 0;
     try
     {
+      std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin());
+      if (buffer_size > max_buffer_size)
+        buffer_size = max_buffer_size;
+
       boost::function<int (SSL*)> recv_func =
         boost::bind(&::SSL_read, boost::arg<1>(),
             boost::asio::buffer_cast<void*>(*buffers.begin()),
-            boost::asio::buffer_size(*buffers.begin()));
+            static_cast<int>(buffer_size));
       openssl_operation<Stream> op(recv_func,
         next_layer,
         impl->recv_buf,
@@ -422,10 +442,14 @@
 
     recv_handler* local_handler = new recv_handler(handler, get_io_service());
 
+    std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin());
+    if (buffer_size > max_buffer_size)
+      buffer_size = max_buffer_size;
+
     boost::function<int (SSL*)> recv_func =
       boost::bind(&::SSL_read, boost::arg<1>(),
           boost::asio::buffer_cast<void*>(*buffers.begin()),
-          boost::asio::buffer_size(*buffers.begin()));
+          static_cast<int>(buffer_size));
 
     openssl_operation<Stream>* op = new openssl_operation<Stream>
     (
@@ -440,11 +464,12 @@
         local_handler, 
         boost::arg<1>(),
         boost::arg<2>()
-      )
+      ),
+      strand_
     );
     local_handler->set_operation(op);
 
-    get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));        
+    strand_.post(boost::bind(&openssl_operation<Stream>::start, op));        
   }
 
   // Peek at the incoming data on the stream.
@@ -466,6 +491,8 @@
   }
 
 private:  
+  boost::asio::io_service::strand strand_;
+
   typedef boost::asio::detail::mutex mutex_type;
   
   template<typename Mutex>