Controllo della congestione in TCP

Da Wikipedia, l'enciclopedia libera.

Il controllo della congestione in TCP è una funzionalità di controllo di trasmissione da parte di TCP che permette di limitare la quantità di dati trasmessi sotto forma di pacchetti e non ancora riscontrati dal mittente, adattando il flusso dati inviato all'eventuale stato di congestione della rete. Tale stato è desunto indirettamente a partire da informazioni ricavabili dallo stato della trasmissione dei pacchetti da parte di un terminale, evitando così congestione nella rete stessa.

Descrizione[modifica | modifica wikitesto]

TCP è uno dei protocolli di trasporto più diffusi nelle reti IP, ed attua il controllo della congestione. UDP non implementa invece alcuna forma di controllo di flusso o della congestione, anche se queste funzionalità possono essere realizzate al livello applicazioni.

Il TCP implementa il controllo della congestione, congiuntamente al controllo di flusso, solo agli estremi della comunicazione/connessione, e non richiede nessun supporto da parte dei router intermedi per realizzare questa funzione. Questo è coerente con il modello progettuale di IP, che prevede di aggiungere "intelligenza" ovvero funzioni di elaborazione ai nodi terminali lasciando ai router mansioni meno complesse e proprie del livello di rete. Un'ulteriore motivazione di questo dettaglio implementativo risiede nel fatto che lo stesso protocollo IP non offre alcun feedback esplicito sulla congestione della rete.

Tale controllo è realizzato in modo reattivo anziché preventivo ovvero valutando istante per istante lo stato di congestione di rete (a partire da variazioni del Round Trip Time e/o da ridotta presenza di ACK) e agendo di conseguenza.

In particolare, il suo funzionamento si basa sull'uso di una variabile del TCP detta CongWin (Congestion window, ovvero "finestra di congestione"). Tale variabile impone un vincolo alla quantità di dati trasmessi e non ancora riscontrati dal mittente, ovvero i dati che sono stati consegnati per la trasmissione al livello di rete, che sono in viaggio sulla rete o in fase di elaborazione da parte di TCP sul nodo destinazione, o i cui ACK sono a loro volta in viaggio sulla rete stessa.

Se il mittente rileva che sul percorso di invio dei pacchetti si verificano condizioni di scarso traffico, incrementa il tasso a cui trasmette i pacchetti, mentre al contrario, se il traffico rilevato è alto, lo riduce.

Si fissa un valore massimo per tale finestra di trasmissione, si assume uno stato di congestione quando si ha perdita di pacchetti (ovvero mancanza di ACK alla scadenza del time-out relativo al segmento da ricevere) ed infine si regola costantemente la finestra di trasmissione a seconda del livello di congestione di rete rilevato modulando il tasso di trasmissione dei pacchetti inviati e apportando così la necessaria stabilità: maggiore è il livello di congestione più piccola sarà la finestra di trasmissione, viceversa minore sarà il livello di congestione maggiore sarà la finestra di trasmissione.

Nello specifico la quantità di dati non riscontrati dal mittente non può essere superiore al minimo tra i valori di CongWin e RcvWindow, ovvero: LastByteSent - LastByteAcked <= min(CongWin, RcvWindow)

Questo vincolo limita la frequenza trasmissiva del mittente solo in modo indiretto. Supponendo che un host A invii segmenti ad un host B all'inizio di ogni RTT (Round Trip Time), il vincolo consente al mittente di trasmettere CongWin Byte sulla propria connessione; al termine dell'RTT il mittente riceve il riscontro dei dati. Da ciò si evince che la frequenza di invio del mittente è CongWin/RTT byte/sec, quindi il mittente può regolare la frequenza di invio di segmenti sulla propria connessione modificando il valore di CongWin.

In presenza di congestione nella rete, le code nei commutatori diventano più lunghe, e questo fa aumentare il ritardo subito dai pacchetti e dai relativi riscontri, e quindi l'RTT. Questo comporta una diminuzione della velocità di trasmissione di tutte le sessioni TCP attive.

L'algoritmo di controllo di congestione presenta due fasi:

  1. Partenza Lenta - Slow Start (Slow-Start)
  2. aumento additivo - diminuzione moltiplicativa (AIMD)

Per distinguere tra le due fasi viene usata una variabile chiamata SSTHRESH. Quando il valore della CongWin è minore del valore di SSTHRESH ci troviamo nella fase di 'Slow-Start', altrimenti siamo nella fase AIMD. All'avvio della trasmissione la variabile viene settata ad un valore molto alto, mentre la dimensione della CongWin è pari alla dimensione di un segmento.

Se la congestione diventa eccessiva, uno o più buffer dei router lungo il percorso vanno in overflow, causando l'eliminazione di un datagramma IP che contiene un segmento TCP.

Quando avviene un evento di perdita dati, che viene rilevato allo scadere di un timeout di ritrasmissione, TCP reagisce dimezzando il valore di SSTHRESH e reimpostando CongWin alla dimensione di un segmento, tornando quindi nella fase di Slow-Start.

Le formule per il calcolo della finestra di trasmissione sono:

MaxWindow = MIN(AdvertisedWindow, CongestionWindow)
EffectiveWindow = MaxWindow - (LastByteSent - LastByteAcked)

con il seguente significato delle variabili:

MaxWindow indica la quantità massima di dati che il mittente può inviare
AdvertisedWindow indica la quantità massima di dati che la rete può accettare (ritardo * ampiezza di banda)
EffectiveWindow indica i dati effettivi che il mittente può ancora spedire
LastByteSent indica l'ultimo byte inviato dalla sorgente (che può anche non essere stato confermato dalla destinazione)
LastByteAcked indica l'ultimo byte confermato dalla destinazione

Politiche per il controllo della congestione[modifica | modifica wikitesto]

Gli eventi che indicano al sender la perdita di dati trasmessi sono:

  1. ACK non riscontrati allo scadere del timer (time-out).
  2. ACK duplicati ricevuti 3 volte.

Esistono due algoritmi per il controllo della congestione: il primo, l'algoritmo di Tahoe, non distingue tra gli eventi sopra elencati, mentre il secondo, l'algoritmo di Reno, fa una netta distinzione tra i due casi.

TCP Tahoe[modifica | modifica wikitesto]

TCP Tahoe prevede che ogni qual volta si verifichi un evento perdita (o evento di congestione) di qualsiasi tipo, la finestra di congestione venga dimezzata e questo nuovo valore viene memorizzato nella variabile soglia SSTHRESH. Fatto questo la trasmissione dei dati ricomincia impostando il valore iniziale della finestra di congestione corrente pari ad 1 MSS (massima dimensione di un segmento TCP). Si ha quindi una 'ripartenza lenta' o slow start, ovvero la crescita della finestra di congestione avviene progressivamente (seguendo un trend esponenziale nel tempo) fino a raggiungere il valore di soglia prima determinato. Oltre questo valore la crescita avviene linearmente nel tempo (in tal caso si parla di fase di congestion avoidance) fino a quando non si verifica nuovamente un evento perdita e l'algoritmo viene rieseguito. È importante sottolineare come la riduzione della finestra di congestione ad 1 MSS comporti una repentina riduzione della velocità di trasmissione dei dati nella connessione TCP. Questo effetto, da un lato, de-congestiona la rete, ma, dall'altro, limita temporaneamente (ma fortemente) la velocità di trasmissione/ricezione dei dati. Pertanto, la crescita esponenziale fino al livello di soglia consente alla connessione TCP di recuperare prontamente (ma parzialmente) una parte della banda ormai persa in seguito all'evento di congestione. Una volta raggiunto il livello di soglia, la crescita avviene lentamente per sondare il livello di banda effettivamente disponibile in rete e cercare di raggiungere nuovamente il livello di congestione il più lentamente possibile. Un ulteriore approfondimento meritano i meccanismi che producono l'incremento del valore della finestra di congestione durante le fasi slow start e congestion avoidance. Durante la slow start, la finestra di congestione viene incrementata di una quantità pari ad 1 MSS per ogni riscontro (o ACK) ricevuto, da cui scaturisce il trend di crescita esponenziale nel tempo. Nella fase di congestion avoidance, invece, la finestra di congestione è incrementata di 1 MSS ogni qual volta venga riscontrata una quantità di pacchetti pari all'attuale valore della finestra di congestione. Poiché il tempo necessario a riscontrare una finestra di pacchetti è proprio pari ad RTT, ne scaturisce il trend di crescita lineare della finestra di congestione durante la fase di congestion avoidance. Si riporta per convenienza e per chiarezza lo pseudo-codice semplificato dell'algoritmo di controllo di congestione Tahoe:

  • ACK ricevuto
se CongWin < SSTHRESH allora CongWin=CongWin+1
altrimenti CongWin=CongWin+1/CongWin
  • 3 ACK duplicati ricevuti o timeout espirato
SSTHRESH=CongWin/2
CongWin=1 MSS

TCP Reno[modifica | modifica wikitesto]

TCP Reno distingue tra i due eventi di perdita sopra elencati:

  • In caso di perdita dovuta al timeout del timer, viene applicato l'algoritmo di Tahoe, poiché si assume che la rete sia talmente congestionata da non essere in grado di far passare nessun altro pacchetto, quindi:
  1. Si fa ripartire la trasmissione impostando la finestra corrente al valore minimo di 1 MSS.
  2. Si ricomincia con la partenza lenta con crescita esponenziale.
  • Quando invece l'evento perdita è generato dalla ricezione di 3 ACK duplicati, il TCP Reno assume che la rete è ancora in grado di trasferire qualcosa. In tal caso si entra nella cosiddetta fase di Fast Recovery. Essa consiste in una riduzione meno drastica della finestra di congestione.
  1. Il valore soglia viene impostato alla metà del valore della finestra di congestione al momento della ricezione di tre ack duplicati.
  2. La trasmissione riparte impostando il valore di finestra corrente pari al valore di soglia e proseguendo nell'invio con un incremento lineare di 1 MSS ad ogni RTT il valore della finestra di congestione.

Si riporta per maggiore chiarezza lo pseudo-codice semplificato dell'algoritmo di controllo di congestione Reno:

  • ACK ricevuto
se CongWin < SSTHRESH allora CongWin=CongWin+1
altrimenti CongWin=CongWin+1/CongWin
  • 3 ACK duplicati ricevuti (Fast Recovery)
SSTHRESH=CongWin/2
CongWin=CongWin/2
  • Timeout espirato
SSTHRESH=CongWin/2
CongWin=1 MSS

Un esempio di controllo della congestione con TCP-RENO:

TCP-RENO.png

TCP New Reno[modifica | modifica wikitesto]

Il TCP Reno risolve in parte il problema di perdite non dovute a congestione solo quando le perdite non sono fortemente correlate tra loro, cioè quando si perde al massimo un pacchetto all'interno di ogni finestra. Questo comportamento è problematico nelle situazioni in cui si perdono interi burst di pacchetti (situazione frequente ad esempio nei collegamenti wireless). Infatti, in questi casi TCP Reno potrebbe ridurre il valore della finestra di congestione più volte consecutivamente (ovvero tante volte quanti sono i pacchetti persi) causando un drastico peggioramento della velocità di trasmissione della connessione TCP. TCP New Reno cerca di aggirare il problema basandosi sul sistema degli ACK parziali. Vengono considerati ACK parziali gli ACK che riscontrano pacchetti intermedi, e non gli ultimi pacchetti che necessiterebbero riscontro, dopo che è stata già iniziata la fase di Fast Recovery in seguito all'arrivo di tre ack duplicati. Quando uno di questi ack si presenta durante una fase di Fast Recovery (cioè in seguito alla ricezione di 3 ack duplicati), TCP New Reno si mantiene in tale fase continuando a reinviare i pacchetti via via richiesti finché non viene riscontrato l'ultimo pacchetto inviato nella fase precedente all'ingresso in Fast Recovery.

Gestione del Retransmission Timeout[modifica | modifica wikitesto]

Nelle precedenti sezioni si è visto come il timeout per la gestione delle ritrasmissioni (Retransmission Timeout o RTO) sia utilizzato negli algoritmi di controllo di congestione del TCP. Tuttavia è anche importante spiegare a quale valore e secondo quali modalità l'RTO venga impostato dal TCP. A tal riguardo, si noti che condizione necessaria a garantire il corretto funzionamento del meccanismo di timeout sia quella di utilizzare un valore di RTO maggiore di RTT (RTO > RTT). La violazione di tale condizione infatti comporterebbe l'occorrenza di timeout spuri (ovvero di timeout espirati poiché troppo brevi rispetto al tempo impiegato ai riscontri per raggiungere il mittente dei dati). Tuttavia, il valore di RTT di una connessione TCP varia continuamente durante la trasmissione dei dati a causa dei ritardi di accodamento variabili che si riscontrano in rete. Questo comporta la necessità di impiegare un meccanismo per l'adattamento dinamico dell'RTO che possa quindi garantire il soddisfacimento della condizione RTO > RTT anche quando l'RTT varia nel tempo. Il TCP calcola il valore di RTO come segue:

RTOSRTT + 4 × DEV,

dove SRTT rappresenta la media dei valori di RTT misurati e DEV una stima della deviazione standard della variabile RTT. Qualora si verifichino espirazioni del timer consecutive, il valore di RTO viene progressivamente raddoppiato.

Equità[modifica | modifica wikitesto]

L'equità in una rete a commutazione di pacchetto misura in che modo la banda di una rete viene ripartita tra i flussi dati attivi. Nel caso di una rete composta da un unico collegamento a collo di bottiglia avente banda pari a R bps, condiviso da K connessioni TCP, la perfetta equità corrisponde ad una ripartizione uniforme della banda R tra le K connessioni attive. In altre parole, la perfettà equità viene raggiunta se ciascuna delle K connessioni TCP ottiene a regime una velocità media di trasmissione dei dati pari a R/K. Nel caso del TCP, questa condizione può verificarsi solo quando le K connessioni presentano lo stesso RTT (Round Trip Time). Infatti, la velocità media di trasmissione dei dati di una connessione TCP è inversamente proporzionale al suo RTT. Queste considerazioni sono valide in presenza di applicazioni persistenti, ovvero in grado di trasmettere senza interruzioni quantità di dati teoricamente infinita.

Voci correlate[modifica | modifica wikitesto]

Collegamenti esterni[modifica | modifica wikitesto]

Telematica Portale Telematica: accedi alle voci di Wikipedia che parlano di reti, telecomunicazioni e protocolli di rete