SSL_read因SSL_ERROR_SYSCALL错误而失败

pav*_*van 13 ssl openssl

我们已经使用openssl实现了tls.从服务器下载较大的数据SSL_ERROR_SYSCALL后收到一些数据后收到错误.对于较小的文件,我没有收到此错误,能够下载没有任何错误.对于较大的文件,ERR_get_error()显示为零.

我们正在使用linux和c ++框架.如何找到失败的原因?失败的原因是什么?请提供您的建议.

Jay*_*Jay 10

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错误(对于Unix系统上的套接字I/O,请参阅errno以获取详细信息).

  • 谢谢,ERR_get_error()返回0,所以在这种情况下什么是协议viloation?可能是什么问题? (2认同)
  • 我收到SSL_ERROR_SYSCALL错误后我正在使用Linux环境我已经打印了errorno并且它显示零作为errorno. (2认同)

Sam*_*son 10

我发现问题是我公司的防火墙阻止了请求。回家应该可以了


won*_*ice 5

如果您查看源代码,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();
Run Code Online (Sandbox Code Playgroud)

n为 0 时,errSSL_ERROR_SYSCALL只是因为。但是st仍然是 0 表示没有真正的错误。SSL_read刚刚返回 0,因为 0 个字节被写入buf.

但是,请在调用后查找errno/WSAGetLastError()值以获取更多详细信息。


小智 5

检查您是否以缓冲区大小 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);
Run Code Online (Sandbox Code Playgroud)

如果nBuf == bufSize调用 SSL_read() 时缓冲区大小为 0,则会导致 SSL_ERROR_SYSCALL 且 errno == 0。

更改 doReadFd 检查将避免此问题:

int doReadFd = FD_ISSET(fd, &rfds) || nBuf < bufSize && SSL_pending(ssl);
Run Code Online (Sandbox Code Playgroud)