Как управлять очередью ошибок в openssl (SSL_get_error и ERR_get_error)

В OpenSSl страницы руководства для большинства вызовов SSL_ * указывают на ошибку, возвращая значение <= 0 и предлагая вызывать SSL_get_error(), чтобы получить расширенную ошибку.

Но в man-страницах для этих вызовов, а также для других вызовов библиотеки OpenSSL существуют неопределенные ссылки на использование "очереди ошибок" в OpenSSL. Таков случай на странице руководства для SSL_get_error:

   The current thread error queue must be empty before the TLS/SSL I/O
   operation is attempted, or  SSL_get_error() will not work reliably.

И на той же самой странице man, описание для SSL_ERROR_SSL говорит следующее:

   SSL_ERROR_SSL
       A failure in the SSL library occurred, usually a protocol error.
       The OpenSSL error queue contains more information on the error.

Этот тип подразумевает, что в очереди ошибок стоит прочитать. И неспособность прочитать это делает последующий вызов SSL_get_error ненадежным. Предположительно, вызов сделать ERR_get_error.

Я планирую использовать неблокирующие сокеты в моем коде. Поэтому важно, чтобы я уверенно обнаружил, когда условие ошибки SSL_ERROR_WANT_READ или SSL_ERROR_WANT_WRITE, поэтому я могу поместить сокет в правильный режим опроса.

Итак, мои вопросы таковы:

  • Вызывает ли SSL_get_error() вызов ERR_get_error() для меня? Или мне нужно использовать оба?

  • Должен ли я звонить ERR_clear_error перед каждым вызовом библиотеки OpenSSL?

  • Возможно ли, что после завершения вызова библиотеки OpenSSL может оказаться более одной ошибки в очереди? Следовательно, существуют ли ситуации, когда первая ошибка в очереди более актуальна, чем последняя ошибка?

Ответ 1

  • SSL_get_error не вызывает ERR_get_error. Поэтому, если вы просто вызываете SSL_get_error, ошибка остается в очереди.
  • Вы должны вызвать ERR_clear_error до ЛЮБОГО SSL-вызова (SSL_read, SSL_write и т.д.), за которым следует SSL_get_error, иначе вы можете прочитать старую ошибку, которая произошла ранее в текущем потоке.