客户端上的SSL_read()即使在select()返回可读服务器套接字之后也会阻塞

问题描述 投票:0回答:2

我正在使用 C 构建 TLS 客户端,以使用 TLS 1.3 连接到安全服务器。

我创建了一个阻塞(常规)TCP 套接字。然后连接到远程安全服务器。我还创建并配置了 SSL 上下文,并将服务器套接字链接到 SSL 对象 (SSL_set_fd())。我的

SSL_connect()
成功了,我能够从远程服务器发送/接收数据。

我面临的问题是,我有一个事件循环,我正在执行多个

SSL_write()
并有一个
select()
来监视套接字以获取来自服务器的传入数据。然而,在事件循环的每次迭代中,l
select()
返回可读套接字,并且 SSL_read() 阻塞。

为什么他

SSL_read((
无法读取,即使
select()
标记了套接字已准备好读取?

c security ssl openssl posix-select
2个回答
4
投票

因为套接字收到了一些用于 OpenSSL 的字节,而不是用于您的。就像重新谈判或心跳一样。

因为您使用的是阻塞套接字,所以 OpenSSL 知道您不希望 SSL_read 返回,直到它收到一些数据为止。

如果您希望 SSL_read 返回,即使它没有任何数据给您,那么首先将套接字设置为非阻塞。


2
投票

select
不反映 TLS 级别的数据可用性。可能可以从套接字读取数据,但这根本不是有效负载,而是会话票证(TLS 1.3 的新功能)或警报。或者它可能是有效负载,但不是完整的 TLS 帧 - 在这种情况下
SSL_read
无法返回任何数据。类似地,
select
可能声称无法读取任何内容,但
SSL_read
实际上会成功 - 因为最后一个 TLS 帧中仍有未读取的数据(使用
SSL_pending
检查)。

© www.soinside.com 2019 - 2024. All rights reserved.