Dokładnie kiedy wykonywany jest PMTUD? (Odkrycie ścieżki MTU)

21

W rozmowach, które wynikły z innych pytań na tej stronie , zdałem sobie sprawę, że nie do końca rozumiem, kiedy wykonywana jest ścieżka MTU Discovery (PMTUD).

Wiem, co robi - odkryj najniższą MTU na ścieżce od klienta do serwera).
Wiem, jak to robi - wysyłaj stopniowo większe pakiety z ich zestawem bitów „Don't Fragment” i zobacz, jak duży pakiet można przejść bez wyświetlania błędu „ICMP Need to Fragment”.

Moje pytanie dotyczy zatem, kiedy host wykona PMTUD?

Szukam konkretnych przypadków. Nie tylko coś takiego jak „kiedy host chce odkryć MTU ścieżki”. Punkty bonusowe, jeśli możesz zapewnić przechwytywanie pakietów przez host, który to robi, lub podać instrukcje dotyczące generowania takiego przechwytywania pakietów.

Mówię też o IPv4. Wiem, że przejściowe routery IPv6 nie są odpowiedzialne za fragmentację i mogę sobie wyobrazić, że PMTUD zdarza się znacznie częściej. Ale na razie szukam konkretnych przykładów PMTUD w IPv4. (chociaż jeśli jedyne przechwytywanie pakietów, które można złożyć razem z PMTUD, to IPv6, nadal chciałbym je zobaczyć)

Eddie
źródło
Czy PMTUD jest wykonywany od najniższej obsługiwanej MTU do najwyższej? Czy też urządzenie wykonujące PMTUD najpierw wypróbowuje największą MTU, a następnie obniża o dużą wartość, aż pakiet przejdzie, a następnie zwiększa o mniejszą wartość, a następnie zmienia się w przód iw tył, aż do ostatecznego ustalenia?
cpt_fink
@ cpt_fink, istnieje kilka strategii. Nowoczesne implementacje komunikatu Potrzebne fragmentowanie ICMP zawierają w samej treści ICMP MTU łącza, dla którego wymagana była fragmentacja. Ułatwia to, ponieważ host początkowy od razu wie, jaka jest ścieżka MTU ścieżki. Starsze implementacje muszą wykorzystywać różne strategie do „wyszukiwania” właściwej MTU do użycia. Strategie te są opisane w RFC1191 w rozdziale 5. Obejmują one zakres od domyślnego domyślnego IP do minimum IP (576), po użycie tabeli „wspólnych” MTU w celu bardziej wydajnego wyszukiwania (patrz RFC1191 rozdział 7.1).
Eddie,
2
To interesujące pytanie. Robiłem kopanie na PMTUD i znalazłem to. Mimo że jest stary, postanowiłem odpowiedzieć, ponieważ miałem dokładnie to samo pytanie i po kilku godzinach poszukiwań mogłem znaleźć całkiem przyzwoitą odpowiedź (tak myślę). Jeśli to możliwe, spróbuję zaktualizować i wesprzeć moją odpowiedź przechwytywaniem pakietów jutro.
Filipe Gonçalves

Odpowiedzi:

15

Odpowiedź jest prosta: zawsze, gdy gospodarz zechce. Naprawdę. To takie proste.

Poniższe wyjaśnienie zakłada środowisko tylko IPv4, ponieważ IPv6 eliminuje fragmentację w routerach (zmuszając hosta do radzenia sobie z fragmentacją i wykrywaniem MTU).

Nie ma ścisłej zasady, która reguluje, kiedy (a nawet jeśli) host dokonuje Wykrywania MTU ścieżki. Powodem pojawienia się PMTUD jest to, że fragmentacja jest uważana za szkodliwą z różnych powodów. Aby uniknąć fragmentacji pakietów, koncepcja PMTUD została wprowadzona w życie jako obejście problemu. Oczywiście fajny system operacyjny powinien używać PMTUD, aby zminimalizować fragmentację.

Tak więc, naturalnie, dokładna semantyka użycia PMTUD zależy od systemu operacyjnego nadawcy - w szczególności od implementacji gniazda. Mogę mówić tylko w konkretnym przypadku Linuksa, ale inne warianty UNIX prawdopodobnie nie różnią się bardzo.

W systemie Linux PMTUD jest kontrolowany przez IP_MTU_DISCOVERopcję gniazda. Możesz odzyskać jego bieżący status getsockopt(2), określając poziom IPPROTO_IPi IP_MTU_DISCOVERopcję. Ta opcja jest ważna SOCK_STREAMtylko dla gniazd ( SOCK_STREAMgniazdo jest dwukierunkowym, niezawodnym, zorientowanym na połączenie gniazdem; w praktyce jest to gniazdo TCP, chociaż możliwe są inne protokoły), a po ustawieniu Linux wykona PMTUD dokładnie tak, jak zdefiniowano w RFC 1191.

Należy zauważyć, że w praktyce PMTUD jest procesem ciągłym; pakiety są wysyłane z ustawionym bitem DF - w tym z 3-stronnymi pakietami uzgadniania - możesz myśleć o tym jako o właściwości połączenia (chociaż implementacja może w pewnym momencie zaakceptować pewien stopień fragmentacji i przestać wysyłać pakiety z DF zestaw bitów). Zatem PMTUD jest tylko konsekwencją faktu, że wszystko na tym połączeniu jest wysyłane z DF.

Co jeśli nie ustawisz IP_MTU_DISCOVER?

Istnieje wartość domyślna. Domyślnie IP_MTU_DISCOVERjest włączony w SOCK_STREAMgniazdach. Można to odczytać lub zmienić, czytając /proc/sys/net/ipv4/ip_no_pmtu_disc. Wartość zero oznacza, że IP_MTU_DISCOVERjest domyślnie włączona w nowych gniazdach; niezerowa oznacza coś przeciwnego.

Co z gniazdami bezpołączeniowymi?

Jest to trudne, ponieważ niepołączone, niewiarygodne gniazda nie retransmitują utraconych segmentów. Obowiązkiem użytkownika jest spakowanie danych w porcje wielkości MTU. Oczekuje się również, że użytkownik dokona niezbędnych retransmisji w przypadku zbyt dużego błędu komunikatu. Zasadniczo kod użytkownika musi ponownie wdrożyć PMTUD. Niemniej jednak, jeśli jesteś gotowy na wyzwanie, możesz zmusić bit DF, przekazując IP_PMTUDISC_DOflagę do setsockopt(2).

Dolna linia

  • Host decyduje, kiedy (i czy) użyć PMTUD
  • Kiedy używa PMTUD, działa jak atrybut połączenia, dzieje się to w sposób ciągły (ale w dowolnym momencie implementacja może przestać to robić)
  • Różne systemy operacyjne używają różnych podejść, ale zwykle niezawodne, zorientowane na połączenie gniazda domyślnie wykonują PMTUD, podczas gdy zawodne, bezpołączeniowe gniazda nie
Filipe Gonçalves
źródło
4

Zazwyczaj wykrywanie maksymalnej ścieżki transmisji (PMTUD) ma miejsce zawsze, gdy host myśli, że pakiet został odrzucony z powodu zbyt dużego rozmiaru.

Może to być odpowiedź na wymaganą fragmentację ICMP (typ 3, kod 4), która wyraźnie wskazuje, że pakiet został odrzucony. W typowej praktyce wszystkie pakiety IPv4 są ustawione z ustawioną flagą „nie fragmentuj” (DF), więc każdy pakiet przekraczający MTU wywoła taką odpowiedź. IPv6 w ogóle nie obsługuje fragmentacji.

Niektóre routery lub zapory hosta często odrzucają cały ICMP, ponieważ naiwny administrator uważa ICMP za zagrożenie bezpieczeństwa . Lub niektóre schematy agregacji łączy mogą przerywać dostarczanie ICMP . W RFC4821 zaproponowano alternatywny mechanizm wykrywania MTU, który nie opiera się na ICMP .

tracepathto moje ulubione narzędzie do sondowania MTU w systemie Linux. Oto przykład z hosta z jednostką MTU 9001 w sieci LAN, ale który musi przejść przez sieć VPN IPsec, aby osiągnąć 10.33.32.157:

$ tracepath -n 10.33.32.157
 1?: [LOCALHOST]                                         pmtu 9001
 1:  10.1.22.1                                             0.122ms pmtu 1500
 1:  169.254.3.1                                           1.343ms pmtu 1422
 1:  10.255.254.61                                        23.790ms 
 2:  no reply
^C [this host won't return an ICMP port unreachable, so tracepath won't terminate]

Błędy ICMP można zaobserwować za pomocą tcpdump:

$ sudo tcpdump -p -ni eth0 'icmp and icmp[0] == 3 and icmp[1] == 4'
14:46:57.313690 IP 10.1.22.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1500), length 36
14:46:57.315080 IP 169.254.3.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1422), length 556

Odkrycia MTU są buforowane. W Linuksie można to zaobserwować i usunąć ip(uwaga na zmiany od Linuksa 3.6 ):

$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache  expires 591sec mtu 1422
$ sudo ip route flush cache
$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache

W przypadku protokołu TCP przekroczenie MTU można uniknąć w ramach konfiguracji połączenia. Do SYN wysyłanego przez każdy koniec zawarty jest maksymalny rozmiar segmentu (MSS). Nagłówek TCP (20 bajtów bez opcji ) i nagłówek IP (20 bajtów) oznaczają, że MSS i MTU są powiązane różnicą 40 bajtów.

Oto przykład konfiguracji połączenia między tymi dwoma hostami podczas przesyłania dużego pliku za pomocą scp:

$ sudo tcpdump -p -ni eth0 'host 10.33.32.157 and tcp[13]&2 == 2'
IP 10.1.22.194.45853 > 10.33.32.157.22: Flags [S], seq 634040018, win 26883, options [mss 8961,sackOK,TS val 10952240 ecr 0,nop,wscale 7], length 0
IP 10.33.32.157.22 > 10.1.22.194.45853: Flags [S.], seq 1371736848, ack 634040019, win 26847, options [mss 1379,sackOK,TS val 10824267 ecr 10952240,nop,wscale 7], length 0

W pierwszym pakiecie host lokalny proponuje MSS 8961. Jest to skonfigurowana jednostka MTU 9001, mniej niż 40 bajtów. Zwrócony SYN / ACK ma MSS 1379, co sugeruje MTU 1419. Zdarza się, że w tej sieci zdalny host również wysłał 8961, ale wartość została zmodyfikowana przez router, ponieważ wie, że ścieżka zawiera ścieżkę internetową ( MTU 1500) narzut z tunelu IPsec. Router zmodyfikował również nasz wysłany MSS 8961, aby pojawiał się jako 1419 na drugim hoście. Nazywa się to zaciskaniem MSS .

W pewnym sensie PMTUD dzieje się cały czas. W praktyce może się to nigdy nie zdarzyć, jeśli blokowanie MSS jest na miejscu, a cały ruch odbywa się przez TCP lub jeśli żaden z routerów nie ma MTU mniejszej niż skonfigurowana w punktach końcowych. Nawet bez blokowania MSS może się to zdarzyć rzadko, gdy pamięć podręczna wygaśnie.

Phil Frost
źródło