boost asio ssl not working as expected when used with null_buffers

时间:2016-10-20 20:08:16

标签: c++ sockets ssl boost boost-asio

We have boost asio ssl server that reads data from a client. We have a requirement to perform actual read of the data in our own code as oppose to read directly by boost async_read_some() routines by passing a buffer to it. Hence we pass null_buffers() to async_read_some() and later do the actual data read using socket->read_some() API. Our sockets are all always non-blocking for read and write. http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/overview/core/reactor.html

This works fine with normal stream (tcp) socket. However, with ssl socket, it is not working correctly.

  1. read callback constantly gets called even when there is no data available. This churns the cpu for ever.. When ssl_socket->read_some() is called, we get 0 bytes. error code is set to 11 (Resource unavailable)
  2. In the read callback, we always trigger future reads again, by calling socket->async_read_some(null_buffers(), ...)

If we don't do (2), then not all data is received, when large amounts of data needs to be read. If we do (2), all data is correctly received (over many read callbacks), but the read callback keeps getting called even after all data has been read and when there is no more data to read...

To verify the same, I used the example boost ssl server and client code and notice a similar behavior with following change to the server code http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/example/ssl/server.cpp handle_read() call back constantly gets called for ever... If we use normal boost stream (tcp) socket (not boost ssl), then we do not see such callbacks when no data is available to read.

We see the same behavior even with the latest boost and ssl code as well. Is null_buffers() read/write mode with ssl socket well tested and supported ? I could not find much documentation for this any where..

Can some one please help. Thank you so much!

diff --git a/server.cc b/server.cc
index 3f2b028..bfd65c7 100644
--- a/server.cc
+++ b/server.cc
@@ -40,7 +40,10 @@ public:
   {
     if (!error)
     {
-      socket_.async_read_some(boost::asio::buffer(data_, max_length),
+      socket().non_blocking(true);
+
+      // socket_.async_read_some(boost::asio::buffer(data_, max_length),
+      socket_.async_read_some(boost::asio::null_buffers(),
           boost::bind(&session::handle_read, this,
           boost::asio::placeholders::error,
           boost::asio::placeholders::bytes_transferred));
@@ -56,6 +59,8 @@ public:
   {
     if (!error)
     {
+      boost::system::error_code err;
+      bytes_transferred = socket_.read_some(boost::asio::mutable_buffers_1(boost::asio::buffer(data_, max_length)), err);
       boost::asio::async_write(socket_,
           boost::asio::buffer(data_, bytes_transferred),
           boost::bind(&session::handle_write, this,
         boost::asio::placeholders::error));
+
+      // Post for read again..
+      socket_.async_read_some(boost::asio::null_buffers(),
+                              boost::bind(&session::handle_read, this,
+                              boost::asio::placeholders::error,
+                              boost::asio::placeholders::bytes_transferred));

0 个答案:

没有答案