我正在使用Bio Memory接口使TLS通过SCTP实现。
在客户端发送申请数据时,
-
SSL_write()
API加密数据并将数据写入关联的写生界面。 - 然后使用
BIO_read()
调用将来自生物接口的数据读取到输出缓冲区,然后 - 使用
sctp_sendmsg()
API发送到插座。
在服务器端类似,读取套接字的数据
-
sctp_recvmsg()
api从插座读取Ecrypted消息块, -
BIO_write()
API将其写入读取生物缓冲区, -
SSL_read()
API解密从生物中读取的数据。
我感兴趣的情况是在客户端,步骤1和2完成的位置,而在做3时,我从插座上得到了Eagain。因此,我从生物缓冲区中读取的任何数据,我都会清理它,并要求应用程序在一段时间后再次重新发送数据。
现在,当我这样做时,稍后,当客户端的步骤1、2和3经过良好时,在服务器端,OpenSSL发现它收到的记录已有A BAD_RECORD_MAC并关闭了连接。p>从谷歌搜索中,我知道它发生的一种可能性是,如果TLS数据包不顺序,因为Mac编码对先前的数据包的依赖性,并且TLS需要以相同的顺序交付数据包。因此,当我清理有关Eagain的数据时,我要丢弃一个SSL数据包,然后发送下一个不订单的数据包(此处丢失清晰度)?
?只是为了确保我的假设,每当插座返回Eagain时,我都会更改代码以进行无限等待,直到插座可以写入,然后一切都很好,我看不到服务器端的任何bad_record_mac。
有人可以在这里帮助我吗?我不能无限等待解决这个问题,还有其他出路吗?
...我从插座上得到一只老鹰。因此,我从生物缓冲区中读取的任何数据,我都会清理它,并要求应用程序在一段时间后再次重新发送数据。
如果您在套接字上获得Eagain,则应尝试发送稍后再发送相同的加密数据。
您要做的是将加密的数据丢弃,并要求应用程序再次发送相同的普通数据。这意味着这些数据再次加密。但是,在SSL中加密普通数据还包括SSL帧的序列编号,并且该序列编号与您丢弃的最后一个SSL帧不同。
因此,如果您已经扔掉了完整的SSL框架,则试图发送一个新的SSL帧,其中下一个序列编号不符合预期序列编号。如果您成功地发送了以前的SSL帧的一部分,而其余部分则将您发送的新数据视为上一个帧的一部分,这意味着该框架的HMAC将不匹配。
因此,不要扔掉加密的数据,而要尝试对这些数据进行讨厌,而不是让上层怨恨普通数据。
- 选择写入。
- 重复发送。
- 如果发送不完整,请删除发送的缓冲区的部分,然后转到(1)。
所以我从生物缓冲区中阅读的任何数据,我都会清理
我不知道这意味着什么。您正在发送,不收到。
只是为了确保我的假设,每当插座返回Eagain时,我都会更改代码以进行无限等待,直到插座可以写入,然后一切都很好,我看不到服务器端的任何bad_record_mac。
这正是您应该做的。我无法想象您还可以做什么,而您对它的描述也没有任何意义。