web-dev-qa-db-ja.com

TCPヘッダーオプション:SACK許可(選択的確認)ネゴシエーション

私はtcp接続を分割する必要がある研究プロジェクトを行っています。ですから、私の開発で起こるかもしれないいくつかの特別な質問があります。問題は、TCP SACKで許可されたネゴシエーションの理解です。RFCを読みましたが、そこで答えが見つかりません。

2つのtcpプログラム(AとB)間の3ウェイtcpハンドシェイクの場合。AがA TCP SYNをSACK許可でBに送信した場合、BはSACK許可でSYN/ACKパケットに確実に応答します。 ?Bがa TCP SYN/ACK、SACK許可なし)で応答する場合、それは意味しますか

1)SACK-permmitedはAでのみ有効です。AはAからのtcpパケットを選択的に確認できますが、AはBからのtcpパケットを選択的に確認できません。

または

2)SACK-permmitedはAとBの両方で有効になっていません

aがSACKを許可せずにTCP SYNをBに送信した場合、BはSACKを許可してSYN/ACKパケットに応答できますか?

さらに、SACK許可が許可または禁止されるのはなぜですか?それはオペレーティングシステムやカーネルの設定などに依存しますか?それを制御することは可能ですか?ありがとう!

4
misteryes

SACKは後で追加されたため、エンドホストとミドルボックスの両方で下位互換性が必要です(以下も参照)。 SACK-permittedオプションはまさにそれを実現します。

SACK-permittedはAからBに送信され、AがSACKオプションを受信する意思があることを示します。 SACK処理の場合(ほとんどの再送信処理の場合)、TCPは、それぞれ状態が異なる2つのシンプレックス接続で構成されていると考えることができます。したがって、SACKのみを移動させることは完全に合法です(ただし一般的ではありません)。一方向(SYNまたはSYNACK中のSACK-permittedの逆方向)。

通常、パフォーマンスが向上するため、SACKを有効のままにしておくことをお勧めします。ただし、ファイアウォールとNATボックスがあり、SEQヘッダーフィールドとACKヘッダーフィールドを変更しますが、SACKを認識しないため、SACKオプションのシーケンス番号を対応して適合させません)。 。これにより、接続がハングする可能性があります(SACKが受信されていない別のセグメントを確認したため)。これが、両方のマシンがSACKをサポートしている場合でもSACKを無効にする理由です。

SACKは、* BSDシステム(MacOS Xを含む)でsysctl -w net.inet.tcp.sack=0と入力して無効にし(テスト用または上記の醜いミドルボックスが存在する場合)、1に戻すことで再度有効にできます。Linuxでは、sysctl -w net.ipv4.tcp_sack=0は同じ効果。

RFC 2018のセクション4 の最初の段落では、SACK許可が受信されたときにSACKを送信できます。通常、SACK対応のホストはSACK許可をアナウンスします。 SACK対応のホストがSACK許可をアドバタイズせず、SACKを使用するという便利なシナリオを想像することはできません(非現実的な例は、ミドルボックスが一方向にのみSACKをひどくいじる場合です)。したがって、SACKが一方向にのみ使用されることは期待していません。

Linux、MacOSX(おそらく、* BSDに一般化可能)、およびHPプリンターに対するWiresharkの簡単なテストでは、SACK許可がSYNにあったときに、SYNACKでSACK許可で応答することが示されています。ただし、RFCには、この動作を要求または奨励するものは何もありません。

4

これは、Van Jacobsenまたは彼の同僚がたまたまこのフォーラムに参加していない限り、あなたが尋ねたようにそれに答えようとする人の側に多大な努力を伴う可能性が高いという質問です。あなたがそれについて考えるならば、あなたの質問に答えるために必要な研究のレベルはあなたが現在取り組んでいる研究プロジェクトと同じかそれ以上になるでしょう。

しかし、私たちの多くは、答えが明白でなかったり、すぐに利用できなかったりするような難しい質問をする機会もありました。私の場合、最終的にはそのような質問に対する答えを自分で見つける必要がありますが、幸運なことに、私を正しい方向に向けてくれる親切な人々がいました...

私は現在、2つのBSD-unixシステムでルートアクセス権を持っていませんが、もしそうなら...選択的なACkはsysctlで制御できることを知っています。私のMacでは、SACKを有効にするエントリはnet.inet.tcp.sackです。有効にすると、値は1になります。無効にするには、sysctl -w net.inet.tcp.sack=0。さまざまなシナリオを設定し、tcpdumpを使用して問題をテストします。

他の人はあなたのために異なるヒントを持っているかもしれません...

0
Nevin Williams