如何管理 openssl 中的错误队列(SSL_get_error 和 ERR_get_error)
Posted
技术标签:
【中文标题】如何管理 openssl 中的错误队列(SSL_get_error 和 ERR_get_error)【英文标题】:How to manage the error queue in openssl (SSL_get_error and ERR_get_error) 【发布时间】:2013-08-13 07:12:41 【问题描述】:在 OpenSSl 中,大多数 SSL_* 调用的手册页通过返回值
但是在这些调用以及其他 OpenSSL 库调用的手册页中,模糊地提到在 OpenSSL 中使用“错误队列” - SSL_get_error 的手册页中就是这种情况:
The current thread's error queue must be empty before the TLS/SSL I/O
operation is attempted, or SSL_get_error() will not work reliably.
在同一个手册页中,SSL_ERROR_SSL 的描述是这样的:
SSL_ERROR_SSL
A failure in the SSL library occurred, usually a protocol error.
The OpenSSL error queue contains more information on the error.
这种暗示表明错误队列中有一些值得一读的东西。并且未能读取它会使随后对 SSL_get_error 的调用不可靠。大概,拨打电话是ERR_get_error。
我计划在我的代码中使用非阻塞套接字。因此,重要的是我能够可靠地发现错误条件何时是 SSL_ERROR_WANT_READ 或 SSL_ERROR_WANT_WRITE,以便我可以将套接字置于正确的轮询模式。
所以我的问题是这样的:
SSL_get_error() 是否为我隐式调用 ERR_get_error()?还是我需要同时使用两者?
我应该在每次调用 OpenSSL 库之前调用 ERR_clear_error 吗?
OpenSSL 库调用完成后,队列中是否有可能出现多个错误?因此,是否存在队列中的第一个错误比最后一个错误更相关的情况?
【问题讨论】:
对于最后一个:是的,这可能发生。较低级别可能有错误,将消息添加到队列中,并且由于此错误,库中的较高级别添加了自己的消息。在某些情况下,我在堆栈上看到了 5 条甚至更多消息。 另请参阅codereview.stackexchange.com/questions/108600/… 这太疯狂了...就像...除非您在每次通话后都小心谨慎地清除它(并多次调用),否则您应该先清除它每次通话。因为你不能确定。哇... @rogerdpack 那不是errno
在 C 中无论如何都可以工作。我想它是模仿那种(糟糕的)行为。
【参考方案1】:
SSL_get_error 不调用 ERR_get_error。因此,如果您只是调用 SSL_get_error,则错误会留在队列中。
您应该在任何 SSL 调用(SSL_read、SSL_write 等)之前调用 ERR_clear_error,然后再调用 SSL_get_error,否则您可能正在读取当前线程中先前发生的旧错误。
【讨论】:
@QuinnCarver 看看ERR_error_string。你会将ERR_get_error()
的结果传递给它。以上是关于如何管理 openssl 中的错误队列(SSL_get_error 和 ERR_get_error)的主要内容,如果未能解决你的问题,请参考以下文章