Esattamente quando viene eseguito PMTUD? (Rilevamento MTU percorso)


21

Nelle discussioni che sono scaturite da altre domande su questo sito , mi sono reso conto che non ho una solida comprensione di quando viene eseguito Path MTU Discovery (PMTUD).

So cosa fa: scopri l'MTU più basso su un percorso dal client al server).
So come lo fa - invia pacchetti progressivamente più grandi con il loro bit impostato "Non frammentare", e vedi quanto è grande un pacchetto che puoi ottenere senza ottenere un errore "ICMP Need to Fragment".

La mia domanda è in particolare quindi, quando un host eseguirà PMTUD?

Sto cercando casi specifici. Non solo qualcosa di generico come "quando un host vuole scoprire il percorso MTU". Punti bonus se è possibile fornire un'acquisizione di pacchetti di un host che lo sta eseguendo o fornire istruzioni per generare tale acquisizione di pacchetti.

Inoltre, mi riferisco specificamente a IPv4. So che i router transitori IPv6 non sono responsabili della frammentazione e posso immaginare che PMTUD avvenga molto più comunemente. Ma per ora, sto cercando esempi specifici di PMTUD in IPv4. (anche se l'unica acquisizione di pacchetti che puoi mettere insieme di PMTUD è in IPv6, mi piacerebbe comunque vederlo)


PMTUD viene eseguito dall'MTU più basso supportato al più alto? Oppure il dispositivo che esegue PMTUD prova prima l'MTU più grande e poi fa un passo avanti di un grande incremento fino a quando il pacchetto non passa, quindi aumenta con incrementi più piccoli, quindi si alterna avanti e indietro fino a quando non viene presa una decisione finale?
cpt_fink,

@cpt_fink, ci sono alcune strategie. Le moderne implementazioni del messaggio ICMP Fragmentation Needed includono nel payload ICMP stesso l'MTU del collegamento per il quale era richiesta la frammentazione. Questo lo rende semplice, poiché l'host iniziale sa subito qual è il percorso MTU. Le implementazioni precedenti devono utilizzare varie strategie per "cercare" il giusto MTU da utilizzare. Tali strategie sono descritte in RFC1191 nella sezione 5. Esse vanno dal default automatico al minimo IP (576), all'uso di una tabella di MTU 'comuni' per effettuare ricerche più efficienti (vedere la sezione 7.1 di RFC1191).
Eddie,

2
Questa è una domanda interessante Stavo facendo un po 'di ricerche su PMTUD e l'ho trovato. Anche se è vecchio, ho deciso di rispondere perché avevo la stessa identica domanda e dopo alcune ore di ricerche sono riuscito a trovare una risposta abbastanza decente (immagino). Proverò ad aggiornare e supportare la mia risposta con un'acquisizione di pacchetti domani, se possibile.
Filipe Gonçalves,

Risposte:


15

La risposta è semplice: ogni volta che l'ospite piace. Veramente. È così semplice.

La spiegazione seguente presuppone un ambiente solo IPv4, poiché IPv6 elimina la frammentazione nei router (costringendo l'host a gestire sempre la frammentazione e il rilevamento MTU).

Non esiste una regola rigida che regola quando (o anche se) un host esegue il rilevamento MTU Path. Il motivo per cui PMTUD è emerso è che la frammentazione è considerata dannosa per vari motivi. Per evitare la frammentazione dei pacchetti, il concetto di PMTUD è stato realizzato come soluzione alternativa. Naturalmente, un buon sistema operativo dovrebbe usare PMTUD per ridurre al minimo la frammentazione.

Quindi, naturalmente, la semantica esatta di quando viene utilizzato PMTUD dipende dal sistema operativo del mittente, in particolare l'implementazione del socket. Posso parlare solo per il caso specifico di Linux, ma probabilmente altre varianti UNIX non sono molto diverse.

In Linux, PMTUD è controllato IP_MTU_DISCOVERdall'opzione socket. È possibile recuperare il suo stato corrente getsockopt(2)specificando il livello IPPROTO_IPe l' IP_MTU_DISCOVERopzione. Questa opzione è valida SOCK_STREAMsolo per i socket (un SOCK_STREAMsocket è un socket bidirezionale, orientato alla connessione, affidabile; in pratica è un socket TCP, anche se sono possibili altri protocolli) e, quando impostato, Linux eseguirà PMTUD esattamente come definito in RFC 1191.

Si noti che in pratica, PMTUD è un processo continuo; i pacchetti vengono inviati con il set di bit DF - inclusi i pacchetti di handshake a 3 vie - puoi considerarlo come una proprietà di connessione (anche se un'implementazione potrebbe essere disposta ad accettare un certo grado di frammentazione a un certo punto e interrompere l'invio di pacchetti con DF bit impostato). Pertanto, PMTUD è solo una conseguenza del fatto che tutto su quella connessione viene inviato con DF.

Cosa succede se non si imposta IP_MTU_DISCOVER?

C'è un valore predefinito. Per impostazione predefinita, IP_MTU_DISCOVERè abilitato sui SOCK_STREAMsocket. Questo può essere letto o modificato leggendo /proc/sys/net/ipv4/ip_no_pmtu_disc. Un valore zero indica che IP_MTU_DISCOVERè abilitato per impostazione predefinita nei nuovi socket; un diverso da zero significa il contrario.

Che dire delle prese senza connessione?

Ciò è complicato perché le prese senza connessione e inaffidabili non ritrasmettono i segmenti persi. Diventa responsabilità dell'utente impacchettare i dati in blocchi di dimensioni MTU. Inoltre, l'utente dovrebbe effettuare le ritrasmissioni necessarie in caso di errore di messaggio troppo grande . Quindi, essenzialmente il codice utente deve reimplementare PMTUD. Tuttavia, se sei pronto per la sfida, puoi forzare il bit DF passando il IP_PMTUDISC_DOflag a setsockopt(2).

La linea di fondo

  • L'host decide quando (e se) utilizzare PMTUD
  • Quando utilizza PMTUD, è come un attributo di connessione, accade continuamente (ma in qualsiasi momento l'implementazione è libera di smettere di farlo)
  • Sistemi operativi diversi utilizzano approcci diversi, ma in genere socket affidabili e orientati alla connessione eseguono PMTUD per impostazione predefinita, mentre socket inaffidabili e senza connessione no

4

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.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.