Boost Asio SSL не может получать данные 2 раза (1 раз ОК) - PullRequest
0 голосов
/ 05 июня 2018

Я работаю над Boost Asio и Boost Beast для простого сервера RESTful.Для нормальных сокетов HTTP и TCP это работает отлично.Я поставил его под нагрузочный тест с JMeter, все работает нормально.

Я попытался добавить сокет SSL.Я установил ssl :: context и также вызвал async_handshake () - дополнительные шаги для SSL по сравнению с обычным сокетом.Работает только в первый раз.Клиент может соединиться со мной (сервером), и я также могу получить данные через 'boost :: beast :: http :: async_read ()'.

Поскольку это RESTful, поэтому соединение будет разорвано послезапрос и ответ.Я вызываю «SSL_Socket.shutdown ()», а затем «SSL_Socket.lowest_layer (). Close ()», чтобы закрыть сокет SSL.

При следующем входящем запросе клиент может соединиться со мной (сервер).Я вызвал «SSL_Socket.async_handshake ()», а затем последовал «boost :: beast :: http :: async_read ()».Но на этот раз я не смог получить никаких данных.Но соединение успешно установлено.

Кто-нибудь знает, что я пропустил?

Большое спасибо!

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

У меня была похожая проблема, во второй раз мой асинхронный прием всегда завершался неудачно с неинициализированным идентификатором сеанса.

Я решил эту проблему, вызвав SSL_CTX_set_session_id_context в контексте или установив режим кэширования контекста с помощью SSL_SESS_CACHE_OFF и SSL_OP_NO_TICKET в параметрах контекста.

Это мои центы к чьей-то проблеме.

0 голосов
/ 12 декабря 2018

Если вы хотите повторно использовать экземпляр потока, вам нужно манипулировать SSL_Socket.native_handle() с помощью функции openssl lib.После выключения ssl, используйте SSL_clear() перед началом нового рукопожатия ssl.

прочитайте (обратите внимание на предупреждения) ссылка для подробностей

SSL_clear () сбрасывает объект SSL, чтобы разрешить другое соединение.Однако операция сброса сохраняет некоторые настройки последних сеансов (некоторые из этих настроек были сделаны автоматически во время последнего рукопожатия) .........

ПРЕДУПРЕЖДЕНИЯ

SSL_clear () сбрасывает объект SSL, чтобы разрешить другое соединение.Однако операция сброса сохраняет некоторые настройки последних сеансов (некоторые из этих настроек были сделаны автоматически во время последнего рукопожатия).Это имеет смысл только для нового соединения с точно таким же одноранговым узлом, который разделяет эти параметры, и может потерпеть неудачу, если этот одноранговый узел изменяет свои настройки между соединениями.Используйте последовательность SSL_get_session (3);SSL_new (3);SSL_set_session (3);SSL_free (3) вместо этого, чтобы избежать таких сбоев (или просто SSL_free (3); SSL_new (3), если повторное использование сеанса нежелательно).

Что касается проблемы с отключением ssl, link Объясните, как работает boost asio ssl shutdown.

В Boost.Asio операция shutdown () считается завершенной в случае ошибки или если участник отправил и получил сообщение close_notify.

Если вы посмотрите на boostИсходный код .asio (1.68) boost \ asio \ ssl \ detail \ impl \ engine.ipp показывает, как boost.asio выполняет ssl-выключение и stream_truncated происходит, когда есть данные, которые нужно прочитать, или ssl-завершение ожидается изПэр не получил .

int engine::do_shutdown(void*, std::size_t)
{
  int result = ::SSL_shutdown(ssl_);
  if (result == 0)
    result = ::SSL_shutdown(ssl_);
  return result; 
} 
const boost::system::error_code& engine::map_error_code(
    boost::system::error_code& ec) const
......
// If there's data yet to be read, it's an error.
if (BIO_wpending(ext_bio_))
{
    ec = boost::asio::ssl::error::stream_truncated;
    return ec;
}
......
// Otherwise, the peer should have negotiated a proper shutdown.
if ((::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN) == 0)
{
    ec = boost::asio::ssl::error::stream_truncated;
}
}

Также вы можете увидеть, что процедура завершения работы boost.asio ssl может дважды вызвать openssl SSL_shutdown(), если вначале вернет 0, документ openssl разрешит это, но вызов по совету SSL_read() для двунаправленного отключения, если сначала SSL_shutdown() возвращает 0.

Считайте ссылку для подробностей.

0 голосов
/ 06 июня 2018

Мне удалось решить проблему, переключив сокет «ssl :: stream» на «boost :: option», а затем добавил «SSL_Socket.emplace (io_context, oSSLContext)» каждый раз, когда сокет выключается и закрывается.

Большой кредит для sehe на ' Невозможно реализовать boost :: asio :: ssl :: streamпереподключиться к серверу '.Его утверждение « самое чистое решение - не использовать повторно объекты потока / сокета »!Сэкономьте мое время.

Спасибо.

...