使用OpenSSL BIO进行非阻塞I / O.

时间:2017-01-30 20:58:12

标签: c++ linux sockets openssl

我在Linux上使用OpenSSL 1.0.0-fips。我遇到的问题是SSL_connect()返回-1而SSL_get_error()正在返回SSL_ERROR_WANT_READ。然后我将文件描述符放入select()timeval结构设置为10秒,select()只是超时。

我解雇了Wireshark并且我看到“客户端你好”出去了,我看到ServerHello回到了客户端,但它从未在select()中“醒来”。它只是超时。

我的问题是:

  1. 我是否必须使用BIO_new_socket()创建BIO对象,然后使用SSL_set_bio()将BIO对象分配给我的SSL对象? SSL_set_fd()的手册页说它会自动创建一个BIO对象,这似乎意味着SSL_set_bio()是一种无用的函数,你永远不需要调用它。

  2. 我们假设我们使用SSL_set_fd()并分配一个阻塞的连接TCP文件描述符。让我们说我们稍后使用fcntl()将该文件描述符更改为非阻塞。这是否会破坏SSL对象(或底层BIO对象)?

1 个答案:

答案 0 :(得分:1)

  

1)我是否必须使用BIO_new_socket()然后创建BIO对象   使用SSL_set_bio()将BIO对象分配给我的SSL对象?男人   SSL_set_fd()的页面说它会自动创建一个BIO对象   所以这似乎意味着SSL_set_bio()有点无用   你永远不必打电话的功能。

如果默认的BIO对象足以满足您的需求,那么您不必手动创建和安装自己的BIO对象。 SSL_set_bio()调用是为了防止您想要创建/使用与SSL_set_bio()代表您创建的默认BIO对象不同的BIO对象。

  

2)我们假设我们使用SSL_set_fd()并分配连接的TCP文件   阻塞的描述符。让我们说我们后来改变了   文件描述符使用fcntl()进行非阻塞。这会破坏SSL   无论如何对象(或底层的BIO对象)?

是的,我相信它会破裂。非阻塞OpenSSL的调用模式与阻塞OpenSSL的调用模式非常不同,我不相信您可以在运行中从一种模式切换到另一种模式。也就是说,我自己没有尝试过,所以我可能是错的,但我认为是安全的(并且要保持一致)你应该预先选择是否要使用阻塞或非阻塞I / O并在连接期间坚持使用它。

特别是这个引用来自手册页:

  

BIO和SSL引擎继承了fd。

的行为

...建议SSL设置调用将检查fd的状态,并根据fd的阻塞/非阻塞状态在BIO和SSL对象中设置私有变量。如果你然后“落后于OpenSSL的后面”并改变fd的行为,那么OpenSSL的例程将不会发生这种情况,很可能会做错事而且无法正常工作。