minimales TCP-MSS unter Linux

9

Das TCP-MSS unter Linux muss mindestens 88 sein (include / net / tcp.h):

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

Meine Frage ist: Wo haben sie "60 + 60 + 8" gefunden und warum? Ich bekomme, dass 20 + 20 vom IP-Header + TCP-Header kommt.

EDIT: Nach einem genaueren Blick auf die Überschriften sieht die Formel für mich so aus:

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

Die Frage bleibt noch: Warum ? Warum verwendet der Linux-Kernel diese Formel und verhindert so (einen erzwungenen Fluss von) TCP-Segmenten von beispielsweise 20 Bytes? Denken Sie hier iperf.

EDIT2: Hier ist mein Anwendungsfall. Durch Erzwingen eines niedrigen MSS für Socket / Verbindung haben alle vom Stapel gesendeten Pakete eine geringe Größe. Ich möchte ein niedriges MSS einstellen, wenn ich mit iperf für Pakete / zweite Tests arbeite. Ich kann keine IP-Pakete erhalten, die kleiner als 128 Bytes (Ethernet-Frames von 142 Bytes) sind, da diese Untergrenze für das MSS liegt! Ich möchte einer Ethernet-Frame-Größe von 64 Bytes gemäß RFC 2544 so nahe kommen. Theoretisch sollte dies möglich sein: 18 + 20 + 20 <64.

Mircea Gherzan
quelle
Wie verbietet dies TCP-Segmente von 20 Bytes?
David Schwartz
MSS steht für Maximum Segment Size, die Obergrenze (nicht die Untergrenze) für die Segmentgröße in einer bestimmten Verbindung. TCP_MIN_MSS gibt die Untergrenze für dieses Limit an. Es verbietet also in keiner Weise Segmente mit weniger als 88 Bytes, sondern gibt lediglich an, dass MSS für jede Verbindung> = 88 Bytes sein sollte.
Gelraen
Natürlich! Tut mir leid, dass ich nicht klar genug bin. Bitte beachten Sie die neueste Bearbeitung.
Mircea Gherzan
Warum hast du das Kopfgeld verfallen lassen? Davids Antwort klärt die Dinge zumindest zu meiner Zufriedenheit auf. Der Unterschied zwischen seiner und meiner Antwort besteht darin, dass wir über verschiedene Minima sprechen. Für das, was es wert ist, gibt es ein drittes Minimum, nämlich 41 oder 20 + 20 + 1 Byte TCP-Daten. Die minimale Paketgröße hängt also vom Grund ab, den Sie fragen. Ich gehe davon aus, dass 68 die richtige Antwort in den Fällen ist, in denen der Kernel verwendet TCP_MIN_MSS.
Warren Young
Ich bin immer noch nicht zufrieden mit der Antwort. Ich sehe immer noch nicht den Grund, aus dem der Kernel es mir nicht erlaubt, einer App eine willkürliche kleine MSS aufzuerlegen. Ich hätte gerne (einen konstanten Strom von TCP-geladenen) IP-Paketen mit 41 Bytes, kann dies aber aufgrund der TCP_MIN_MSS. Warum kann es nicht 1 sein? Welchen RFC würde es brechen? Welches theoretische / praktische Problem würde es verursachen? Sind Sie sicher, dass es "außerhalb der Spezifikation" ist? "Unterschiedliche Minima"? Hier gibt es nur ein Minimum an Interesse: das kleinste vom Kernel zugelassene MSS.
Mircea Gherzan

Antworten:

5

Eine Implementierung ist erforderlich, um die maximal großen TCP- und IP-Header zu unterstützen, die jeweils 60 Byte groß sind.

Eine Implementierung muss 576-Byte-Datagramme unterstützen, was selbst bei maximalen Headern mehr als 8 Byte Daten im Datagramm bedeutet. Um Datagramme mit mehr als 8 Datenbytes zu senden, muss die IP-Fragmentierung mindestens 8 Datenbytes in mindestens eines der Pakete einfügen, die die Fragmente des Datagramms darstellen. Daher muss eine Implementierung mindestens 8 Datenbytes in einem Paket unterstützen.

Zusammengenommen muss eine Implementierung 60 + 60 + 8-Byte-Pakete unterstützen.

Wenn wir Pakete senden, die Teil eines TCP-Streams sind, haben sie einen 20-Byte-IP-Header (plus Optionen) und einen 20-Byte-TCP-Header (plus Optionen). Damit verbleiben mindestens (60 + 60 + 8) - (20 + 20) Bytes für Daten und Optionen. Daher ist dies das Maximum, das wir sicher für das TCP-MSS einer Implementierung annehmen können.

David Schwartz
quelle
1
Die MSS enthält jedoch nicht den Header (es ist nur die Nutzlast), und der 60wird zweimal
angezeigt
Eine Implementierung muss in der Lage sein, ein Paket mit einem Header maximaler Größe zu unterstützen, aber wir senden keinen Header maximaler Größe. Die Differenz zwischen dem Maximum und dem, was wir tatsächlich senden, ist daher für Daten verfügbar und sollte dem MSS hinzugefügt werden.
David Schwartz
OK, Sie haben also die 8 Bytes erklärt. Ich weiß nicht, was Sie unter "TCP / IP" -Header verstehen. Ich kenne einen IP-Header und einen TCP-Header. Und wie Michael betonte, tauchen 60 zweimal auf. Und der RFC diskutiert nur das "effektive MSS" und kein minimales.
Mircea Gherzan
60 wird zweimal angezeigt, einmal für den IP-Header und einmal für den TCP-Header.
David Schwartz
68 geht es nur um Fragmentierung. "60 + 60 + 8" könnte fragmentiert werden. Warum sollte man sich dann um Fragmentierung kümmern? Sogar "68 + 20" könnte fragmentiert werden. Und warum "muss" die andere Seite "60 + 60 + 8" "akzeptieren"? "Akzeptieren" wie in "ohne Fragmentierung"? Fazit: Warum darf ich nicht "20 + 20" + 10 Datenbytes senden?
Mircea Gherzan
3

Ich weiß nicht, woher diese Nummer kommt, aber ich kann Ihnen sagen, dass sie außerhalb der Spezifikation liegt. Die für IP-Netzwerke unterstützte Mindest-MTU beträgt 576 Byte, dh 512 Datenbyte plus bis zu 64 Byte für IP + TCP-Header und TCP-Optionen. Dieser Wert wurde gewählt, um im typischen Fall einen angemessen geringen Overhead zu erzielen.

Mein Lesen von Kernel-Code-Bits legt nahe, dass der angezeigte Wert nicht willkürlich ist. Es gab eine ältere Praxis, nur die Rohkonstante 64 anstelle von zu verwenden TCP_MIN_MSS. Daher gehe ich davon aus, dass es ein seltsames IP-over-Foo-Netzwerk gibt, auf das die Kernel-Entwickler gestoßen sind, das sie zu der Entscheidung veranlasst hat, den Wert auf das zu erhöhen, was Sie sehen, wie.

Was dieser nicht standardmäßige Netzwerktyp ist, kann ich jedoch nicht sagen.

Warren Young
quelle
576 ist die MTU für Datagramme . In diesem Fall sind die Paketgrenzen von Bedeutung, nicht die Datagrammgrenzen, da TCP-Pakete das DF-Bit setzen.
David Schwartz
Die für IP-Datagramme definierte Mindest-MTU und TCP-Pakete sind ebenfalls IP-Datagramme.
Gelraen
Richtig, aber diese TCP-Einschränkung gilt für Pakete, nicht für Datagramme, da TCP-Datagramme niemals (normalerweise) fragmentieren. Der einzige Sinn, in dem die 576-Byte-Datagrammregel von Bedeutung ist, besteht darin, dass die Implementierung mindestens 8 Byte Daten in einem Paket unterstützen muss (daher die 8 in der Formel). Andernfalls wäre es unmöglich, ein 576-Byte-Datagramm zu fragmentieren.
David Schwartz