Як правило, виявлення максимальної одиниці передачі шляху (PMTUD) відбувається, коли хост вважає, що пакет був упущений через занадто великий розмір.
Це може бути у відповідь на необхідну відповідь про фрагментацію ICMP (тип 3, код 4), що явно вказує на те, що пакет відпав. У типовій практиці всі пакети IPv4 встановлюються набором прапора "не фрагмент" (DF), тому будь-який пакет, що перевищує MTU, викликає таку відповідь. IPv6 взагалі не підтримує фрагментацію.
Деякі маршрутизатори або хост-брандмауери часто скидають усі ICMP, оскільки наївний адміністратор вважає ICMP ризиком для безпеки . Або деякі схеми агрегації ланок можуть порушити доставку ICMP . У RFC4821 запропоновано альтернативний механізм виявлення MTU, який не покладається на ICMP .
tracepath
- мій улюблений інструмент Linux для зондування MTU. Ось приклад хоста з 9001 MTU в локальній мережі, але який повинен пройти IPsec VPN, щоб досягти 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]
Помилки ICMP можна спостерігати за 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
Відкриття MTU зберігаються в кеші. У Linux це можна помітити і переконатись ip
(будьте обережні щодо змін після Linux 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
Для TCP перевищення MTU може уникнути як частина налаштування з'єднання. Має максимальний розмір сегмента (MSS), що входить до SYN, що надсилається кожним кінцем. Заголовок TCP (20 байт без урахування параметрів ) і IP-заголовок (20 байт) означають, що MSS і MTU пов'язані різницею в 40 байт.
Ось приклад налаштування з'єднання між цими двома хостами при передачі великого файлу за допомогою 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
У першому пакеті локальний хост пропонує MSS 8961. Це налаштований 9001 MTU, менше 40 байт. Повернений SYN / ACK має MSS 1379, що означає MTU 1419. Я випадково знаю, що в цій мережі віддалений хост також надіслав 8961, але значення було змінено маршрутизатором, оскільки він знає, що шлях включає Інтернет-шлях ( MTU 1500) накладні витрати з тунелю IPsec. Цей маршрутизатор також змінив наш відправлений MSS 8961, щоб він відображався як 1419 у іншого хоста. Це називається затисканням MSS .
Тож у певному сенсі PMTUD відбувається постійно. На практиці це дійсно може статися ніколи, якщо затискання MSS не відбувається і весь трафік відбувається через TCP або якщо жоден з маршрутизаторів не має MTU, менший, ніж налаштовано на кінцевих точках. Навіть без затискання MSS це може траплятися лише рідко, коли кеш закінчується.