我们已经使用openssl实现了tls。从服务器下载较大的数据时收到一些数据后出现SSL_ERROR_SYSCALL
错误。对于较小的文件,我没有收到此错误,能够下载没有任何错误。对于较大的文件,ERR_get_error()显示为零。
我们正在使用linux和c ++框架。如何找到失败的原因?失败的原因是什么?请提供你的建议。
答案 0 :(得分:8)
SSL_ERROR_SYSCALL表示底层I / O发生了一些问题(在这种情况下应该是TCP)。因此,您可以尝试使用errno进行检查。
OpenSSL帮助说:
SSL_ERROR_SYSCALL
发生了一些I / O错误。 OpenSSL错误队列可能 包含有关错误的更多信息。如果错误队列为空 (即ERR_get_error()返回0),ret可用于查找更多信息 关于错误:如果ret == 0,则观察到EOF违反了 协议。如果ret == -1,则底层BIO报告了I / O错误(for Unix系统上的socket I / O,详情请咨询errno。
答案 1 :(得分:4)
检查是否使用缓冲区大小为0调用SSL_read()。我使用SSL_pending()犯了以下错误:
int waitForReadFd = nBuf < bufSize;
if (waitForReadFd)
FD_SET(fd, &rfds);
// ...
// select
int doReadFd = FD_ISSET(fd, &rfds) || SSL_pending(ssl);
if (doReadFd)
n = SSL_read(ssl, buf, bufSize - nBuf);
如果调用nBuf == bufSize
SSL_read(),缓冲区大小为0,则导致SSL_ERROR_SYSCALL与errno == 0。
更改doReadFd检查可以避免此问题:
int doReadFd = FD_ISSET(fd, &rfds) || nBuf < bufSize && SSL_pending(ssl);
答案 2 :(得分:3)
如果您查看SSL_get_error()
的源代码,您会看到,只要它不确定究竟发生了什么,它就会返回SSL_ERROR_SYSCALL
。它基本上是“未知”案例的默认返回码。
例如,在我的情况下(使用BIO执行非阻塞IO):
int buf;
const int n = SSL_read(ssl, &buf, 0);
const int err = SSL_get_error(ssl, n);
const int st = ERR_get_error();
当n
为0时,err
仅为SSL_ERROR_SYSCALL
因为。但是st
仍然为0表示没有真正的错误。 SSL_read
刚刚返回0,因为0个字节被写入buf
。
但是,请在通话后查看errno
/ WSAGetLastError()
值,了解更多详情。
答案 3 :(得分:0)
问题是由网络连接被切断和服务器重新设置引起的。
在下载数据之前,请确保连接正常。
使用vagrant时可以看到类似的问题。
答案 4 :(得分:0)
我发现问题出在我的公司防火墙阻止了请求。回家就可以了
答案 5 :(得分:0)
我们在Go应用程序中遇到了此错误。我们正在使用第三方库从Go连接到基础的openssl库。在读取数据时,第三方库正在将要读取的缓冲区/数据的长度转换为32位的C.int。对于大于等于2GB的大数据,这会导致溢出,并且会将负值传递给C.SSL_read函数。 在这种情况下,它会引发SSL_ERROR_SYSCALL错误。