我正在使用OpenSSL版本1.1.0f加密我的客户端和我没有任何访问权限的中继服务器之间的连接。有时客户端的连接会因客户端的readLine故障而突然终止。
以下是错误代码:
readLine:readString返回-1,错误消息 - 错误:00000005:lib(0):func(0):DH lib
我确实搜索了这种错误代码的适当原因,每个人(示例this线程)都表示在建立连接期间似乎存在Diffie-Helman密钥交换的问题。但是连接几分钟都很好(有时可能甚至没有发生,并且可能在连接成功2到3分钟后经常发生一次),直到它突然终止。
以下是我所拥有的日志中的一些错误
SSL_read失败,错误 - 5,字节收到-1,错误字符串错误:00000005:lib(0):func(0):DH lib,wsaError 0
SSL错误 - 5:错误:FFFFFFFF:lib(255):func(4095):reason(4095)
以下是来自SSL客户端的套接字读取代码
if ((isSecureMode() == true) && (lpSSL != NULL))
{
bytesReceived = SSL_read(lpSSL, receiveBuf, bufferSize) ;
if ((bytesReceived <= 0))
{
int sslErrorCode = lpSSL ? SSL_get_error(lpSSL, bytesReceived) : -1;
char sslErrorString[MAX_ERROR_MSG_LEN] = {'\0'};
ERR_error_string(sslErrorCode, sslErrorString);
setLastError(sslErrorCode, std::string(sslErrorString));
int wsaError = WSAGetLastError();
if(isShutdownInitiated == false)
{
if (Logger)
{
Logger->log(LOG_WARNING, "receiveString - SSL_read failed with error - %d, bytes received %d, error string %s, wsaError %d", sslErrorCode, bytesReceived, std::string(sslErrorString), wsaError);
}
// Always return -1 incase of failure
bytesReceived = -1;
}
else
{
if (Logger)
{
Logger->log(LOG_WARNING, "receiveString - Socket was Shutdown, SSL_read failed with error - %d, bytes received %d, error string %s , wsaError %d", sslErrorCode, bytesReceived, std::string(sslErrorString), wsaError);
}
setLastError(ERROR_ALREADY_SHUTDOWN);
bytesReceived = -1;
}
}
}
我不是OpenSSL的专家,我怀疑问题可能与服务器有关,但除了上述情况之外,没有任何错误消息可以证明它。
我做了很多分析并花了几周没有任何改进。
更新 在分析错误消息时,错误代码SSL_ERROR_SYSCALL以及wsa error_code 10054表示连接已被远程方终止。在服务器日志上写入相同的错误消息。这导致怀疑连接被中间设备(可能是驻留在客户端和服务器之间的路由器)重置为this线程。我正在尝试进一步分析并解决问题。
更新2:我还发现问题有时会发生在某些网络上。它在很少的网络上运行得很好。上面提到的线程也说明了这一点。
更新3:我已经找到了连接终止的原因之一,错误10054实际上是由于防火墙和现在已经解决的网络。
调试readline失败并显示错误
SSL_read失败,错误 - 5,字节收到-1,错误字符串 错误:00000005:lib(0):func(0):DH lib,wsaError 0
任何帮助都将不胜感激。
答案 0 :(得分:5)
SSL_get_error
的返回值不应传递给ERR_error_string
。 sslErrorCode
中的值5可能是SSL_ERROR_SYSCALL
。
您应该使用ERR_get_error
遍历本地线程错误队列以查找失败的原因,并且还应该在调用SSL_read
之前清空错误队列。
(所有这些也包含在https://stackoverflow.com/a/37980911/1478356)
中在SSL_read
(Windows上为-1
)时,还有许多SSL_ERROR_SYSCALL
返回SSL_get_error
(errno = 0
WSAGetLastError
}的报告当底层连接收到EOF时,错误队列为空。有关详细讨论,请参阅https://github.com/openssl/openssl/issues/1903;特别是this comment解释了如何手动检查EOF。
有人声称这已在1.1.0d中修复,但在1.1.0f中还有其他报告存在此错误(例如https://redmine.lighttpd.net/issues/2784)。