Internet: architettura e protocolli/Livello Trasporto: Protocolli TCP-UDP
Il TCP e l'UDP sono due protocolli di livello trasporto.
Ogni host ha un unico indirizzo IP, ma può avere in esecuzione più applicazioni. Ogni applicazione comunica attraverso una porta TCP e una porta UDP; il livello di trasporto effettua poi il multiplexing delle connessioni, cioè gestisce i flussi provenienti dalle varie porte verso il protocollo di rete sottostante.
TCP
[modifica | modifica sorgente]Formato dell'intestazione dei pacchetti TCP
[modifica | modifica sorgente]L'intestazione dei pacchetti TCP ha il formato seguente:
- source port: la porta TCP sorgente;
- destination port: la porta TCP di destinazione;
- numero di sequenza;
- acknowledgment number: la destinazione specifica il numero di sequenza del prossimo pacchetto da ricevere;
- hlen: la lunghezza dell'intestazione;
- flag: identificano l'informazione contenuta nel pacchetto:
- il flag ACK identifica se il pacchetto è un ACK;
- il flag SYN serve per l'apertura della connessione;
- il flag FIN serve per la chiusura della connessione;
- window size: la dimensione della finestra di ricezione del mittente del pacchetto, per permettere l'uso dei protocolli a finestra;
- checksum.
Numero di sequenza
[modifica | modifica sorgente]Il TCP è un protocollo orientato ai byte: il primo pacchetto inizia con un numero casuale, il secondo pacchetto ha quel numero incrementato del numero di byte di cui è costituito il primo pacchetto, e così via.
I buffer del mittente (coda di trasmissione) e della destinazione (coda di ricezione) non sono necessariamente di uguale dimensione → i dati possono venire segmentati in un modo e riassemblati in un altro.
Circuito virtuale
[modifica | modifica sorgente]Il TCP è un protocollo connesso: funziona tramite circuito virtuale tra una porta del mittente e una porta del destinatario.
Il circuito virtuale è full-duplex: consente la comunicazione in entrambi i sensi.
Esistono delle porte standard, chiamate well-known port, tramite cui può essere contattato l'applicativo di destinazione: ad ogni well-known port è assegnato un protocollo ben preciso → l'applicativo di destinazione riesce a sapere quale protocollo vuole usare l'applicativo sorgente per la comunicazione. Ad esempio, la porta 80 è riservata alla comunicazione tramite il protocollo HTTP. Siccome la comunicazione è full-duplex, la risposta uscirà dalla porta 80 dell'applicativo di destinazione e giungerà alla porta aperta prima dall'applicativo sorgente per l'invio della richiesta. Le well-known port sono 1024, una piccola parte rispetto a tutte le porte utilizzabili.
Apertura della connessione
[modifica | modifica sorgente]Per aprire una connessione, il TCP usa un three-way handshake:
- SYN: il client invia un SYN al server, impostando il numero di sequenza del segmento ad un valore casuale x;
- SYN-ACK: il server risponde con un SYN-ACK, impostando il numero di acknowledgment al numero di sequenza ricevuto più uno (x + 1), e scegliendo come numero di sequenza del pacchetto un altro numero casuale y;
- ACK: infine il client invia indietro un ACK al server, impostando il numero di sequenza al valore di acknowledgement ricevuto (x + 1), e il numero di acknowledgement al numero di sequenza ricevuto più uno (y + 1).
A questo punto, sia il client sia il server hanno ricevuto un acknowledgment della connessione e la comunicazione full-duplex è stabilita.
Chiusura della connessione
[modifica | modifica sorgente]La chiusura della connessione richiede l'invio di FIN e ACK in entrambe le direzioni. È una chiusura di tipo graceful leaving, perché gli interlocutori non abbandonano improvvisamente la conversazione ma prima la chiudono interagendo in maniera "educata".
Uso dei protocolli a finestra
[modifica | modifica sorgente]Il TCP richiede più banda dell'UDP, a causa delle maggiori dimensioni dell'header dovute ai maggiori controlli: a differenza dell'UDP, il TCP effettua il controllo di flusso e di congestione, e garantisce che tutti i pacchetti vengano consegnati integri a destinazione. L'acknowledge è obbligatorio (normalmente tramite piggybacking), e se un pacchetto non è giunto a destinazione va ritrasmesso.
Se un segmento va perso e arrivano segmenti successivi nella sequenza, il ricevitore inizia ad inviare NACK duplicati riferiti al segmento mancante. Il trasmettitore capisce che deve ritrasmettere il segmento quando riceve 3 NACK duplicati.
La dimensione della finestra di trasmissione viene modificata dinamicamente in funzione della capacità della rete e del ricevitore:
Il trasmettitore conosce la finestra di ricezione grazie al campo "window size" nell'intestazione dei pacchetti TCP.
Finestra di congestione
[modifica | modifica sorgente]La finestra di congestione serve per evitare di congestionare la rete limitando la finestra di trasmissione. All'apertura della connessione la finestra di congestione ha dimensione pari a 1, cioè viene mandato un solo pacchetto. Man mano che arrivano gli ACK, la finestra di congestione:
- cresce esponenzialmente (2, 4, 8...) fino ad arrivare a un certo valore di soglia, che la prima volta è predefinito;
- superato il valore di soglia cresce linearmente.
Se un riscontro non arriva entro il timeout, il valore di soglia viene impostato alla metà del valore corrente della finestra di congestione e si riparte da 1.
UDP
[modifica | modifica sorgente]Il protocollo UDP è privo dei controlli di flusso e di congestione → il trasmettitore continua a trasmettere alla massima velocità consentita dalla banda di trasmissione senza aspettare alcun ACK. Esegue solamente il controllo degli errori, cioè verifica il checksum del pacchetto per verificarne l'integrità.
L'UDP è un protocollo non connesso:
- non vi è alcun ritardo di apertura e di chiusura della connessione;
- è basso l'overhead, cioè il carico sul sistema operativo per tenere aperte le connessioni;
- i ritardi sono bassi e costanti, cioè la distanza tra un pacchetto e l'altro è uguale per tutti i pacchetti.
L'intestazione dei pacchetti UDP è molto più breve e semplice:
- source port;
- destination port;
- UDP length;
- UDP checksum.
L'UDP è utile:
- quando la rete è affidabile → i controlli non servono;
- quando le prestazioni e la riduzione del ritardo sono più importanti dell'affidabilità (es. telefonia);
- quando l'applicazione mette tutti i dati in un singolo pacchetto → non servono meccanismi per regolare la dimensione della finestra.
Eventuali meccanismi di ritrasmissione, come l'invio di ACK, devono essere gestiti a livello applicazione.