- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我制作了一个服务器和一个客户端,它们在安全的 TLSv1.3、OpenSSL 3.0.0 channel 中进行通信。他们必须能够发送和接收,但在这个测试中,服务器只接收,客户端只定期发送应用程序数据。
握手成功后,客户端 select()
发出有数据可供读取的信号。当我尝试时,SSL_read()
没有返回。我检查了 wireshark 中的网络流量,并调试了 OpenSSL 库,发现服务器在握手后向客户端发送了 2 个 SESSION_TICKET,这就是消息 SSL_read()
处理失败。出于好奇,我在握手后立即向服务器发送了一条消息,以查看客户端对此有何 react 。令人惊讶的是,客户端离开了它的阻塞状态,之后通信工作正常。
由于观察到的行为,我唯一的猜测是我尝试读取用于 OpenSSL 的数据,当我调用 SSL_read()
时,它可能由其状态机处理。当库调用 read()
时,实际上没有可用的应用程序数据,因此它会阻塞线程。
下面是我用来读取“count”字节的成员函数。
int EventHandler::readByte(CommBuffer &buffer, ssize_t count, struct timeval &tmout){
fd_set rfds;
int retSelect, retRead;
int readByte=0;
int endRead=0;
int readSize=count;
buffer.setBufferSize(count+1);
do{
FD_ZERO(&rfds);
FD_SET(fd,&rfds);
retSelect=select(fd+1,&rfds,NULL,NULL,&tmout);
if(retSelect>0){
if (encryptionOn) {
retRead = SSL_read(ssl, (const_cast<char*>(&buffer.get()[readByte])), readSize); // Thread blocks here.
} else {
retRead = read(fd, (const_cast<char*>(&buffer.get()[readByte])), readSize);
}
if( retRead > 0 ){
readByte+=retRead;
allReadBytes+=retRead;
buffer.setDataSize(readByte);
if(readByte>=count) endRead=1;
readSize=count-readByte;
}
else{
if( retRead == -1 && errno == EINTR ){
continue;
}
if(fd>=0){
close(fd);
}
fd=CLOSED_FD;
return (CLOSED_FD);
}
}
else if(retSelect==0){
// handle timeout error
return(TIMEOUT_FD);
}
else{
return(retSelect);
}
}while(endRead!=1);
return(readByte);
}
请注意,此功能在没有加密的情况下也能正常工作。 (read()
而不是 SSL_read()
)
最佳答案
select
在 TCP 级别工作,而 SSL_read
在 TLS 级别工作。阻塞套接字上的 SSL_read
将(通常)仅在应用程序数据可用时返回,而 select
将在套接字上有任何类型的数据可用时发出信号,即也适用于非应用程序记录或不完整的 SSL 帧。
在您的特定情况下,这些数据是使用 TLS 1.3 的 session 票证,不再作为 TLS 握手的一部分发送,而是在握手之后发送。但是,对于较低的 TLS 版本,即使 select
返回数据可用,也可能发生 SSL_read
被阻止的情况:TLS 中的应用程序数据在 SSL 帧内发送,并且可能发生select
表示可用数据,即使只有部分 SSL 帧可用。在这种情况下,SSL_read
将阻塞,直到可以读取完整的 SSL 帧。此外,即使 select
发出可用数据信号,SSL_read
也会阻止 SSL 重新协商。
此外,select
可能不会发出可用数据的信号,但 SSL_read
会返回一些数据。当先前的 SSL_read
没有消耗已从 TCP 套接字读取的最后一个 SSL 帧中包含的所有数据时,就是这种情况。
换句话说:select
不应与 SSL 中的阻塞套接字一起使用。相反,套接字应该是非阻塞的,这样 SSL_read
(和其他函数)可能会因 SSL_ERROR_WANT_READ
或 SSL_ERROR_WANT_WRITE
而失败,其中一个应该按照记录进行处理.此外,应调用 SSL_pending
来检查已从 TCP 套接字读取但尚未被 SSL_read
使用的数据。
关于c++ - 握手成功后 SSL_read() 不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58218797/
我正在寻找通过 HTTPS 从服务器下载或读取文件,并且我正在使用 openSSL。 我看到连接成功,但是 SSL_read()返回 0。SSL_get_error()返回 6 表示 SSL_ERRO
我正在尝试通过 SSL 连接到安全服务,但是在下面的代码中,SSL_read 永远不会返回,如果服务器不返回任何消息,这当然是正常行为,但是我尝试连接的服务器应该返回某种消息。以下内容是否有不允许阅读
考虑以下代码,它显示了尝试从 ssl 连接读取 buff_size 字节的尝试。 int bytes = SSL_read(m_ssl, buf, buff_size); int err = SSL_
我正在尝试使用 SSL_read 从 Openssl 链接套接字读取数据。我在客户端模式下执行 Openssl 操作,发送命令并从真实世界的服务器接收数据。我使用了两个线程,其中一个线程处理所有 Op
我有一个使用 ssl 的 openssl 客户端。客户端之前正在与 openssl 服务器通信,一切都很好。我们现在正在用 Java 重写服务器,我们看到发生了以下情况。 1) 连接到服务器 WORK
我正在获得随机字节来领导每个SSL_read缓冲区中的内容 char *getJSON(char *url) { int sock, length, bytes, https = 0;
当前的 OpenSSL 版本是 1.1.1d。 我正在使用 SSL 到 TCP 套接字。 以下是相关来源。 ... ... struct timeval tv; fd_set fdIn;
我正在读一本 openssl 编程 tutorial . 我不能让服务器应用程序在单个连接的任何操作上被阻止, 因此我将使用非 block 套接字。 看来,ssl 握手发生在 ssl_accept 和
我正在尝试将 OpenSSL 添加到 epoll 中,并且套接字处于非阻塞模式。令我困惑的一个问题是:由于 SSL 重新协商,SSL_read 可能会产生 SSL_ERROR_WANT_WRITE ,
我正在尝试编写一个连接到带有 OpenSSL 的服务器的 C++ 应用程序。我可以发送数据,它完好无损地到达服务器,但读取操作只读取 1 个字节。 代码: char* dest_u
我制作了一个服务器和一个客户端,它们在安全的 TLSv1.3、OpenSSL 3.0.0 channel 中进行通信。他们必须能够发送和接收,但在这个测试中,服务器只接收,客户端只定期发送应用程序数据
我是套接字编程的新手。 下面的代码片段用于从服务器获取大约 100 万行的响应。我不知道响应的确切长度,因此检查响应串是否包含结束词,如 OK、NO、SUCCESS、FAILURE 等。 size =
我有一个用C来处理ssl的程序,步骤如下: retval = select(maxfd + 1, &rfds, NULL, NULL, &tv); if (retval == -1) {
这个问题的答案可能是“取决于”,那么我的问题就变成了“它取决于什么?”以及“应该怎么做才能按顺序收到它们?”。 最佳答案 是的。 TLS 在保证流的字节顺序的 TCP 上运行,并且正如@dave_th
我正在编写一个使用 OpenSSL 进行连接的程序。除了一个选项外,使用阻塞套接字和线程一切正常: 我的线程 1 调用 SSL_read() 并等待它接收任何东西 - 但如果连接被合作伙伴关闭,SSL
我在 LogCat 中收到大量(一次数百条)消息: 07-15 21:24:48.096: D/NativeCrypto(1606): Doing SSL_Read() 07-15 21:24:48.
我正在编写一个 https 服务器。我已经创建了 csr 并使用我的测试域的根证书对其进行了签名。当客户端连接时,SSL_accept() 成功完成。我正在使用非阻塞 IO。因此,我将首先在 char
我有一个需要升级到 SSL 通信的客户端/服务器通信。目前我有一个发送和接收 tcp 数据的网络套接字。 客户端向服务器发出一个 tcp connect()。 服务器已经实现了接受部分,接受连接后服务
我正在尝试使用 openssl 用 c 编写 Apple 推送通知服务器提供程序(APNS 提供程序)。 到目前为止,我已经能够通过 ssl_write 成功发送通知,但有时可能会发生我发送的消息被拒
我正在尝试使用 OpenSSL 创建一个非阻塞套接字,这样我就可以遍历 SSL_read() 直到没有更多数据剩余,然后中断循环。经过大量工作,我终于使连接正常工作,但现在对于前一千多次迭代,SSL_
我是一名优秀的程序员,十分优秀!