TCP MSS minimo in Linux


9

TCP MSS in Linux deve essere almeno 88 (include / net / tcp.h):

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

La mia domanda è: dove sono venuti fuori con "60 + 60 + 8" e perché? Ho capito che 20 + 20 provengono dall'intestazione IP + dall'intestazione TCP.

EDIT: Dopo aver dato un'occhiata più da vicino alle intestazioni, la formula mi cerca così:

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

La domanda è ancora valida: perché ? Perché il kernel Linux usa questa formula, proibendo così (un flusso forzato di) segmenti TCP, diciamo, di 20 byte? Pensa iperf qui.

EDIT2: ecco il mio caso d'uso. Forzando un MSS basso su socket / connessione, tutti i pacchetti inviati dallo stack avranno dimensioni ridotte. Voglio impostare un MSS basso quando lavoro con iperf per pacchetti / secondo test. Non riesco a ottenere pacchetti IP più piccoli di 128 byte (frame Ethernet di 142 byte) sul cavo a causa di questo limite inferiore per MSS! Vorrei avvicinarmi a una dimensione di frame Ethernet di 64 byte secondo RFC 2544. Teoricamente questo dovrebbe essere possibile: 18 + 20 + 20 <64.


In che modo ciò impedisce i segmenti TCP di 20 byte?
David Schwartz,

MSS sta per Dimensione massima del segmento, è il limite superiore (non inferiore) per la dimensione del segmento in particolare connessione. TCP_MIN_MSS specifica il limite inferiore per questo limite. Quindi, non proibisce in alcun modo segmenti con meno di 88 byte, afferma semplicemente che MSS per qualsiasi connessione dovrebbe essere> = 88 byte.
Gelraen,

Ovviamente! Scusa per non essere abbastanza chiaro. Si prega di consultare l'ultima modifica.
Mircea Gherzan,

Perché hai lasciato scadere la taglia? La risposta di David chiarisce le cose almeno per la mia soddisfazione. La differenza tra la sua risposta e la mia è che stiamo parlando di minimi diversi. Per quello che vale, c'è un terzo minimo, ovvero 41, o 20 + 20 + 1 byte di dati TCP. Pertanto, la dimensione minima del pacchetto dipende dal motivo per cui lo stai chiedendo. Mi aspetto che 68 sia la risposta giusta nei casi in cui il kernel usa TCP_MIN_MSS.
Warren Young,

Non sono ancora soddisfatto della risposta. Non riesco ancora a vedere il motivo per cui il kernel non mi consente di imporre un piccolo MSS arbirario a un'app. Mi piacerebbe avere (un flusso costante di TCP caricati) pacchetti IP di 41 byte, ma non posso, a causa del TCP_MIN_MSS. Perché non può essere 1? Quale RFC si romperebbe? Quale problema teorico / pratico provocherebbe? Sei sicuro che sia "fuori dalle specifiche"? "Minimi diversi"? C'è solo un minimo di interesse qui: il più piccolo MSS consentito dal kernel.
Mircea Gherzan,

Risposte:


5

È necessaria un'implementazione per supportare le intestazioni TCP e IP di dimensioni massime, ciascuna di 60 byte.

Un'implementazione deve supportare datagrammi a 576 byte, che anche con le intestazioni massime significano più di 8 byte di dati nel datagramma. Per inviare datagrammi con più di 8 byte di dati, la frammentazione IP deve inserire almeno 8 byte di dati in almeno uno dei pacchetti che rappresentano i frammenti del datagramma. Pertanto un'implementazione deve supportare almeno 8 byte di dati in un pacchetto.

Mettendo tutto insieme, un'implementazione deve supportare pacchetti da 60 + 60 + 8 byte.

Quando inviamo pacchetti che fanno parte di un flusso TCP, hanno un'intestazione IP di 20 byte (più opzioni) e un'intestazione TCP di 20 byte (più opzioni). Ciò lascia un minimo di (60 + 60 + 8) - (20 + 20) byte rimanenti per dati e opzioni. Quindi questo è il massimo che possiamo tranquillamente assumere TCP MSS di un'implementazione.


1
Il MSS non include l'intestazione (è solo il payload) e lo 60show due volte
Michael Mrozek

Un'implementazione deve essere in grado di supportare un pacchetto con un'intestazione di dimensioni massime, ma non stiamo inviando un'intestazione di dimensioni massime. La differenza tra il massimo e ciò che effettivamente inviamo è quindi disponibile per i dati e dovrebbe essere aggiunta all'MSS.
David Schwartz,

OK, quindi hai spiegato gli 8 byte. Non so cosa intendi per intestazione "TCP / IP". Conosco un'intestazione IP e una TCP. E, come ha sottolineato Michael, 60 si presentano due volte. E la RFC discute solo dell '"MSS efficace" e non minimale.
Mircea Gherzan,

60 compare due volte, una per l'intestazione IP e una per l'intestazione TCP.
David Schwartz,

68 riguarda solo la frammentazione. "60 + 60 + 8" potrebbe essere frammentato, quindi perché preoccuparsi della frammentazione? Anche "68 + 20" potrebbe essere frammentato. E perché "deve" l'altra parte "accettare" "60 + 60 + 8"? "Accetta" come in "senza frammentazione"? In conclusione: perché non posso inviare "20 + 20" + 10 byte di dati?
Mircea Gherzan,

3

Non so da dove provenga quel numero, ma posso dirti che è al di fuori delle specifiche. L'MTU minimo supportato per le reti IP è 576 byte, ovvero 512 byte di dati più un massimo di 64 byte per le intestazioni IP + TCP e le opzioni TCP. Tale valore è stato scelto per fornire un sovraccarico decentemente basso nel caso tipico.

La mia lettura di bit di codice del kernel suggerisce che il valore che stai mostrando non è arbitrario. C'era una pratica più vecchia per usare solo la costante grezza 64 al posto di TCP_MIN_MSS. Pertanto, suppongo che ci sia una strana rete IP-over-Foo in cui si sono imbattuti gli sviluppatori del kernel che li ha indotti a decidere di aumentare il valore di ciò che vedi.

Che cosa sia quel tipo di rete non standard, tuttavia, non posso dire.


576 è l'MTU per i datagrammi . In questo caso, sono i limiti dei pacchetti che contano, non i limiti del datagramma perché i pacchetti TCP impostano il bit DF.
David Schwartz,

Gli MTU minimi definiti per i datagrammi IP e i pacchetti TCP sono anche datagrammi IP.
Gelraen,

Giusto, ma questa limitazione TCP è per i pacchetti, non per i datagrammi, perché i datagrammi TCP non si frammentano (normalmente). L'unico senso in cui conta la regola del datagramma a 576 byte è che significa che l'implementazione deve essere in grado di supportare almeno 8 byte di dati in un pacchetto (quindi gli 8 nella formula). Altrimenti, sarebbe impossibile frammentare un datagramma a 576 byte.
David Schwartz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.