Datagramy UDP mają niewiele wspólnego z rozmiarem MTU, możesz je ustawić tak duże, jak chcesz, aż do 64K, jak wspomniano powyżej. Możesz nawet wysłać jeden z nich w całym pakiecie, o ile używasz dużych ramek o rozmiarze większym niż duży datagram.
Jednak ramki typu jumbo muszą być obsługiwane przez cały sprzęt, który będzie pomijany, co stanowi problem. Dla celów praktycznych ramki Ethernet są najczęstszym rozmiarem transportu, MTU dla nich wynosi około 1500 bajtów, powiem 1500 w przyszłości, ale nie zawsze. Gdy utworzysz datagram UDP większy niż podstawowa jednostka MTU (która, jak wskazano, to najczęściej ethernet), zostanie on po cichu podzielony na 1500 ramek bajtowych. Jeśli tcpdump ten ruch, zobaczysz liczbę pakietów uszkodzonych na granicy MTU, które będą miały ustawione więcej flag fragmentów wraz z liczbą fragmentów. Pierwszy pakiet będzie miał numer fragmentu 0, a więcej ustawionych fragmentów, a ostatni będzie miał niezerową liczbę fragmentów i więcej nie ustawionych fragmentów.
Dlaczego więc to obchodzi? Szczegóły dotyczące implementacji mają znaczenie. Fragmentacja może zaszkodzić wydajności w sieci, nie jest to już duży problem, ale jeden, o którym należy pamiętać. Jeśli użyje się ogromnego rozmiaru datagramu, to w przypadku utraty jakiegokolwiek fragmentu całe datagramy będą musiały zostać wysłane ponownie. Równie przy dużych ilościach, a dziś są to objętości doskonale osiągalne, wówczas możliwe jest błędne skojarzenie ram przy ponownym montażu. Mogą również wystąpić problemy z uzyskaniem fragmentów pakietów UDP w celu przejścia przez konfiguracje zapory korporacyjnej, w których moduły równoważące obciążenie rozłożą pakiety, jeśli jeden fragment znajduje się na jednej zaporze, a drugi na innym, ruch zostanie odrzucony jako niekompletny.
Nie twórz więc datagramów UDP większych niż fragmentacja wielkości MTU, chyba że musisz i musisz określić, że infrastruktura, która jest komunikowana między nimi, jest zamknięta (ta sama podsieć zamknięta), w którym to momencie jumbo ramki byłyby prawdopodobnie dobrą opcją.
By default, Linux UDP does path MTU (Maximum Transmission Unit) discovery. This means the kernel will keep track of the MTU to a specific target IP address and return EMSGSIZE when a UDP packet write exceeds it.
Warstwa IP podzieli twój pakiet na końcu wysyłającym, a następnie ponownie złoży go z powrotem na końcu odbierającym, przed przekazaniem go do UDP. Z warstwy UDP nie można tak naprawdę stwierdzić, że pakiet został pofragmentowany. Jeśli używasz narzędzia do przechwytywania pakietów, takiego jak Wireshark , powinieneś zobaczyć, że twój komputer odbiera pakiety IP ograniczone do MTU.
źródło
Okazuje się, że zezwolenie stosowi TCP / IP na fragmentowanie pakietów w razie potrzeby jest znacznie niższe narzut niż wysyłanie pojedynczych pakietów.
źródło
UDP nic nie wie o MTU. Pakiety UDP mogą mieć dowolny rozmiar od 8 do 65535 bajtów. Warstwy protokołu poniżej UDP albo mogą wysłać pakiet o określonym rozmiarze, albo odrzucą wysyłanie tego pakietu z błędem, jeśli jest zbyt duży.
Warstwa poniżej UDP to zwykle IP, IPv4 lub IPv6. A pakiet IP może mieć dowolny rozmiar od 20 (IPv4) / 40 (IPv6) do 65535 bajtów, czyli tyle samo co UDP. Jednak IP obsługuje mechanizm zwany fragmentacją . Jeśli pakiet IP ma większy rozmiar niż ten, który może transportować poniższa warstwa, IP może podzielić pojedynczy pakiet na wiele pakietów zwanych fragmentami. Każdy fragment jest w rzeczywistości własnym pakietem IP (ma własny nagłówek IP) i jest również wysyłany samodzielnie do miejsca docelowego; zadaniem miejsca docelowego jest zebranie wszystkich fragmentów i odbudowanie z nich pełnego pakietu przed przekazaniem odebranych danych na następnej wyższej warstwie (np. UDP).
Protokół Ethernet może transportować tylko ramki o ładunku między 46 a 1500 bajtów (są wyjątki, ale wykracza to poza zakres tej odpowiedzi). Jeśli dane ładunku są mniejsze niż 46 bajtów, są dopełniane, aby mieć dokładnie 46 bajtów. Jeśli dane ładunku przekraczają 1500 bajtów, interfejs odmówi ich przyjęcia. Jeśli tak się stanie, to od warstwy IP zależy teraz fragmentowanie pakietu, aby żaden fragment nie był większy niż 1500 bajtów, lub zgłoszenie błędu do następnej wyższej warstwy, jeśli fragmentacja została wyłączona lub zabroniona dla tego konkretnego połączenia.
Na ogół należy unikać fragmentacji, jak
Właśnie dlatego TCP inteligentnie przyjmuje rozmiar ramki, aby pakiety nigdy nie wymagały IP do ich fragmentacji. Można tego dokonać zakazując fragmentacji pakietów IP, a jeśli IP zgłasza, że pakiet jest zbyt duży, aby go wysłać, TCP zmniejsza rozmiar ramki i próbuje ponownie, dopóki nie zostanie zgłoszony żaden błąd.
Jednak w przypadku UDP byłoby to zadaniem samej aplikacji, ponieważ UDP jest „głupim” protokołem, nie ma własnej logiki zarządzania, co czyni go bardzo elastycznym, szybkim i prostym.
Jedyny rozmiar UDP, na którym można zawsze polegać na transporcie, to 576 minus 8 bajtów nagłówka UDP i minus 20 (v4) / 40 (v6) bajtów nagłówka IP, ponieważ standard IP wymaga, aby każdy host IP mógł odbierać pakiety IP z całkowity rozmiar 576 bajtów. Implementacja protokołu nie będzie zgodna ze standardem, jeśli nie będzie akceptować pakietów co najmniej tego rozmiaru. Zauważ jednak, że standard nie mówi 576 bez fragmentacji, więc nawet pakiet 576 bajtów może zostać podzielony między dwa hosty.
Jedyny rozmiar pakietu, na którym można polegać, że można go przenosić bez fragmentacji, to 24 bajty dla IPv4 i 56 bajtów IPv6, ponieważ najmniejsze nagłówki IP dla fragmentu to 20/48 bajtów (v4 / v6), a fragment musi mieć co najmniej 4/8 dane ładunku bajtów (v4 / v6). Zatem system transportowy poniżej warstwy IP, który nie może transportować co najmniej pakietów o tych rozmiarach, nie może być wykorzystywany do transportu ruchu IP.
I zanim ktokolwiek komentuje, że nagłówek IPv6 ma tylko 40 bajtów: To prawda, ale w przeciwieństwie do nagłówka IPv4, standardowy nagłówek IPv6 nie ma pól nagłówka do fragmentacji. Jeśli pakiet musi zostać pofragmentowany, nagłówek rozszerzenia fragmentacji należy dodać poniżej nagłówka podstawowego IPv6, a ten nagłówek rozszerzenia ma 8 bajtów. Również w przeciwieństwie do IPv4, przesunięcia fragmentacji w IPv6 są liczone w 8 bajtach, a nie w 4 bajtach, dlatego fragment może przenosić tylko ładunek będący wielokrotnością 8 bajtów w przypadku IPv6.
źródło
Aby odpowiedzieć na twoje pytanie: „Jeśli rozmiar samej ramki wynosi maksymalnie 1472 bajtów (jak w moim podręczniku), w jaki sposób rozmiar pakietu IP może być większy niż ten, który jest tutaj 65535?”
Wynika to z funkcji odciążania zwanej UFO (UDP Fragmentation Offload). Proszę odnieść się do tego linku.
Możesz weryfikować i przełączać funkcje rozładowywania za pomocą odpowiednio ethtool -k ethX i ethtool -K ethX.
źródło
Jeśli monitorujesz wychodzące ramki, możliwe, że karta sieciowa obsługuje odciążanie segmentacji i jest włączona. Po włączeniu odciążania segmentacji sama karta sieciowa obsługuje segmentację pakietu / ramki do odpowiedniego rozmiaru, a nie stosu sieciowego. To zwalnia procesor komputera do wykonywania innych zadań, poprawiając wydajność. W systemie Linux „ethtool -k [device]” pokaże flagi odciążania.
źródło