\
TCP/IP
Copyright © 1986 Universita'
di Firenze. All rights reserved.
Free license available.
INTERNET & APPLICATIONS
Transmission Control Protocol/Internet Protocol




Nel complesso del protocollo TCP/IP, l'User Datagram Protocol (UDP)
fornisce un servizio di recapito dei datagrammi connectionless ed inaffidabile, usando l'IP
per trasportare messaggi da una macchina ad un'altra; prevede delle porte di protocollo usate per distinguere
tra più programmi in esecuzione (o processi) su una singola macchina.
E' un protocollo di trasporto che si colloca sopra l'Internet Protocol Layer (IP):

E' simile all'IP, ma oltre ai dati spediti, ciascun messaggio UDP contiene sia il numero di porta di destinazione che quello
di origine, rendendo possibile al software UDP di destinazione di recapitare il messaggio al corretto ricevente (programma od utente),
ed a quest'ultimo di inviare una replica.
L'inaffidabilità è quella propria dell'IP, in quanto l'UDP non prevede nessun protocollo per il
controllo dell'errore, a differenza del TCP: non usa acknowledgement per assicurare al mittente
che i messaggi siano arrivati, non dispone le sequenze di datagrammi in ordine e non fornisce una retroazione per il
controllo del rate del flusso di informazioni tra macchine. Perciò i messaggi UDP possono essere persi, duplicati
oppure arrivare fuori dall'ordine; inoltre i datagrammi possono arrivare più velocemente di quanto il ricevente
sia in grado di processarli.
Il protocollo UDP lavora bene in una rete locale, ma potrebbe fallire se usato in una rete di maggiori dimensioni
Esso realizza un datagramma più utile di quello IP per i collegamenti fra utenti;
infatti, per fare un esempio, su tale base è stato costruito l'applicativo
Network File System (NFS) largamente diffuso nelle reti locali.
Ciascun messaggio UDP è detto user datagram ed è costituito di due parti: UDP header ed UDP
data area, che verranno incapsulate nell'IP datagram. Come mostra la figura, l'header del'UDP è simile a quello del TCP,
ma risulta essere più corto non avendo nessun numero di sequenza; è diviso in quattro campi
di 16 bits, che specificano il numero di porta da cui il messaggio è stato spedito (opzionale), quello della porta di
destinazione (usata per demultiplexare i datagrammi tra i processi che aspettano di riceverli), la lunghezza del messaggio
ed il checksum.

Concettualmente, tutte le operazioni di multiplexing e demultiplexing tra l'UDP ed i programmi
applicativi avvengono attraverso il meccanismo delle porte; in pratica, ciascun programma applicativo deve negoziare con
il sistema operativo per ottenere una porta di protocollo e l'associato numero prima che sia spedito un UDP datagram.
Assegnata la porta, ogni datagramma che il programma applicativo spedisce attraverso essa avrà quel numero di porta
nel suo UDP source port field. L'UDP accetta i datagrammi provenienti dal software IP e li demultiplexa in base alla
UDP destination port, come mostra la figura:

I sistemi operativi della maggiorparte dei computers, permettono a più programmi applicativi di essere in
esecuzione contemporaneamente (processes. tasks, application programs); tali sistemi sono detti
multitasking systems.
Potrebbe sembrare naturale che un processo su una particolare macchina sia l'ultima destinazione di un messaggio,
ma è più opportuno immaginare che ciascuna macchina contenga un set di punti di destinazione astratti,
detti protocol ports, identificati ciascuno da un intero positivo. Il sistema operativo locale fornisce un
meccanismo di interfaccia che i processi usano per specificare una porta o accedere ad essa.
In generale, le porte sono bufferizzate, in modo che i dati arrivati prima che il processo sia pronto, non vengano
perduti. Per permettere il buffering, il software di protocollo del sistema operativo posiziona in una coda (finita) i
poacchetti che arrivano per una particolare porta, finchè il processo non li estrae.
Per comunicare con una porta esterna, il mittente deve conoscere sia l'indirizzo IP
che il numero di porta di protocollo della macchina di destinazione. Ciascun messaggio deve contenere sia il numero della
Destination Port della macchina da cui il messaggio è spedito che il numero della Source Port della
macchina mittente, a cui la replica dovrà essere indirizzata, rendendo possibile, per ogni processo, il
collooquio tra mittente e destinatario.
Ci sono due fondamentali approcci per l'assegnazione delle porte, usando:
- Central Authority: due computers che devono interoperare tra di loro, si accordano per
permettere ad un'autorità centrale di assegnare i numeri di porta (Well-known ports) che necessitano e
di pubblicare la lista di tutte le assegnazioni (Universal assignment)
il software che gestisce le porte sarà realizzato in base a tale lista.
- Dynamic Binding: in questo approccio le porte non sono universalmente conosciute; infatti, se un
programma necessita di una porta, è il software di rete ad assegnargliela. Per sapere la porta corrente assegnata
su un altro computer, è necessario inviargli una richiesta del numero di porta assegnata al servizio di interesse.
I progettisti del TCP/IP usano un approccio ibrido che assegna alcuni numeri di porta a priori (Low values) e lascia altri
disponibili per siti locali o programmi applicativi (High values).
La tabella seguente contiene alcune tra le più significative UDP well-known ports:
|
|
|
| Decimal |
Keyword |
UNIX Keyword |
Description |
| 7 |
ECHO |
echo |
Echo |
| 9 |
DISCARD |
discard |
Discard |
| 11 |
USERS |
systat |
Active Users |
| 42 |
NAMESERVER |
name |
Host Name Server |
| 43 |
NICNAME |
whois |
Who is |
| 53 |
DOMAIN |
nameserver |
Domain Name Server |
| 69 |
TFTP |
tftp |
Trivial File Transfer |
Il Transmission Control Protocol (TCP), si assume la
responsabilità di instaurare un collegamento tra due utenti, di rendere
affidabile il trasferimento di dati e comandi tra essi ed infine di
chiudere la connessione. Esso è capace di trasferire un flusso continuo di
dati fra due utenti in entrambe le direzioni (full-duplex), decidendo quando bloccare o
continuare le operazioni a suo piacimento.
Poiché il TCP fa veramente
poche assunzioni riguardo l'hardware sottostante, è possibile implementarlo
sia su una singola rete come una ethernet sia su un complesso variegato
quale l'internet.
Tale protocollo, come l'UDP, si colloca, nel modello a strati,
sopra l'Internet Protocol Layer (IP), che gestisce il
trasferimento e l'instradamento del singolo pacchetto fino a destinazione,
ma, come ulteriore funzionalità, tiene una traccia di ciò che è stato
trasmesso ed eventualmente ritrasmette quella parte di informazione che è
andata perduta lungo il tragitto.

Come l'UDP, il TCP permette a più programmi applicativi su una stessa macchina di
comunicare contemporaneamente, e demultiplexa il traffico dei pacchetti in ingresso a tali
programmi; usa i numeri di porta per identificare la destinazione
finale all'interno di una macchina. La fondamentale differenza con l'UDP è che il TCP
garantisce un servizio di trasporto affidabile (Reliable Delivery Service),
ponendo rimedio alle cause di inaffidabilità proprie dell'IP
(duplicazione e perdita di dati, caduta di rete, ritardi, pacchetti ricevuti fuori ordine, etc.),
anche se ciò comporta una implementazione più complessa. L'importanza
dell'affidabilità del flusso permessa da tale protocollo è il motivo
per cui il complesso del protocollo TCP/IP ha tale nome.
L'affidabilità di questo servizio è caratterizzata da cinque proprietà:
- Stream Orientation: quando due programmi applicativi trasferiscono dati
(stream of bits), il flusso nella macchina di destinazione passa al ricevente
esattamente come è stato originto nella macchina sorgente.
- Virtual Circuit Connection: dal punto di vista del programmatore e dell'utente, il servizio
che il TCP fornisce è analogo a fornire una connessione dedicata.
- Buffered Trasfer: i routers interessati dal trasferimento sono provvisti di buffers per
rendere più efficiente il trasferimento e minimizzare il traffico di rete.
- Unstructured Stream: il TCP/IP stream service non adotta un flusso di dati strutturato; ovvero
non c'è modo di distinguere i records che costituiscono il flusso dati.
- Full-duplex Connection: la connessione fornita dal TCP/IP stream service permette un trasferimento di
flusso contemporaneo ed indipendente in entrambe le direzioni, senza apparente interazione.
Se un qualunque messaggio è troppo
grande per un singolo pacchetto TCP (gli standard consigliano una
dimensione di 576 byte compreso l'header del IP) si procede a dividerlo in
segmenti di lunghezza fissa e poi, arrivato a destinazione, si controlla
che siano in ordine e si riassemblano, in modo che tale operazione risulti
del tutto invisibile ai due utenti.
Poiché queste funzionalità sono
necessarie per molte applicazioni, sono state messe tutte insieme in questo
protocollo piuttosto che inserirle, come parte del programma, in ogni
applicativo che ne ha bisogno.
L'affidabilità è garantita da una tecnica di fondamentale importanza nota come
acknowledgement with retransmission (riscontro con ritrasmissione). Tale tecnica
prevede che il destinatario invii un messaggio di acknowledgement (ACK) al
mittente, una volta ricevuto un pacchetto.
Il mittente mantiene una copia di ciascun pacchetto spedito e la rimuove dal buffer di
trasmissione solo dopo aver ricevuto l'ACK relativo ad essa.
Nella configurazione più banale e
meno efficiente l'utente sorgente, dopo aver trasmesso un pacchetto, aspetta
di ricevere il suo ACK prima di spedire il successivo; inoltre fa anche
partire un "cronometro" per il timeout, allo scadere del quale, se non ha
ricevuto risposta, ritrasmette quello stesso pacchetto:

Un semplice
protocollo del tipo "stop and wait" come questo abbassa notevolmente le
prestazioni della rete, sprecando gran parte della banda disponibile
nell'attesa dell'ACK relativo al pacchetto precedente; infatti un canale full-duplex
è utilizzato come se fosse un half-duplex.
Tale problema è accentuato se i pacchetti devono
attraversare lungo il cammino molti componenti quali bridge, router,
repeater che, ovviamente, introducono un ritardo fisso di
elaborazione, più una componente dovuta al traffico in rete.
Sliding Windows
L'introduzione del protocollo Sliding Windows (finestre scorrevoli)
rende molto più efficiente la trasmissione e quindi l'utilizzo della banda,
perchè permette al mittente di trasmettere tutti i pacchetti nella finestra senza
dover aspettare l'ACK; via via che arrivano i vari ACK, il TCP fa
slittare la finestra in avanti trasmettendo dei nuovi pacchetti dinamicamente, come
rappresentato in figura:

Le dimensioni della finestra possono variare fino ad un
massimo di 64 Kbytes. Una finestra di ampiezza opportuna riuscirebbe quasi,
ipotizzando di non perdere pacchetti, a saturare completamente la banda di
trasmissione.
Infatti appena il primo pacchetto della finestra arriva a
destinazione, parte subito un ACK: se il round-trip di quel collegamento è
abbastanza piccolo, o la finestra sufficientemente grande, in modo che l'ACK
arrivi prima che il trasmettitore abbia esaurito la finestra, allora il
flusso di dati è continuo e pari alle potenzialità massime della rete.
Al contrario, se il round-trip è lento, si può avere la cosiddetta
"silly window syndrome", che consiste in un comportamento anomalo del TCP. Il
trasmettitore spedisce i pacchetti nella finestra e poi perde molto
tempo aspettando i relativi ACK prima di passare ai dati successivi,
lavorando quindi con una generazione impulsiva del carico in rete.
Il meccanismo di acknowledgment può essere un "go back N" o un "go back N
selective repeat", nel senso che le disposizioni dei reference sono molto labili,
specificando solo che ogni pacchetto deve essere riconosciuto in qualche
modo. Gli standard specificano invece chiaramente che tale meccanismo deve
essere cumulativo, nel senso che un ACK è relativo ad un certo numero di
byte della finestra, non ad un pacchetto, e che gli ACK successivi
riconosceranno altri byte in modo cumulativo.
Ad esempio, supposto di
lavorare con ACK da 500 byte, il primo ACK conferma i primi 500 byte, il
secondo assicura che sono stati ricevuti i primi 1000 byte, il terzo
garantisce fino a 1500 byte e così via. Siccome però la dimensione dei
pacchetti non è fissata, non è detto che un ACK corrisponda ad un solo
pacchetto TCP.
Possiamo allora definire la "finestra di acknowledgment"
(da non confondere con quella di trasmissione) come il numero di byte,
ovvero il numero di pacchetti TCP, una volta fissata la loro dimensione,
riconosciuti da un singolo ACK. Avere una finestra di acknowledgment
ampia limita il traffico in rete generato dagli ack, poiché lo stesso numero
di byte trasmesso viene riconosciuto valido con meno pacchetti ACK.
Il meccanismo della finestra è molto
importante anche perché fornisce al ricevente un mezzo per governare
la mole di dati spediti dall'utente sorgente. Infatti,
nell'header dei pacchetti TCP esiste un campo
specifico, detto "window", tramite il quale il ricevente indica al
trasmittente la dimensione in byte della finestra che è disposto
attualmente a ricevere (finestra del ricevente). Questo accordo avviene quando il ricevente
spedisce un ACK (che è anche esso un pacchetto TCP) nel quale specifica
innanzitutto l'ultima posizione riconosciuta valida e, a partire da questa,
il numero di byte che attualmente può accettare.
Headers
L'unità di trasporto tra i software TCP di due macchine è detto segment.
I segmenti sono scambiati per stabilire connessioni, trasferimenti di dati, inviare ACK,
comunicare la dimensione della Sliding Windows e chiudere le connessioni.
Poichè il TCP usa il piggybacking (trasmissione contemporanea di dati in
entrambe le direzioni), un ACK che viaggia da una macchina A ad una macchina B potrebbe
viaggiare in uno stesso segmento in cui viaggiano i dati tra A e B, sebbene l'ACK sia
riferito ai dati spediti tra B ed A.
La figura mostra il formato del segmento TCP:

Ciascun segmento è diviso in due parti: un TCP header ed un TCP data.
Un header ha una lunghezza di almeno 20
byte e comprende molti campi; i più importanti sono sicuramente il "port
number" e il "sequence number", sia della sorgente che della destinazione.
Il numero di porta serve per distinguere fra loro dei trasferimenti che
avvengono contemporaneamente; ovviamente devo conoscere anche i numeri di porta degli
altri tre nodi.
Il numero di sequenza identifica la posizione dei byte dati nel flusso spedito
all'interno del segmento; serve per ordinare i pacchetti in ricezione e per verificare di non
averne perso nessuno; da notare che tale
numerazione riguarda i byte non i pacchetti, nel senso che se si usano
pacchetti da 500 byte, il primo è numerato 500, il secondo 1000, il terzo
1500 e così via.
Un altro campo è il "acknowledgment number"; anche esso,
come il "sequence number", è cumulativo e conta i byte anziché i pacchetti.
Il campo da 2 byte "window" è quello che consente al ricevente di indicare
al trasmittente la dimensione della finestra da usare per il trasferimento
in corso; da notare che due alla sedici fa 64 K, cioè la dimensione massima
della finestra.
Gli ultimi due campi sono il "checksum" dell'header e un
"urgent pointer" per alcuni casi particolari.
Ovviamente, in ricezione il livello TCP ritaglia
l'header TCP, il livello IP ritaglia l'header IP, il livello di rete
ritaglia l'header e il checksum relativo ad esso.
Le porte del TCP sono molto più complesse rispetto a quelle
dell'UDP, perchè un dato numero di porta non corrisponde
ad un singolo oggetto. Infatti nel TCP gli oggetti da identificare sono delle connessioni
di circuito virtuali tra due programmi applicativi, e non delle particolari porte.
Il TCP usa la connessione, e non la porta di protocollo, come sua fondamentale astrazione;
le connessioni sono identificate da una coppia di end points, ognuno dei quali è
costituito da due
interi host,port, dove l'host è l'indirizzo IP
dell'host e port è il numero di porta TCP su quell'host (per esempio: l'end point
128.10.2.3,25 specifica la porta 25 sulla macchina di indirizzo 128.10.2.3).
Poichè il TCP identifica una connessione con una coppia di valori, uno dato
numero di porta può essere condiviso da più connessioni su una stessa
macchina, senza che si crei ambiguità. Perciò la macchina identificata da
128.10.2.3,53 può comunicare simultaneamente con le macchine identificate da
128.2.254.139,1184 e 128.9.0.32,1184.
Si possono così creare servizi concorrenti con connessioni multiple simultanee, senza
dover riservare un numero di porta locale per ogni connessione. Per esempio, alcuni sistemi
forniscono un accesso concorrente al loro servizio di posta elettronica, permettendo a
più utenti di spedire un E-mail contemporaneamente.
Ci sono due fondamentali approcci per l'assegnazione delle porte, usando:
- Central Authority: due computers che devono interoperare tra di loro, si accordano per
permettere ad un'autorità centrale di assegnare i numeri di porta (Well-known ports) che necessitano e
di pubblicare la lista di tutte le assegnazioni (Universal assignment)
il software che gestisce le porte sarà realizzato in base a tale lista.
- Dynamic Binding: in questo approccio le porte non sono universalmente conosciute; infatti, se un
programma necessita di una porta, è il software di rete ad assegnargliela. Per sapere la porta corrente assegnata
su un altro computer, è necessario inviargli una richiesta del numero di porta assegnata al servizio di interesse.
I progettisti del TCP/IP usano un approccio ibrido che assegna alcuni numeri di porta a priori (Low values) e lascia altri
disponibili per siti locali o programmi applicativi (High values).
La tabella seguente contiene alcune tra le più significative TCP well-known ports:
|
|
|
| Decimal |
Keyword |
UNIX Keyword |
Description |
| 7 |
ECHO |
echo |
Echo |
| 9 |
DISCARD |
discard |
Discard |
| 11 |
USERS |
systat |
Active Users |
| 20 |
FTP-DATA |
ftp-data |
File Transfer Protocol (data) |
| 21 |
FTP |
ftp |
File Transfer Protocol |
| 23 |
TELNET |
telnet |
Terminal connection |
| 25 |
SMTP |
smtp |
Simple Mail Transport Protocol |
| 42 |
NAMESERVER |
name |
Host Name Server |
| 43 |
NICNAME |
whois |
Who is |
| 53 |
DOMAIN |
nameserver |
Domain Name Server |
Esistono almeno due notevoli problemi col TCP,
relativi alla congestione della rete ed al meccanismo di "timeout and
retransmission".
La congestione è una condizione di ritardo critico causata da un sovraccaricamento dei
datagrammi in uno o più switching points (es. router). Quando avviene una
congestione, il ritardo aumenta ed i routers iniziano ad accodare datagrammi, finchè
non sono in grado di instradarli.
Nel peggiore dei casi, il numero dei datagrammi che arrivano ad un router congestionato
cresce (esponenzialmente nel tempo) fino a che esso non raggiunge la sua massima capacità e comincia a
perdere datagrammi. Dal punto di vista degli hosts, la congestione è semplicemente
un aumento di ritardo.
Inoltre, poichè la maggiorparte dei protocolli usa un meccanismo di timeout and
retransmission, essi rispondono al ritardo ritrasmettendo datagrammi, aggravando così
la congestione.
Un aumento di traffico produce un aumento di ritardo, che provoca a sua volta un aumento del
traffico, e così via, finchè la rete non può essere più usata:
tale condizione è detta Congestion Collapse (Collasso dovuto alla congestione).
Non esiste un meccanismo esplicito per risolvere il controllo della congestione, anche se
un'attenta implementazione del TCP/IP può permette di individuare ed affrontare
meglio la situazione.
Esistono due modi per affrontare il problema della congestione di rete: recuperare la funzionalità una volta
che la congestione ha avuto luogo (Recovery) oppure evitarla (Avoidance).
Per evitare il collasso della rete, il TCP può utilizzare la tecnica del Multiplicative Decrease
Congestion Avoidance. Il TCP/IP mantiene un secondo limite, oltre dimensione della finestra del ricevente,
detto congestion window limit; in oogni istante il TCP assume come dimensione della finestra di trasmissione, la minima
tra le due.
In condizioni normali, le due finestre sono uguali, ma in condizioni di congestione,
la congestion window riduce il traffico che il TCP immette in rete, dimezzando la propria dimensione
ogni volta che si perde un segmento (fino ad un minimo di uno). Il rate di trasmissione è ridotto in modo
esponenziale ed il valore del timeout viene raddoppiato per ogni perdita.
Se , una volta superata la congestione, si dovesse invertire la tecnica del Multiolicative Decrase, raddoppiando la
congestion window, si avrebbe un sistema instabile che oscillerebbe ampiamente tra assenza di traffico e congestione.
Per ripristinare le condizioni di normale funzionamento, una volta che è avvenuto il collasso, il TCP può
invece adottare una tecnica di Slow Start Recovery. Non appena inizia il traffico su una nuova connessione o
aumenta dopo un periodo di congestione, la congestion window ha la dimensione di un singolo segmento ed
ogni volta che arriva un ACK, viene incrementata di uno.
In questo modo, dopo aver trasmesso il primo segmento ed aver ricevuto il suo ACK, la finestra di congestione viene raddoppiata;
una volta inviati i due segmenti, per ogni ACK ricevuto la congestion window sarà incrementata di una unità,
così il TCP potrà spedire quattro segmenti, e così via, fino a raggiungere il limite imposto dalla
finestra del ricevente.
Per evitare che la dimensione della finestra si incrementi troppo velocemente e causi congestione addizionale, il TCP
impone una ulteriore restrizione. Una volta che la finestra di congestione raggiunge la metà del suo valore
originale, il TPC entra in una fase di congestion avoidance e rallenta il rate di incremento; in questo caso
la dimensione della finestra sarà incrementata di una sola unità dopo che tutti i segmenti della finestra
hanno ricevuto ACK.
La combinazione delle due tecniche di Recovery ed Avoidance migliora drasticamente le prestazioni del TCP senza bisogno
dell'aggiunta di ulteriori strumenti per il controllo della congestione.

Ultimo aggiornamento: 11 Novembre 1996





Explore the TELEMAT Site !!!
WORK IN PROGRESS by D. Mariano e C. Guadalupi