SSL_shutdown()返回-1,errno为0

时间:2015-07-24 14:24:52

标签: 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。

     

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

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

到目前为止,上帝。第二次调用SSL_shutdown()时会出现此问题。返回-1表示发生了错误(参见上文)。现在,如果我查看SSL_get_error(),我会收到错误SSL_ERROR_SYSCALL,而错误errno反过来应该表示发生了系统错误。但现在抓住了。如果我检查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; } } 它返回0 - >未知错误。到目前为止我所读到的关于这个问题的内容是,它可能意味着服务器只是挂断了#34;但说实话,这并不能让我满意。

这是我关闭的实现:

var day = 10;
var month = 04;
var year = 2015;

var dateUtc = Date.UTC(year, month - 1, day + 1, 0, 0, 0);
> 1428710400000

var toDate = new Date(dateUtc);
> Fri Apr 10 2015 21:00:00 GMT-0300 (Hora oficial do Brasil)

运行应用程序日志时:

  

ERROR :: ssl shutdown错误,ssl错误:5,系统错误:未定义错误:0

这里只是服务器关闭连接还是存在更严重的问题?我只是遗漏了一些非常明显的东西吗?

1 个答案:

答案 0 :(得分:5)

完整的SSL关闭包括两部分:

  • 发送'关闭通知'提醒同伴
  • 收到'关闭通知'来自同行的警报

第一个SSL_shutdown返回0表示它确实发送了'关闭通知'对同行但尚未收到任何回复。 SSL_shutdown的第二次调用失败,因为对等方未执行正确的SSL关闭并发送关闭通知'返回,而只是关闭底层的TCP连接。

这种行为实际上非常常见,您通常可以忽略该错误。如果底层TCP连接无论如何都应该关闭并不重要。但是,如果要在同一TCP连接上继续使用纯文本,通常需要正确的SSL关闭,就像FTPS连接中的CCC命令所需要的那样(但即使有各种实现也无法正确处理这种情况)。