SSL_shutdown () возвращает -1, а errno равно 0

В моем приложении C ++ я использую OpenSSL для подключения к серверу с использованием неблокирующего BIO. Я занимаюсь разработкой для Mac OS X и iOS.

Первый звонок SSL_shutdown() возвращает 0. Что означает, что я должен позвонить SSL_shutdown() снова:

Могут возникнуть следующие возвращаемые значения:

0 Завершение работы еще не завершено. Вызовите SSL_shutdown () во второй раз, если необходимо выполнить двунаправленное отключение. Вывод SSL_get_error может вводить в заблуждение, так как ошибочный SSL_ERROR_SYSCALL может быть помечен, даже если не было ошибок.

<0
Завершение работы не было успешным, потому что произошла неустранимая ошибка на уровне протокола или произошла ошибка соединения. Это также может произойти, если необходимо продолжить действие для неблокирующих BIO. Вызовите SSL_get_error с возвращаемым значением ret, чтобы выяснить причину.

https://www.openssl.org/docs/ssl/SSL_shutdown.html

Пока что бог. Проблема возникает при втором вызове SSL_shutdown(), Это возвращает -1, что означает, что произошла ошибка (см. Выше). Теперь, если я проверю с SSL_get_error() Я получаю ошибку SSL_ERROR_SYSCALL что в свою очередь означает, что произошла системная ошибка. Но теперь подвох. Если я проверю errno возвращает 0 -> неизвестная ошибка. То, что я до сих пор читал об этой проблеме, это то, что это может означать, что сервер просто «завис», но, честно говоря, меня это не удовлетворяет.

Вот моя реализация выключения:

int result = 0;
int shutdownResult;
while ((shutdownResult = SSL_shutdown(sslHandle)) != 1) { //close connection 1 means everything is shut down ok
if (shutdownResult == 0) { //we are supposed to call shutdown again
continue;
} else if (SSL_get_error(sslHandle, shutdownResult) == SSL_ERROR_WANT_READ) {
[...] //omitted want read code, in this case the application never reaches this point
} else if (SSL_get_error(sslHandle, shutdownResult) == SSL_ERROR_WANT_WRITE) {
[...] //omitted want write code, in this case the application never reaches this point
} else {
logError("Error in ssl shutdown, ssl error: " + std::to_string(SSL_get_error(sslHandle, shutdownResult)) + ", system error: " + std::string(strerror(errno))); //something went wrong
break;
}
}

Когда запускаются журналы приложений:

ОШИБКА :: Ошибка в завершении работы ssl, ошибка ssl: 5, системная ошибка: неопределенная ошибка: 0

Так вот, просто сервер закрывает соединение или есть более важная проблема? Я просто упускаю что-то действительно очевидное?

2

Решение

Полное отключение SSL состоит из двух частей:

  • отправка однорангового оповещения «закрыть уведомление»
  • получение оповещения «закрыть уведомление» от партнера

Первый SSL_shutdown возвратил 0, что означает, что он отправил «уведомление о закрытии» одноранговому узлу, но еще ничего не получил обратно. Второй вызов SSL_shutdown завершается неудачно, поскольку одноранговый узел не выполнил надлежащее отключение SSL и не отправил обратно уведомление о закрытии, а просто закрыл базовое TCP-соединение.

Такое поведение на самом деле очень распространено, и вы можете просто игнорировать ошибку. Не имеет большого значения, должно ли базовое TCP-соединение быть закрыто в любом случае. Но правильное отключение SSL обычно требуется, когда вы хотите продолжить в простом тексте на том же TCP-соединении, как это необходимо для команды CCC в соединениях FTPS (но даже там, где различные реализации не справляются с этим делом должным образом).

3

Другие решения


По вопросам рекламы [email protected]