minimalny TCP MSS w Linuksie

9

TCP MSS w Linuksie musi mieć co najmniej 88 (zawierać / net / tcp.h):

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

Moje pytanie brzmi: skąd pomysł na „60 + 60 + 8” i dlaczego? Rozumiem, że 20 + 20 pochodzi z nagłówka IP + nagłówka TCP.

EDYCJA: Po bliższym przyjrzeniu się nagłówkom formuła wygląda tak:

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

Pozostaje pytanie: dlaczego ? Dlaczego jądro Linuksa używa tej formuły, tym samym zabraniając (wymuszonemu przepływowi) segmentów TCP, powiedzmy, 20 bajtów? Pomyśl tutaj.

EDIT2: Oto mój przypadek użycia. Wymuszając niski poziom MSS na gnieździe / połączeniu, wszystkie pakiety wysyłane przez stos będą miały niewielki rozmiar. Chcę ustawić niski MSS podczas pracy z iperf do testowania pakietów / sekund. Nie mogę uzyskać pakietów IP mniejszych niż 128 bajtów (ramki Ethernet o długości 142 bajtów) z powodu tego dolnego limitu dla MSS! Chciałbym zbliżyć się do ramki Ethernet o wielkości 64 bajtów zgodnie z RFC 2544. Teoretycznie powinno to być możliwe: 18 + 20 + 20 <64.

Mircea Gherzan
źródło
Jak to uniemożliwia segmenty TCP o wielkości 20 bajtów?
David Schwartz
MSS oznacza Maksymalny rozmiar segmentu, jest to górna granica (nie niższa) dla wielkości segmentu w danym połączeniu. TCP_MIN_MSS określa dolną granicę tego limitu. Tak więc, nie zabrania to w żaden sposób segmentów zawierających mniej niż 88 bajtów, po prostu stwierdza, że ​​MSS dla dowolnego połączenia powinien wynosić> = 88 bajtów.
gelraen
Oczywiście! Przepraszam, że nie jestem wystarczająco jasny. Zobacz najnowszą edycję.
Mircea Gherzan
Dlaczego pozwoliłeś, aby nagroda wygasła? Odpowiedź Davida wyjaśnia wszystko, co najmniej ku mojej satysfakcji. Różnica między jego odpowiedzią a moją polega na tym, że mówimy o różnych minimach. Za to, co jest warte, istnieje trzecie minimum, czyli 41 lub 20 + 20 + 1 bajtów danych TCP. Zatem minimalny rozmiar pakietu zależy od przyczyny, dla której pytasz. Spodziewam się, że 68 jest właściwą odpowiedzią w przypadkach, w których używa jądra TCP_MIN_MSS.
Warren Young,
Nadal nie jestem zadowolony z odpowiedzi. Nadal nie widzę powodu, dla którego jądro nie pozwala mi narzucić arbirarnej małej MSS aplikacji. Chciałbym mieć (ciągły strumień załadowanych TCP) pakietów IP o wielkości 41 bajtów, ale nie mogę, z powodu TCP_MIN_MSS. Dlaczego nie może być 1? Jaki RFC by to zepsuł? Jaki problem teoretyczny / praktyczny spowodowałby? Czy na pewno jest to „poza specyfikacją”? „Różne minima”? Jest tu tylko jedno minimum zainteresowania: najmniejszy MSS dozwolony przez jądro.
Mircea Gherzan

Odpowiedzi:

5

Implementacja jest wymagana do obsługi nagłówków TCP i IP o maksymalnych rozmiarach, z których każdy ma 60 bajtów.

Implementacja musi obsługiwać datagramy 576 bajtów, co nawet przy maksymalnej liczbie nagłówków oznacza więcej niż 8 bajtów danych w datagramie. Aby wysłać datagramy zawierające więcej niż 8 bajtów danych, fragmentacja IP musi umieścić co najmniej 8 bajtów danych w co najmniej jednym pakiecie reprezentującym fragmenty datagramu. Dlatego implementacja musi obsługiwać co najmniej 8 bajtów danych w pakiecie.

Podsumowując, implementacja musi obsługiwać pakiety 60 + 60 + 8 bajtów.

Kiedy wysyłamy pakiety, które są częścią strumienia TCP, mają 20-bajtowy nagłówek IP (plus opcje) i 20-bajtowy nagłówek TCP (plus opcje). To pozostawia minimum (60 + 60 + 8) - (20 + 20) bajtów dla danych i opcji. Dlatego jest to maksimum, które możemy bezpiecznie założyć implementacji TCP MSS.

David Schwartz
źródło
1
MSS nie zawiera jednak nagłówka (to tylko ładunek), a 60pokazuje się dwa razy
Michael Mrozek
Implementacja musi obsługiwać pakiet z nagłówkiem o maksymalnym rozmiarze, ale nie wysyłamy nagłówka o maksymalnym rozmiarze. Różnica między maksimum a tym, co faktycznie wysyłamy, jest więc dostępna dla danych i powinna zostać dodana do MSS.
David Schwartz
OK, więc wyjaśniłeś 8 bajtów. Nie wiem, co masz na myśli przez nagłówek „TCP / IP”. Znam nagłówek IP i TCP. I, jak zauważył Michael, 60 pojawia się dwa razy. A RFC omawia tylko „skuteczny MSS”, a nie minimalny.
Mircea Gherzan
60 pojawia się dwa razy, raz dla nagłówka IP i raz dla nagłówka TCP.
David Schwartz
68 dotyczy tylko fragmentacji. „60 + 60 + 8” może ulec fragmentacji, więc po co więc przejmować się fragmentacją? Nawet „68 + 20” może ulec fragmentacji. I dlaczego „druga strona” musi zaakceptować „60 + 60 + 8”? „Zaakceptować” jak w „bez fragmentacji”? Konkluzja: dlaczego nie wolno mi wysłać „20 + 20” + 10 bajtów danych?
Mircea Gherzan
3

Nie wiem, skąd pochodzi ta liczba, ale mogę powiedzieć, że jest poza specyfikacją. Minimalna MTU obsługiwana dla sieci IP wynosi 576 bajtów, czyli 512 bajtów danych plus do 64 bajtów dla nagłówków IP + TCP i opcji TCP. Wartość tę wybrano, aby zapewnić przyzwoicie niskie koszty ogólne w typowym przypadku.

Moje czytanie fragmentów kodu jądra sugeruje, że pokazywana wartość nie jest arbitralna. Była starsza praktyka, aby po prostu użyć surowej stałej 64 zamiast TCP_MIN_MSS. Dlatego zakładam, że istnieje dziwna sieć IP over Foo, z którą natknęli się programiści jądra, która skłoniła ich do podjęcia decyzji, że mogą podnieść wartość do tego, co widzisz.

Tego nietypowego typu sieci nie mogę jednak powiedzieć.

Warren Young
źródło
576 to MTU dla datagramów . W tym przypadku liczą się limity pakietów, a nie limity datagramów, ponieważ pakiety TCP ustawiają bit DF.
David Schwartz
Minimalna MTU zdefiniowana dla datagramów IP, a pakiety TCP są również datagramami IP.
gelraen
Zgadza się, ale to ograniczenie TCP dotyczy pakietów, a nie datagramów, ponieważ datagramy TCP nigdy (normalnie) nie fragmentują. Jedynym sensem, w którym ma znaczenie reguła datagramowa 576 bajtów, jest to, że implementacja musi obsługiwać co najmniej 8 bajtów danych w pakiecie (stąd 8 we wzorze). W przeciwnym razie fragmentacja datagramu o długości 576 bajtów byłaby niemożliwa.
David Schwartz