我们已经使用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以获取详细信息).
如果您查看源代码,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 时,err将SSL_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)
| 归档时间: |
|
| 查看次数: |
64749 次 |
| 最近记录: |