2017-09-17 11 views
-1

私はBIOメモリインターフェイスを使用してSCTPでTLSを実装しています。メモリBIOインターフェイスを使用してSCTPストリーム上のTLSのEAGAINケースを処理する方法

ので、アプリケーションデータを送出しながら、クライアント側で、

  1. SSL_write() APIは、データを暗号化し、関連する書き込みBIOインターフェイスにデータを書き込みます。
  2. そしてBIOインタフェースは、次にBIO_read()コールと
  3. を用いて出力バッファに読み出されるデータは、sctp_sendmsg() APIを使用してソケットに送出します。サーバ側で同様

、ソケットからデータを読み出す

  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があり、接続を閉じていることがわかります。

グーグルで私は、MACエンコーディングがエンコードされている前のパケットに依存しているため、TLSパケットが順序外れする場合があることを知りました。TLSは同じ順序でパケットを配信する必要があります。だから私はEAGAIN上のデータをクリーンアップしていたときに私はSSLパケットを落として、次のパケットを送信しています。

私の仮説を確かめるために、ソケットがEAGAINを返すたびに、ソケットが書き込み可能になるまで無限の待機をするようにコードを変更しました。そしてすべてがうまく行き、サーバー側でbad_record_macを見ません。

このEAGAINの取り扱いで私を助けることができる人はいますか?私は問題を回避するために無限の待機をすることはできません、他の方法はありますか?

答えて

0
  1. 書き込み専用に選択します。
  2. 送信を繰り返します。
  3. 送信が完了していない場合は、送信されたバッファの一部を削除して(1)に進みます。

だから、どんなデータiのBIOバッファから読んで、私はこれが何を意味するのか分からない

それをクリーンアップします。あなたは送っていますが、受け取っていません。

ちょうど私の仮説のを確実にするソケットがEAGAINを返した時はいつでも、私は書き込み可能だったソケットまで無限に待機を行うには、コードの変更を行った後、すべてがうまく行くと、私は、サーバー側で任意のbad_record_macを参照してくださいいけません。

これはまさにあなたがすべきことです。私はあなたが他に何をしているのか想像することはできません。その説明は意味をなさない。

1

...私はソケットからEAGAINを取得します。ですから、私がBIOバッファから読み込んだデータが何であれ、私はそれをきれいにし、しばらくしてからアプリケーションを再送するように依頼します。あなたがソケットにEAGAINを取得した場合

後で同じ暗号化データを送信しようとする必要があります。

代わりに暗号化されたデータを投げ捨て、同じプレーンデータを再度送信するようにアプリケーションに依頼してください。これは、これらのデータが再び暗号化されることを意味します。 SSLのプレーンデータを暗号化するには、SSLフレームのシーケンス番号も含まれています。このシーケンス番号は、最後に投げたSSLフレームと同じではありません。

したがって、完全なSSLフレームを破棄した場合は、期待されるシーケンス番号に適合しない次のシーケンス番号を持つ新しいSSLフレームを送信しようとしています。以前のSSLフレームの一部を送信し、残りの部分を送信することに成功した場合、送信する新しいデータは前のフレームの一部とみなされます。つまり、フレームのHMACが一致しません。

したがって、暗号化されたデータを破棄せず、上位層にプレーンデータを再送信させる代わりに、再送信してください。

+0

非常に良い、私は彼が何について話していたのか分からなかった。 – EJP

関連する問題