повышение asio ssl не работает должным образом при использовании с null_buffers

#c #sockets #ssl #boost #boost-asio

#c #сокеты #ssl #повышение #поддержка asio

Вопрос:

У нас есть сервер boost asio ssl, который считывает данные с клиента. У нас есть требование выполнять фактическое чтение данных в нашем собственном коде, в отличие от прямого чтения подпрограммами boost async_read_some() путем передачи в него буфера. Следовательно, мы передаем null_buffers() в async_read_some() и позже выполняем фактическое чтение данных с помощью socket-> read_some() API. Все наши сокеты всегда неблокируются для чтения и записи. http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/overview/core/reactor.html

Это отлично работает с обычным потоковым сокетом (tcp). Однако с ssl-сокетом он работает некорректно.

  1. обратный вызов read постоянно вызывается, даже когда нет доступных данных. Это навсегда загружает процессор.. При вызове ssl_socket->read_some() мы получаем 0 байт. код ошибки установлен на 11 (ресурс недоступен)
  2. При обратном вызове read мы всегда запускаем последующие чтения снова, вызывая socket-> async_read_some(null_buffers(), …)

Если мы не выполним (2), то будут получены не все данные, когда необходимо прочитать большие объемы данных. Если мы выполним (2), все данные будут получены правильно (по многим обратным вызовам чтения), но обратный вызов чтения продолжает вызываться даже после того, как все данные были прочитаны и когда больше нет данных для чтения…

Чтобы проверить то же самое, я использовал пример кода сервера и клиента boost ssl и заметил аналогичное поведение при следующем изменении кода сервераhttp://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/example/ssl/server.cpp обратный вызов handle_read() постоянно вызывается навсегда… Если мы используем обычный сокет boost stream (tcp) (не boost ssl), то мы не видим таких обратных вызовов, когда данные недоступны для чтения.

Мы видим такое же поведение даже с последней версией boost и ssl-кода. Хорошо ли протестирован и поддерживается ли режим чтения / записи null_buffers () с ssl-сокетом? Я нигде не смог найти много документации для этого..

Может кто-нибудь, пожалуйста, помочь. Большое вам спасибо!

 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(amp;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(amp;session::handle_write, this,
         boost::asio::placeholders::error));
 
       // Post for read again..
       socket_.async_read_some(boost::asio::null_buffers(),
                               boost::bind(amp;session::handle_read, this,
                               boost::asio::placeholders::error,
                               boost::asio::placeholders::bytes_transferred));
  

Комментарии:

1. Еще одно замечание: если вместо этого я прочитаю в базовом tcp-сокете socket_->lowest_layer().async_read_some(boost::asio::null_buffers(), …), то постоянные ненужные уведомления о чтении не будут получать. Однако, когда необходимо получить большие объемы данных, принимаются не все данные. Где-то застрял некоторый объем данных, возможно, в библиотеке ssl.

2. Я столкнулся с этой же проблемой 5 лет спустя: ( github.com/chriskohlhoff/asio/issues/1015