20

在 OpenSSl 中,大多数 SSL_* 调用的手册页通过返回值 <= 0 来指示错误,并建议调用 SSL_get_error() 以获取扩展错误。

但是在这些调用以及其他 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 库调用完成后,队列中是否有可能出现多个错误?因此,是否存在队列中的第一个错误比最后一个错误更相关的情况?

4

1 回答 1

10
  • SSL_get_error 不调用 ERR_get_error。因此,如果您只是调用 SSL_get_error,则错误会留在队列中。
  • 您应该在任何 SSL 调用(SSL_read、SSL_write 等)之前调用 ERR_clear_error,然后再调用 SSL_get_error,否则您可能正在读取先前在当前线程中发生的旧错误。
于 2014-06-25T13:02:20.397 回答