SSL_shutdown()返回-1,而errno为0

Arn*_*her 2 c++ ssl openssl nonblocking system-error

在我的C ++应用程序中,我使用OpenSSL使用非阻塞BIO连接到服务器。我正在为Mac OS X和iOS开发。

第一次调用SSL_shutdown()返回0。这意味着我必须SSL_shutdown()再次调用:

可能会出现以下返回值:

0关闭尚未完成。如果将执行双向关闭,则第二次调用SSL_shutdown()。SSL_get_error的输出可能会产生误导,因为即使没有发生错误,也可能会标记错误的SSL_ERROR_SYSCALL。

<0关闭不成功,因为在协议级别发生了致命错误或发生了连接故障。如果需要采取措施继续非阻塞BIO的操作,也会发生这种情况。使用返回值ret调用SSL_get_error找出原因。

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;
  }
} 
Run Code Online (Sandbox Code Playgroud)

运行应用程序日志时:

错误:: ssl关闭错误,ssl错误:5,系统错误:未定义错误:0

那么,这是仅服务器关闭连接还是还有一个更严重的问题?我只是错过了一些明显的东西吗?

Ste*_*ich 5

完全SSL关闭包含两个部分:

  • 发送“关闭通知”警报给对等方
  • 接收来自对等方的“关闭通知”警报

第一个SSL_shutdown返回0,这意味着它确实向对等体发送了“ close notify”,但是还没有收到任何东西。SSL_shutdown的第二次调用失败,因为对等方未进行适当的SSL关闭并发送回“ close notify”,而只是关闭了基础TCP连接。

这种行为实际上非常普遍,您通常可以忽略该错误。无论如何都应关闭基础TCP连接并不重要。但是,当您想在同一TCP连接上以纯文本格式继续时,通常需要适当的SSL关闭,例如FTPS连接中的CCC命令所需要的(但是即使有各种实现也无法正确处理这种情况)。