Il problema dell’affidabilità su rete IP
IP è un protocollo best-effort: consegna i pacchetti nel modo migliore possibile ma non garantisce nulla. I datagrammi possono andare persi, duplicati, riordinati, corrotti. TCP costruisce un servizio affidabile sopra IP attraverso tre meccanismi fondamentali: numerazione dei byte, acknowledgment e ritrasmissione.
Numerazione dei byte e ACK cumulativo
TCP tratta i dati come un flusso continuo di byte. Ogni byte ha un numero di sequenza. Il campo Sequence Number nell’header indica il numero del primo byte del payload trasportato in quel segmento.
Mittente invia: Seg 1: seq=1001, payload="Hello" → 5 byte, occupa seq 1001-1005 Seg 2: seq=1006, payload=" World" → 6 byte, occupa seq 1006-1011 Ricevitore risponde: ACK=1006 (ho ricevuto fino a 1005, attendo 1006) ACK=1012 (ho ricevuto fino a 1011, attendo 1012)
L’ACK è cumulativo: il valore indica il numero del prossimo byte atteso, quindi implicitamente conferma la ricezione di tutti i byte precedenti. Questo semplifica la gestione ma ha un limite: se arriva il segmento 3 prima del 2, il ricevitore non può riscontrare il 3 senza prima riscontrare il 2 (SACK risolve questo problema).
Timeout e ritrasmissione — stima dell’RTT
Se un ACK non arriva entro il RTO (Retransmission TimeOut), il mittente ritrasmette il segmento. Il timeout non può essere fisso: una rete WAN ha RTT molto diverso da una LAN locale. TCP deve stimare dinamicamente l’RTT.
Algoritmo di Jacobson/Karels (RFC 6298)
SRTT = (1 − α) × SRTT + α × RTT_campione α = 0.125 (1/8) RTTVAR = (1 − β) × RTTVAR + β × |SRTT − RTT_campione| β = 0.25 (1/4) RTO = SRTT + 4 × RTTVAR Minimo RTO raccomandato: 1 secondo Backoff esponenziale: ogni ritrasmissione raddoppia il RTO
SRTT (Smoothed RTT) è una media mobile esponenziale che filtra le fluttuazioni. RTTVAR misura la variabilità del RTT. Il fattore 4×RTTVAR aggiunge un margine di sicurezza proporzionale alla varianza — reti con RTT variabile ottengono automaticamente un timeout più generoso.
Algoritmo di Karn
Quando un segmento viene ritrasmesso e arriva un ACK, non è possibile sapere se l’ACK risponde all’invio originale o alla ritrasmissione. Usare questo campione di RTT porta a stime errate. Karn’s Algorithm: non usare i campioni di RTT ottenuti da segmenti ritrasmessi per aggiornare SRTT/RTTVAR. Durante il backoff esponenziale il RTO viene raddoppiato ad ogni ritrasmissione, e non viene aggiornato finché non arriva un ACK di un segmento non ritrasmesso.
SACK — Selective Acknowledgment
Il limite dell’ACK cumulativo emerge in caso di perdita: se manca il segmento 5 ma sono arrivati 6, 7, 8, il ricevitore non può dirlo al mittente con un semplice ACK. Il mittente deve ritrasmettere tutto a partire dal 5. SACK (RFC 2018) risolve il problema.
Mittente invia segmenti: 1, 2, 3, 4, 5, 6, 7, 8 Rete perde: 3 Ricevitore ha: 1,2, [buco], 4,5,6,7,8 ACK cumulativo: ACK=3 (attendo il 3, non so altro) SACK option: ACK=3, SACK=[4-8] ← "ho ricevuto 4-8, manca solo 3!" Mittente ritrasmette: solo il segmento 3
SACK è negoziato durante il three-way handshake tramite l’opzione SACK-Permitted. Se entrambi i lati la supportano, il ricevitore può segnalare fino a 4 blocchi SACK per segmento (l’opzione occupa al massimo 40 byte nello spazio opzioni TCP).
ACK duplicati e Fast Retransmit
Se il ricevitore riceve un segmento fuori ordine (es. il 5 arriva ma mancava il 3), continua a mandare ACK=3. Il mittente riceve così più ACK con lo stesso valore: ACK duplicati.
| N° di ACK duplicati | Interpretazione | Azione mittente |
|---|---|---|
| 1–2 | Probabile riordinamento in rete | Attendi |
| 3 | Segnale forte di perdita | Fast Retransmit: ritrasmissione immediata senza attendere timeout |
Il timeout RTO segnala una perdita grave (nessun segnale dalla rete). Il Fast Retransmit (3 ACK duplicati) segnala una perdita lieve (la rete funziona, ma un segmento è andato perso). La risposta è diversa: il timeout porta TCP in Slow Start, il Fast Retransmit attiva Fast Recovery (più aggressivo). Il comportamento è dettagliato nella lezione sul controllo della congestione (L07).
Gestione dei segmenti fuori ordine
I segmenti che arrivano fuori ordine vengono bufferizzati dal ricevitore (non scartati). Quando il segmento mancante arriva, il ricevitore ricompone il flusso in ordine e invia un ACK cumulativo che riscontra tutti i byte ricevuti in sequenza.
La capacità di bufferizzare segmenti fuori ordine dipende dalla receive window (rwnd) del ricevitore. Se il buffer è pieno, i segmenti fuori ordine vengono scartati — questo porta a ulteriori ritrasmissioni. Il dimensionamento del buffer TCP è un parametro critico per le performance in reti ad alta latenza (es. satellitari).
- Numeri di sequenza: ogni byte è numerato — il ricevitore riordina i segmenti fuori ordine
- ACK cumulativo: il valore indica il prossimo byte atteso, conferma implicitamente tutti i precedenti
- RTO calcolato dinamicamente con SRTT + 4×RTTVAR; backoff esponenziale ad ogni ritrasmissione
- Algoritmo di Karn: non aggiornare SRTT/RTTVAR con campioni da segmenti ritrasmessi
- SACK (RFC 2018): il ricevitore segnala blocchi non contigui ricevuti → il mittente ritrasmette solo ciò che manca davvero
- Fast Retransmit: 3 ACK duplicati triggherano ritrasmissione immediata senza attendere il timeout RTO