In genere, il rilevamento di unità di trasmissione massima di percorso (PMTUD) si verifica ogni volta che un host ritiene che un pacchetto sia stato eliminato a causa dell'eccessiva dimensione.
Ciò può essere in risposta alla frammentazione ICMP richiesta (tipo 3, codice 4), che indica esplicitamente che il pacchetto è stato eliminato. Nella pratica tipica tutti i pacchetti IPv4 sono impostati con il flag "non frammentare" (DF) impostato, quindi qualsiasi pacchetto che supera l'MTU genererà tale risposta. IPv6 non supporta affatto la frammentazione.
Alcuni router o firewall host eliminano spesso tutti gli ICMP perché un amministratore ingenuo ritiene che ICMP rappresenti un rischio per la sicurezza . Oppure, alcuni schemi di aggregazione dei collegamenti potrebbero interrompere la consegna dell'ICMP . In RFC4821 viene proposto un meccanismo alternativo per scoprire l'MTU che non si basa su ICMP .
tracepath
è il mio strumento Linux preferito per sondare MTU. Ecco un esempio di un host con un MTU 9001 sulla LAN, ma che deve attraversare una VPN IPsec per raggiungere il 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]
Gli errori ICMP possono essere osservati con 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
Le scoperte di MTU sono memorizzate nella cache. In Linux questo può essere osservato e risolto ip
(attenzione alle modifiche da 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
Per TCP, il superamento dell'MTU può essere evitato come parte della configurazione della connessione. Incluso nel SYN inviato da ciascuna estremità è una dimensione massima del segmento (MSS). L'intestazione TCP (20 byte escluse le opzioni ) e l'intestazione IP (20 byte) indicano che MSS e MTU sono correlati da una differenza di 40 byte.
Ecco un esempio di configurazione della connessione tra questi due host quando si trasferisce un file di grandi dimensioni con 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
Nel primo pacchetto, l'host locale propone un MSS di 8961. Questa è la MTU 9001 configurata, meno 40 byte. Il SYN / ACK restituito ha un MSS di 1379, il che implica un MTU di 1419. Mi capita di sapere in questa rete anche l'host remoto ha inviato 8961, ma il valore è stato modificato da un router poiché sa che il percorso include un percorso Internet ( MTU 1500) un overhead da un tunnel IPsec. Questo router ha anche modificato il nostro MSS inviato di 8961 per apparire come 1419 sull'altro host. Questo si chiama bloccaggio MSS .
Quindi, in un certo senso, PMTUD sta accadendo tutto il tempo. In pratica, in realtà non può accadere mai, se il blocco MSS è in atto e tutto il traffico avviene su TCP o se nessuno dei router ha un MTU più piccolo di quello configurato sugli endpoint. Anche senza il blocco MSS, ciò può accadere solo raramente, quando la cache scade.