Linuxの最小TCP MSS


9

LinuxのTCP MSSは少なくとも88(include / net / tcp.h)でなければなりません:

/* Minimal accepted MSS. It is (60+60+8) - (20+20). */
#define TCP_MIN_MSS             88U

私の質問は、「60 + 60 + 8」をどこで思いついたのか、そしてなぜですか?20 + 20は、IPヘッダー+ TCPヘッダーから取得されます。

編集:ヘッダーを詳しく見てみた後、式は次のように私を探します:

(MAX_IP_HDR + MAX_TCP_HDR + MIN_IP_FRAG) - (MIN_IP_HDR + MIN_TCP_HDR)

問題はまだ残っています:なぜですか?なぜLinuxカーネルはこの公式を使用して、たとえば20バイトのTCPセグメント(の強制フロー)を禁止するのですか?ここでiperfを考えてください。

EDIT2:これが私のユースケースです。ソケット/接続のMSSを低く設定すると、スタックによって送信されるすべてのパケットのサイズが小さくなります。パケット/秒のテストでiperfを使用する場合、MSSを低く設定したいと思います。MSSのこの下限のため、128バイト(142バイトのイーサネットフレーム)より小さいIPパケットをワイヤで取得できません。RFC 2544に従って、64バイトのイーサネットフレームサイズにできるだけ近い値を取得したいと考えています。理論的には、18 + 20 + 20 <64が可能です。


これにより、20バイトのTCPセグメントがどのように禁止されますか?
David Schwartz

MSSは最大セグメントサイズの略で、特定の接続におけるセグメントサイズの上限(下限ではありません)です。TCP_MIN_MSSは、この制限の下限を指定します。したがって、88バイト未満のセグメントを禁止することはせず、接続のMSSは88バイト以上である必要があると述べています。
gelraen

もちろん!十分に明確になっていないため申し訳ありません。最新の編集をご覧ください。
Mircea Gherzan、2011年

賞金を期限切れにしたのはなぜですか?デビッドの答えは、少なくとも私の満足するまで物事をクリアします。彼の答えと私の答えの違いは、異なる最小値について話していることです。価値があるのは、3番目の最小値である41、つまり20 + 20 + 1バイトのTCPデータです。したがって、最小パケットサイズは、要求している理由に依存します。カーネルが使用するケースでは、68が正解だと思いますTCP_MIN_MSS
ウォーレンヤング

私はまだ答えに満足していません。カーネルが任意の小さなMSSをアプリに課さない理由を私はまだ見逃しています。41バイトのIPパケット(TCPがロードされた一定のストリーム)が欲しいのですが、それができないためですTCP_MIN_MSS。なぜ1にできないのですか?それはどのRFCを壊しますか?それはどんな理論的/実用的な問題を引き起こしますか?「仕様外」でよろしいですか?「違うミニマ」?ここで最低限必要なものは1つだけです。カーネルによって許可される最小のMSSです。
Mircea Gherzan、2011年

回答:


5

最大サイズのTCPおよびIPヘッダー(それぞれ60バイト)をサポートするには、実装が必要です。

実装は576バイトのデータグラムをサポートする必要があります。これは、最大ヘッダーがあっても、データグラム内のデータが8バイトを超えることを意味します。8バイトを超えるデータを含むデータグラムを送信するには、IPフラグメンテーションは、データグラムのフラグメントを表す少なくとも1つのパケットに少なくとも8バイトのデータを入れる必要があります。したがって、実装では、パケットで少なくとも8バイトのデータをサポートする必要があります。

これをまとめると、実装は60 + 60 + 8バイトのパケットをサポートする必要があります。

TCPストリームの一部であるパケットを送信する場合、20バイトのIPヘッダー(およびオプション)と20バイトのTCPヘッダー(およびオプション)があります。これにより、データおよびオプション用に少なくとも(60 + 60 + 8)-(20 + 20)バイトが残ります。したがって、これは実装のTCP MSSを安全に想定できる最大値です。


1
ただし、MSSにはヘッダーが含まれていません(これは単なるペイロードです)。これ60は2回表示されます
Michael Mrozek

実装は最大サイズのヘッダーを持つパケットをサポートできなければなりませんが、最大サイズのヘッダーを送信していません。したがって、最大値と実際に送信する最大値の差はデータに利用可能であり、MSSに追加する必要があります。
David Schwartz、

OK、8バイトについて説明しました。「TCP / IP」ヘッダーの意味がわかりません。IPヘッダーとTCPヘッダーを知っています。そして、マイケルが指摘したように、60が2回表示されます。また、RFCは「効果的なMSS」についてのみ説明しており、最小限のものについては説明していません。
Mircea Gherzan、2011年

60は2回表示されます。1回はIPヘッダー用、もう1回はTCPヘッダー用です。
David Schwartz

68は断片化についてです。「60 + 60 + 8」は断片化する可能性があるので、なぜ断片化に注意する必要があるのでしょうか。「68 + 20」でも断片化する可能性があります。そして、なぜ反対側を「受け入れる」「60 + 60 + 8」にする必要があるのでしょうか。「断片化なし」のように「受け入れる」?結論:なぜ「20 + 20」+ 10バイトのデータを送信できないのですか?
Mircea Gherzan、2011年

3

その数がどこから来たのかはわかりませんが、仕様の範囲外です。IPネットワークでサポートされる最小MTUは576バイトです。これは、512データバイトに加えて、IP + TCPヘッダーとTCPオプションで最大64バイトです。この値は、一般的なケースでオーバーヘッドをかなり低くするために選択されました。

カーネルコードのビットを読んだところ、あなたが示している値は恣意的ではないことがわかりました。の代わりに生の定数64を使用するという古い慣習がありましたTCP_MIN_MSS。したがって、カーネル開発者が遭遇した奇妙なIP-over-Fooネットワークがあり、その結果、あなたがどのようにして価値を高めることができるかを彼らが判断したと思います。

しかし、その非標準のネットワークタイプは何であるかはわかりません。


576はデータグラムのMTUです。この場合、TCPパケットがDFビットを設定するため、データグラムの制限ではなく、パケットの制限が問題になります。
David Schwartz

IPデータグラムに定義されている最小MTU、およびTCPパケットもIPデータグラムです。
gelraen

そうですが、TCPデータグラムは(通常)断片化しないため、このTCP制限はデータグラムではなくパケットに対するものです。576バイトのデータグラムルールが重要な唯一の意味は、実装がパケット内の少なくとも8バイトのデータをサポートできる必要があることを意味します(したがって、式では8バイトです)。そうしないと、576バイトのデータグラムをフラグメント化することができません。
David Schwartz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.