2017-09-17 52 views
-1

我正在使用BIO存储器接口使TLS通过SCTP实现。如何使用内存BIO接口处理通过SCTP流传输的TLS的EAGAIN案例

所以在客户端侧,在发送出应用数据,

  1. SSL_write() API加密数据和所述相关联的写入BIO接口写入数据。
  2. 然后从BIO接口的数据读入到使用BIO_read()呼叫,然后
  3. 发送到使用sctp_sendmsg() API套接字一个输出缓冲区。
  4. 在服务器侧

类似地,虽然从插座读取数据

  1. sctp_recvmsg() API读取来自插座ecrypted消息块,
  2. BIO_write() API将其写入到读取BIO缓冲器,和
  3. SSL_read() api解密从BIO读取的数据。

我感兴趣的情况是在客户端,步骤1和2完成,并在做3时,我从套接字获得EAGAIN。因此,无论我从BIO缓冲区读取的数据是什么,我都会清理它,并要求应用程序在一段时间后重新发送数据。

现在,当我这样做,后来当客户端的步骤1,2和3经过罚款,在服务器端,openssl发现它收到的记录已得到一个bad_record_mac并关闭连接。

从谷歌搜索我知道它的一个可能性是如果TLS数据包出现序列,因为MAC编码依赖于先前编码的数据包,并且,TLS需要以相同的顺序传递数据包。所以,当我清理EAGAIN上的数据时,我正在丢弃一个SSL数据包,然后发送一个乱序的数据包(这里缺少清晰度)?

只是为了确认我的假设,无论何时套接字返回EAGAIN,我将代码更改为无限等待,直到套接字可写,然后一切正常,我没有在服务器端看到任何bad_record_mac。

有人可以帮我在这里处理这个EAGAIN吗?我无法做出无限的等待来解决这个问题,还有没有其他办法?

回答

0
  1. 选择可写性。
  2. 重复发送。
  3. 如果发送未完成,请删除已发送的缓冲区部分并转至(1)。

所以,无论数据我已经从生物缓冲区中读取,我清理

我不知道这意味着什么。你正在发送,没有收到。

只是为了确保我的假设,每当插座返回EAGAIN,我所做的代码更改做一个无限等待,直到插座是可写的,然后一切都很好,我没有看到在服务器端的任何bad_record_mac。

这正是你应该做的。我无法想象你还能做些什么,而你对它的描述没有任何意义。

1

...我从套接字中得到一个EAGAIN。因此,无论我从BIO缓冲区读取的数据是什么,我都会清理它,并要求应用程序在一段时间后重新发送数据。

如果你得到的插座上的EAGAIN你应该尝试稍后发送相同的加密数据。

你所做的是抛弃加密的数据并要求应用程序再次发送相同的明文数据。这意味着这些数据会再次被加密。但是,对SSL中的明文数据进行加密还包括SSL帧的序列号,并且此序列号与您丢弃的最后一个SSL帧不相同。

因此,如果您丢弃了完整的SSL框架,则您尝试发送一个新的SSL框架,其下一个序列号不符合预期的序列号。如果您成功发送了以前的SSL帧的一部分,那么您发送的新数据将被视为前一帧的一部分,这意味着帧的HMAC不匹配。

因此,不要丢弃加密的数据,而是尝试重新发送这些数据,而不是让上层重新发送普通数据。

+0

非常好,我搞不清楚他在说什么。 – EJP