Introduzione
Note
Il TCP è un protocollo di trasporto che assicura il trasporto affidabile. Mediante TCP è possibile costruire applicazioni che si basano sul trasferimento di file senza errori tra host remoti. Il protocollo TCP effettua anche un controllo di congestione end-to-end che limita il traffico di rete e consente agli utenti di condividere in modo equo le risorse.
Connection oriented
TCP è orientato alla connessione, di conseguenza prima di cominciare il trasferimento dati è necessario instaurare una connessione mediante opportuna segnalazione. Inoltre le connessioni TCP si appoggiano su datagram e sono di tipo full-duplex.
Flusso di dati
Il TCP è orientato alla trasmissione di flussi continue di dati: i flussi sono convertiti in segmenti di dimensione variabile e sono accumulati in un buffer. Periodicamente il TCP prende una parte dei dati nel buffer e forma un segmento. Siccome la dimensione del segmento è critica per le prestazioni TCP cerca di attendere fino a che un ammontare ragionevole di dati non sia presente nel buffer di trasmissione.
Numerazione di bit e riscontri
Il TCP adotta un meccanismo per il controllo delle perdite di pacchetti di tipo Go-Back-N.
Il TCP numera ogni byte trasmesso, I segmenti sono formati da gruppi di byte. Nell’header TCP è trasportato il numero di sequenza del primo byte, e il ricevitore deve riscontrare i dati ricevuti inviando il numero di sequenza del prossimo byte che ci si aspetta. Se un riscontro non arriva entro un dato timeout, i dati sono ritrasmessi.
Formato
Header del segmento TCP
Definiamo i contenuti dell’header:
- Sequence Number: numero di sequenza del primo byte nel payload
- Acknowledge Number: numero di sequenza del prossimo byte che si intende ricevere
- HLEN: lunghezza totale dell’header TCP, multiplo di 32
- Window: valore della finestra di ricezione come comunicato dal ricevitore al trasmettitore
- Checksum: medesimo di UDP
- Flags:
URG: Vale1se vi sono dei dati urgenti e quindi TCP deve passare in modalità urgente.ACK: Vale1se il pacchetto è un ACK valido, cioè se contiene un acknowledge number validoPSH: Vale1quando il trasmettitore intende usare il comando di PUSH: il ricevitore può anche ignorare il comandoRST: reimposta la connessione senza un tear down esplicitoSYN: usato durante il setup per comunicare i numeri di sequenza inizialeFIN: usato per la chiusura esplicita di una connessione- Options e padding: riempimento (fino a 32 bit) e campi opzionali
Di seguito alcune opzioni aggiunte:
Maximum Segment Size
Definisce la dimensione massima del segmento che verrà usata nella connessione TCP. La dimensione è decisa dal mittente durante la fase di setup. Di default è 536 byte.
Fattore di scala della finestra
Definisce il fattore di scala della finestra. Fa sì che venga moltiplicato il valore del campo Window di un fattore pari a 2 elevato al valore contenuto nel campo fattore di scala. Di default è 1.
Esempi di connessioni
Setup
- Il server fa una Passive Open, che comunica al TCP locale che è pronto per accettare nuove connessioni.
- Il client che desidera comunicare fa una Active Open, che comunica al TCP locale che l’applicativo intende effettuare una connessione verso un dato socket.
- Il client TCP estrae un numero di sequenza iniziale e invia un messaggio
SYN=1 contenente il numero di sequenza. Eventualmente indica anche i parametri aggiuntivi. Il numero casuale serve a evitare problemi nel caso il setup non vada a buon fine.- Quando riceve
SYN, il server TCP estrae un numero di sequenza iniziale e manda un segmentoSYN=1 eACK=1 contenendoANpari al numero estratto dal client.- Il client TCP riceve il messaggio
SYN/ACKdel server e inviaACKconANpari al numero estratto dal server. Inserisce anche la dimensione di finestra del server.- Il client notifica all’applicazione che la connessione è aperta.
- Quando il TCP server riceve l’
ACKdel client, notifica al suo applicativo che la connessione è aperta.
Tear down
- Il TCP che chiude la connessione invia un messaggio
FIN=1 con gli ultimi dati.- Il TCP che riceve il messaggio invia
ACKper confermare, lasciando comunque la connessione aperta.- Il TCP che ha ricevuto il messaggio invia quindi un messaggio
FIN=1.- Il TCP che ha inviato il messaggio iniziale risponde con un
ACKfinale.
Reset
La connessione può essere chiusa senza scambio di messaggio nei due versi, in quanto è possibile semplicemente interrompere la connessione impostando il flag di
RESET.
Controllo di flusso
Il lato TCP ricevente controlla il flusso di quello ricevente. In entrambi i lati esistono dei Buffer che accumulano byte ricevuti/in attesa di essere trasmessi.

Lo spazio del buffer in ricezione disponibile per ricevere nuovi dati è detto RCVWND, e si estende dall’ultimo byte inoltrato all’applicazione fino alla fine del buffer. Il buffer di ricezione può riempirsi in certi casi. La sua dimensione è segnalata in ogni segmento inviato dal ricevitore al trasmettitore.
Una il buffer di invio è detto SNDWND e rappresenta i byte che possono essere trasmessi senza attendere ulteriori riscontri. Contiene inoltre la dimensione della finestra di ricezione del partner. Si estende dal primo byte non riscontrato all’estremo a destra della finestra di ricezione del ricevitore.
Silly window syndrome
Questo problema si manifesta sia nel buffer di ricezione che in quello di invio e rallenta la trasmissione.
Nel ricevitore il buffer di ricezione viene svuotato lentamente, di conseguenza i segmenti sono inviati con una finestra molto piccola e il trasmettitore deve inviare segmenti corti con molto overhead.
Nel trasmettitore l’applicazione genera dati lentamente, e quindi invia segmenti molto piccoli man mano che vengono prodotti.
Algoritmo di Clark
Per evitare la Silly window syndrome nel ricevitore, esso mente al trasmettitore indicando una finestra nulla sino a che il suo buffer di ricezione non si è svuotato per metà o per una porzione almeno pari al MSS:
Algoritmo di Nagle
Per evitare la Silly window syndrome nel trasmettitore, esso invia la prima porzione di dati anche se corta, e gli altri dati vengono inviati solo se il buffer di uscita contiene dati sufficienti a riempire una
MMSoppure, quando si riceve unANper un segmento precedente.
Funzione Push
Note
TCP originariamente prevedeva una gestione speciale per i dati che richiedono di essere consegnati immediatamente, per ottenere l’invio immediato infatti l’applicazione può impostare il campo
PUSH, anche se generalmente non è disponibile nelle interfacce offerte dai linguaggi di programmazione, infatti è automaticamente impostato nell’ultimo segmento che svuota il buffer.
Dati URGENT
TCP dispone di una modalità urgent, che però per dei cambiamenti negli standard RFC non è stabile. Gli RFC successivi ribadiscono il cambiamento più recente, tuttavia alcuni dispositivi seguono ancora quello vecchi. Inoltre i sistemi operativi implementano urgent in maniera differente, è consigliabile non usare.
Controllo d’errore
Note
Il meccanismo di controllo d’errore del TCP serve a recuperare pacchetti persi in rete. La causa principale di tale perdita è l’overflow di una delle code dei router attraversati a causa della congestione. I dati vengono ritrasmessi usando Go-Back-N con timeout:
- TCP mantiene nel buffer anche i segmenti fuori ordine.
- Quando arrivano segmenti mancanti la finestra scorre in avanti fino al primo segmento non riscontrato in quelli ricevuti fuori ordine.
- Viene mandato un
ACKche riscontra collettivamente anche i segmenti fuori ordine.La finestra di trasmissione dipende dal meccanismo di controllo di flusso e di congestione.
Uno dei problemi è stabilire il valore ottimo del timeout. Il suo valore ottimale dipende fortemente dal ritardo di rete, quindi il TCP calcola dinamicamente un valore opportuno per il timeout stimando il RTT.
Il TCP adatta il timeout di trasmissione alle condizioni reali della rete tramite gli algoritmi di Karn e Jacobson: campioni di RTT sono definiti come il tempo che passa tra la trasmissione di un segmento e la ricezione del relativo riscontro. Quindi tramite l’algoritmo di Jacobson viene calcolato SRR (Smoothed Round Trip Time):
Viene stimata anche la deviazione standard dei :
E di essa viene calcolato un valore filtrato:
Sulla base di questi valori il timeout è calcolato come
Inizialmente vale .
Dopo la ritrasmissione è necessario passare all’algoritmo di Karn:
- non è aggiornato
- Il timeout è moltiplicato per un valore fisso (tipicamente 2)
- Il timeout cresce fino ad un valore massimo
- Dopo un numero massimo di ritrasmissioni la connessione viene chiusa.
Persistenza
Se il destinatario fissa a 0 la finestra di ricezione la sorgente TCP interrompe la trasmissione, e riprende solo quando il destinatario invia un
ACKcon una dimensione della finestra diversa da 0. Tuttavia se questoACKandasse perso la connessione rimarrebbe bloccata.Per evitare questa situazione si usa un timer di persistenza che viene attivato quando arriva un segmento con finestra nulla. Se il timer di persistenza scade, viene inviato un piccolo segmento sonda, in questo modo se viene ricevuto un
ACKsi esce dallo stato critico, altrimenti al nuovo scadere del timeout si re invia di nuovo.
Controllo della congestione
Note
Il controllo di flusso dipende dalla capacità del ricevitore. Tuttavia attualmente non esistono meccanismi di controllo di congestione a livello rete, esso è delegato a TCP e quindi è end-to-end. Il modo più naturale per controllare il ritmo di immissione in rete dei dati per il TCP è quello di regolare la finestra di trasmissione.
Il trasmettitore mantiene una Congestion Window (
CWND) che varia in base agli eventi osservati. Il trasmettitore non può trasmettere più del minimo traRCVWNDeCWND:L’idea di base del controllo di congestione del TCP è quella di interpretare la perdita di un segmento, come un evento di congestione, e la reazione è quella di ridurre
CWND, quindi riduco il rate equivalente sulla connessione TCP che sto valutando.
Il valore di CWND viene aggiornato dal trasmettitore TCP in base ad un algoritmo: Il modo in cuoi avviene l’aggiornamento si basa sulla fase del trasmettitore (Slow start e Congestion Avoidance). Lo stato è dettato dalla variabile SSTHRESH:
- Se
CWNDSSTHRESHsi è in Slow Start. - Se
CWNDSSTHRESHsi è in Congestion Avoidance.
Inizialmente, il trasmettitore pone CWND a 1 MSS e la SSTHRESH a un valore molto elevato, di conseguenza si parte in Slow Start. In questa modalità, la CWND viene incrementata di 1 per ogni ACK ricevuto. Al contrario di quanto il nome faccia credere infatti, l’incremento della finestra avviene in modo esponenziale. L’incremento può andare avanti fino a uno di questi eventi:
- Evento di congestione.
- Fino a che
CWNDSSTHRESH - Fino a che
CWNDRCWND
Insieme alla finestra aumenta anche il rate di trasmissione, che è stimato come
Evento di congestione
Un evento di congestione si verifica quando il ritmo di trasmissione porta in congestione un link sul percorso in rete verso la destinazione. Un link è definito congestionato quando la somma dei ritmi di trasmissione dei flussi che lo attraversano è maggiore delle sue capacità.
In caso scada il timeout di ritrasmissione il TCP reagisce ponendo
SSTHRESHpari alla metà dei byte trasmessi ma non riscontrati:Di solito i “byte in volo” sono una buona approssimazione pari all’ultima
CWND. Di conseguenza:
CWNDè minore diSSTHRESHe si entra nella fase di Slow Start- Il trasmettitore invia un segmento e la sua
CWNDè incrementata di 1 ad ogniACK.A questo punto il trasmettitore trasmette tutti i segmenti a partire da quello per cui il timeout è fallito (Go-Back-N), e il valore a cui è posta
SSTHRESHè una stima della finestra ottimale che eviterebbe futuri eventi di congestione.
La slow start continua fino a che CWND diventa grande come SSTHRESH e poi parte la fase di Congestion Avoidance. Durante questa fase si incrementa CWND di ad ogni ACK ricevuto. Se la CWND consente di trasmettere segmenti, la ricezione degli ACK relativi a tutti gli segmenti porta la CWND ad aumentare di 1 segmento.
In questa modalità quindi si attua un incremento lineare della finestra di congestione.
Altre funzionalità e informazioni
Condivisione equa delle risorse
È possibile dimostrare che in condizioni ideali il meccanismo di controllo del TCP è in grado di:
- Limitare la congestione in rete
- Consentire di dividere in modo equo la capacità dei link tra i diversi flussi
Le condizioni ideali sono alterate tra l’altro da:
- Differenti RTT per i diversi flussi
- Buffer nei nodi minori del prodotto bandaritardo
Fast Retransmit e Fast Recovery
Questa feature aggiuntiva al TCP classico è usata per ottimizzare la ritrasmissione del singolo pacchetto perso.
Se arrivano degli
ACKduplicati il pacchetto sarà andato perso, tuttavia saranno arrivati i pacchetti successivi. Se non c’è congestione possiamo incrementareCWNDdel numero di pacchetti sicuramente arrivati. Grazie a questa feature il trasmettitore trasmette il pacchetto perso dopo il terzoACKduplicato:
- Alla ricezione del terzo
ACKconsecutivo duplicato:
- Viene ritrasmesso il pacchetto indicato dall’
AN.- Si pone:
- Per ogni ulteriore
ACKduplicato ricevuto laCWNDviene incrementata di 1.- Vengono trasmessi nuovi segmenti se consentito dai valori di
CWNDeRWND.- Appena arriva un
ACKche riscontra nuovi dati si esce dalla fase di fast recovery e si pone di nuovo:
TCP nei sistemi operativi
Esistono diverse versioni di TCP, ma sono tutte retrocompatibili con le versioni base. TCP è implementato nel sistema operativo, infatti esistono versioni come ECN che viola la comunicazione tra livelli differenti. Esistono inoltre versioni adatte a connessioni ibride, dove le perdite sono dovute sia alla congestione che alla perdita sporadica legata a problemi di connessione radio.
La versione base TCP si chiama Tahoe.


