正确处理 SSL_shutdown
Handling SSL_shutdown correctly
SSL_shutdown
上的 OpenSSL 文档指出:
It is therefore recommended, to check the return value of SSL_shutdown()
and call SSL_shutdown()
again, if the bidirectional shutdown is not yet complete (return value of the first call is 0).
https://www.openssl.org/docs/ssl/SSL_shutdown.html
我在下面有一个代码片段,我在其中检查 SSL_shutdown
中的 return 值 0 并再次调用它,我一直在使用它。我的问题是,在第二次调用时忽略 SSL_shutdown
的 return 值是否可以,或者我们应该继续重试 SSL_shutdown
直到 1(双向关闭完成)为 return编辑
int r = SSL_shutdown(ssl);
//error handling here if r < 0
if(!r)
{
shutdown(fd,1);
SSL_shutdown(ssl); //how should I handle return value and error handling here is it required??
}
SSL_free(ssl);
SSLMap.erase(fd);
shutdown(fd,2);
close(fd);
openssl
有点黑暗艺术。
首先,您引用的页面 HTML 严重修改了 return 值。这是手册页 实际上 所说的内容:
RETURN VALUES
The following return values can occur:
0 The shutdown is not yet finished. Call SSL_shutdown() for a second
time, if a bidirectional shutdown shall be performed. The output
of SSL_get_error(3) may be misleading, as an erroneous
SSL_ERROR_SYSCALL may be flagged even though no error occurred.
1 The shutdown was successfully completed. The "close notify" alert
was sent and the peer's "close notify" alert was received.
-1 The shutdown was not successful because a fatal error occurred
either at the protocol level or a connection failure occurred. It
can also occur if action is need to continue the operation for non-
blocking BIOs. Call SSL_get_error(3) with the return value ret to
find out the reason.
如果你有阻塞 BIO,事情就相对简单了。第一次调用为 0 意味着如果您想要完全双向关闭,则需要再次调用 SSL_shutdown
。基本上这意味着您发送了 close_notify 警报但还没有回复)。 1 表示您之前收到了来自其他对等方的 close_notify 警报,并且您已完全完成。 -1 表示不可恢复的错误。在第二次调用时(只有当你返回 0 时你才会这样做),然后双向关闭被启动(即现在从另一端等待他们向你发送他们的 "close_notify" 警报)。逻辑决定你不能再返回 0(因为它是一个阻塞 BIO,并且将完成第一步)。 -1 表示错误,1 表示完成成功。
如果你有非阻塞 BIO,相同的 "possibly 0 then 1" return 值适用,除了你需要经历整个 SSL_ERROR_WANT_READ
和 SSL_ERROR_WANT_WRITE
也很冗长,即:
If the underlying BIO is non-blocking, SSL_shutdown() will also return
when the underlying BIO could not satisfy the needs of SSL_shutdown()
to continue the handshake. In this case a call to SSL_get_error() with
the return value of SSL_shutdown() will yield SSL_ERROR_WANT_READ or
SSL_ERROR_WANT_WRITE. The calling process then must repeat the call
after taking appropriate action to satisfy the needs of SSL_shutdown().
The action depends on the underlying BIO. When using a non-blocking
socket, nothing is to be done, but select() can be used to check for
the required condition. When using a buffering BIO, like a BIO pair,
data must be written into or retrieved out of the BIO before being able
to continue.
所以你有两个层次的重复。您调用 SSL_shutdown
'first' 时间,但如果您在以正常方式绕过 select()
循环后得到 SSL_ERROR_WANT_READ
或 SSL_ERROR_WANT_WRITE
,则重复,并且只计算 'first' SSL_shutdown
如果您收到非 SSL_ERROR_WANT_
错误代码(在这种情况下失败),或者您收到 0
或 1
return.如果你得到 1
return,你就完成了。如果你得到 0
return,并且你想要双向关闭,那么你必须进行第二次调用,你将需要再次检查 SSL_ERROR_WANT_READ
或 SSL_ERROR_WANT_WRITE
并重试 select;那不应该 return 1
,但可能 return 0 或错误。
不简单。
来自 docs 的更多注释:在调用 SSL_shutdown
并第一次返回“0”后,您可以选择调用 SSL_read
而不是 SSL_shutdown
(以防对等方仍在该 SSL 套接字上向您发送任何数据),而且,我猜,"hope" 他们最终会从他们这边向您发送一条关闭消息,以刷新管道。
此外,如果您计划在关闭完成后关闭套接字 "anyway",您可以完全跳过对 SSL_shutdown
的第二次调用(“0 然后 1”的“1”)和继续并关闭套接字,内核应该注意丢弃 "now ignored" close_notify 警报,大概他们应该发送...
SSL_shutdown
上的 OpenSSL 文档指出:
It is therefore recommended, to check the return value of
SSL_shutdown()
and callSSL_shutdown()
again, if the bidirectional shutdown is not yet complete (return value of the first call is 0).
https://www.openssl.org/docs/ssl/SSL_shutdown.html
我在下面有一个代码片段,我在其中检查 SSL_shutdown
中的 return 值 0 并再次调用它,我一直在使用它。我的问题是,在第二次调用时忽略 SSL_shutdown
的 return 值是否可以,或者我们应该继续重试 SSL_shutdown
直到 1(双向关闭完成)为 return编辑
int r = SSL_shutdown(ssl);
//error handling here if r < 0
if(!r)
{
shutdown(fd,1);
SSL_shutdown(ssl); //how should I handle return value and error handling here is it required??
}
SSL_free(ssl);
SSLMap.erase(fd);
shutdown(fd,2);
close(fd);
openssl
有点黑暗艺术。
首先,您引用的页面 HTML 严重修改了 return 值。这是手册页 实际上 所说的内容:
RETURN VALUES
The following return values can occur:
0 The shutdown is not yet finished. Call SSL_shutdown() for a second
time, if a bidirectional shutdown shall be performed. The output
of SSL_get_error(3) may be misleading, as an erroneous
SSL_ERROR_SYSCALL may be flagged even though no error occurred.
1 The shutdown was successfully completed. The "close notify" alert
was sent and the peer's "close notify" alert was received.
-1 The shutdown was not successful because a fatal error occurred
either at the protocol level or a connection failure occurred. It
can also occur if action is need to continue the operation for non-
blocking BIOs. Call SSL_get_error(3) with the return value ret to
find out the reason.
如果你有阻塞 BIO,事情就相对简单了。第一次调用为 0 意味着如果您想要完全双向关闭,则需要再次调用 SSL_shutdown
。基本上这意味着您发送了 close_notify 警报但还没有回复)。 1 表示您之前收到了来自其他对等方的 close_notify 警报,并且您已完全完成。 -1 表示不可恢复的错误。在第二次调用时(只有当你返回 0 时你才会这样做),然后双向关闭被启动(即现在从另一端等待他们向你发送他们的 "close_notify" 警报)。逻辑决定你不能再返回 0(因为它是一个阻塞 BIO,并且将完成第一步)。 -1 表示错误,1 表示完成成功。
如果你有非阻塞 BIO,相同的 "possibly 0 then 1" return 值适用,除了你需要经历整个 SSL_ERROR_WANT_READ
和 SSL_ERROR_WANT_WRITE
也很冗长,即:
If the underlying BIO is non-blocking, SSL_shutdown() will also return
when the underlying BIO could not satisfy the needs of SSL_shutdown()
to continue the handshake. In this case a call to SSL_get_error() with
the return value of SSL_shutdown() will yield SSL_ERROR_WANT_READ or
SSL_ERROR_WANT_WRITE. The calling process then must repeat the call
after taking appropriate action to satisfy the needs of SSL_shutdown().
The action depends on the underlying BIO. When using a non-blocking
socket, nothing is to be done, but select() can be used to check for
the required condition. When using a buffering BIO, like a BIO pair,
data must be written into or retrieved out of the BIO before being able
to continue.
所以你有两个层次的重复。您调用 SSL_shutdown
'first' 时间,但如果您在以正常方式绕过 select()
循环后得到 SSL_ERROR_WANT_READ
或 SSL_ERROR_WANT_WRITE
,则重复,并且只计算 'first' SSL_shutdown
如果您收到非 SSL_ERROR_WANT_
错误代码(在这种情况下失败),或者您收到 0
或 1
return.如果你得到 1
return,你就完成了。如果你得到 0
return,并且你想要双向关闭,那么你必须进行第二次调用,你将需要再次检查 SSL_ERROR_WANT_READ
或 SSL_ERROR_WANT_WRITE
并重试 select;那不应该 return 1
,但可能 return 0 或错误。
不简单。
来自 docs 的更多注释:在调用 SSL_shutdown
并第一次返回“0”后,您可以选择调用 SSL_read
而不是 SSL_shutdown
(以防对等方仍在该 SSL 套接字上向您发送任何数据),而且,我猜,"hope" 他们最终会从他们这边向您发送一条关闭消息,以刷新管道。
此外,如果您计划在关闭完成后关闭套接字 "anyway",您可以完全跳过对 SSL_shutdown
的第二次调用(“0 然后 1”的“1”)和继续并关闭套接字,内核应该注意丢弃 "now ignored" close_notify 警报,大概他们应该发送...