2017-09-17 83 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