TCP: caratteristiche principali e struttura del segmento

// obiettivi di apprendimento
Elencare e spiegare le sei caratteristiche principali di TCP: connection-oriented, affidabile, full-duplex, byte-stream, controllo del flusso e della congestione
Descrivere la struttura dell’header TCP (20 byte fissi + opzioni) identificando il ruolo di ogni campo
Spiegare il ruolo di Sequence Number, Acknowledgment Number e dei flag SYN, FIN, ACK, RST, PSH, URG
Conoscere le principali opzioni TCP (MSS, Window Scale, SACK, Timestamps) e il loro scopo
📄
Slides
PDF con diagramma header TCP commentato
Scarica →
Networking & OS Anno 4 · Modulo 3 · Lezione 3

TCP — il protocollo che garantisce tutto

HTTP, HTTPS, SSH, FTP, SMTP: tutti usano TCP. Non è un caso. TCP è il protocollo di trasporto che garantisce che i dati arrivino a destinazione integri, ordinati e senza duplicati, indipendentemente da quello che succede nella rete sottostante. È la fondamenta su cui è costruita la maggior parte di Internet.

Ma questa garanzia ha un costo: TCP è complesso, ha un header minimo di 20 byte, richiede una connessione esplicita e mantiene stato su entrambi gli host. Capire come funziona internamente ti permette di capire perché alcune applicazioni sono lente, perché certi firewall si comportano in modo strano, e come i moderni protocolli come QUIC cercano di migliorarlo.

Le sei caratteristiche fondamentali

1 — CONNECTION-ORIENTED

Prima di trasferire dati, TCP stabilisce una connessione con un handshake a tre vie (three-way handshake). Solo dopo che entrambi gli host hanno concordato parametri e numeri iniziali di sequenza inizia il trasferimento dati.

2 — AFFIDABILE (RELIABLE)

TCP garantisce che ogni byte trasmesso venga ricevuto correttamente tramite ACK (acknowledgment), ritrasmissione in caso di perdita e riordinamento di segmenti arrivati fuori sequenza.

3 — FULL-DUPLEX

Dati scorrono in entrambe le direzioni simultaneamente sulla stessa connessione. Ogni lato ha il suo Sequence Number indipendente. ACK e dati possono essere trasportati insieme nello stesso segmento (piggybacking).

4 — BYTE-STREAM

TCP non conosce i confini dei messaggi applicativi. L’applicazione invia un flusso continuo di byte; TCP li segmenta come ritiene opportuno. Il ricevitore riassembla il flusso nell’ordine corretto. Contrasto con UDP che è message-oriented.

5 — CONTROLLO DEL FLUSSO

Previene il buffer overflow del ricevitore. Il ricevitore comunica quanto spazio ha disponibile tramite il campo Window Size nell’header. Il mittente non può inviare più byte di quanti il ricevitore ne possa accettare.

6 — CONTROLLO DELLA CONGESTIONE

Previene il collasso della rete. TCP adatta la velocità di trasmissione allo stato della rete tramite algoritmi (Slow Start, AIMD, CUBIC, BBR). Nessuna applicazione può inviare a piena velocità se la rete è congestionata.

La struttura dell’header TCP

L’header TCP ha una dimensione minima di 20 byte (5 parole da 32 bit), espandibile fino a 60 byte con le opzioni. Ogni campo ha un ruolo preciso nel meccanismo di consegna affidabile.

// HEADER TCP — struttura a 32 bit per riga (RFC 793 / RFC 9293)
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port (16)          |        Destination Port (16)        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Sequence Number (32)                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Acknowledgment Number (32)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Data |   |C|E|U|A|P|R|S|F|                                     |
|Offs.|Res|W|C|R|C|S|S|Y|I|       Window Size (16)          |
|(4)  |(3)|R|E|G|K|H|T|N|N|                                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Checksum (16)          |        Urgent Pointer (16)        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Options (0–40 byte, variabile)                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Campi dell’header — analisi dettagliata

CampoDimensioneRuolo
Source Port16 bitPorta del processo mittente (client: porta effimera; server: porta well-known)
Destination Port16 bitPorta del processo destinatario — usata per il demultiplexing
Sequence Number32 bitNumero del primo byte del payload in questo segmento. Inizializzato con l’ISN all’apertura della connessione
Acknowledgment Number32 bitNumero del prossimo byte atteso dal ricevitore (ACK cumulativo). Valido solo se flag ACK=1
Data Offset4 bitLunghezza dell’header in parole da 32 bit. Minimo 5 (= 20 byte), massimo 15 (= 60 byte)
Reserved3 bitRiservati per usi futuri, devono essere 0
Flags (control bits)9 bitCWR, ECE, URG, ACK, PSH, RST, SYN, FIN — controllano il comportamento della connessione
Window Size16 bitSpazio disponibile nel buffer del ricevitore (in byte). Base del controllo del flusso
Checksum16 bitCalcolato su pseudo-header IP + header TCP + dati. Obbligatorio (a differenza di UDP)
Urgent Pointer16 bitOffset fino ai dati urgenti. Usato raramente; valido solo se flag URG=1
Options0–40 byteOpzioni variabili — estendono le funzionalità base di TCP (vedi sezione dedicata)

I flag TCP — il linguaggio della connessione

I 9 bit di flag sono lo strumento con cui TCP comunica lo stato della connessione. Ogni flag attivo (=1) ha un significato preciso:

SYN

Synchronize — apertura connessione. Presente nel primo e nel secondo messaggio del three-way handshake. SYN occupa 1 numero di sequenza.

ACK

Acknowledgment — il campo Ack Number è valido. Presente in quasi tutti i segmenti TCP tranne il primo SYN.

FIN

Finish — chiusura graziosa della connessione. Il lato che invia FIN non trasmetterà più dati (può ancora ricevere). FIN occupa 1 numero di sequenza.

RST

Reset — chiusura immediata e anomala. Nessun graceful close. Usato quando la connessione è in uno stato inconsistente o per rifiutare una connessione.

PSH

Push — richiede al ricevitore di consegnare i dati all’applicazione immediatamente senza aspettare il riempimento del buffer.

URG / CWR / ECE

URG = dati urgenti. CWR/ECE = Explicit Congestion Notification (RFC 3168). Raramente usati nelle implementazioni comuni.

Sequence Number e ACK — il cuore dell’affidabilità

I campi Sequence Number e Acknowledgment Number sono il meccanismo centrale di TCP. Vale la pena capirli a fondo.

// sequence number — definizione operativa
Il Sequence Number di un segmento è il numero del primo byte del payload di quel segmento nel flusso byte complessivo. Se il flusso inizia al byte 0 e invio un segmento con 500 byte, il suo SeqNum è 0. Il segmento successivo avrà SeqNum 500.

L’ISN (Initial Sequence Number) è il numero di partenza, scelto pseudocasualmente all’apertura della connessione (non parte da 0). Il motivo è la sicurezza: un ISN prevedibile consentirebbe attacchi di IP spoofing e session hijacking.
// ESEMPIO — trasferimento dati 1000 byte (ISN=0, MSS=200)
SeqNum=0,   len=200 → byte 0–199     → ACK=200  (prossimo byte atteso)
SeqNum=200,  len=200 → byte 200–399   → ACK=400
SeqNum=400,  len=200 → PERDUTO       → ACK=400  (ricevitore richiede ancora byte 400)
SeqNum=600,  len=200 → byte 600–799   → ACK=400  (fuori ordine! ACK duplicato)
SeqNum=400,  len=200 → ritrasmissione → ACK=800
ACK cumulativo: ACK=800 conferma ricezione di tutti i byte 0–799

Window Size — il controllo del flusso in un campo

Il campo Window Size (16 bit) comunica al mittente quanti byte il ricevitore può ancora accettare nel suo buffer di ricezione. Il mittente non può inviare più dati di quanti indicati dalla window:

// regola del mittente TCP
LastByteSent – LastByteAcked ≤ min(cwnd, rwnd)
cwnd = congestion window (limitata dalla rete)
rwnd = receive window (limitata dal buffer del ricevitore)
// problema — 16 bit non bastano su reti veloci

Con Window Size a 16 bit, il massimo è 65535 byte. Su una connessione con RTT = 100ms e banda 1 Gbps, il BDP (Bandwidth-Delay Product) è circa 12,5 MB. Con una window di soli 64 KB, il mittente sarebbe costretto ad aspettare gli ACK ogni 64 KB, sprecando la banda disponibile. La soluzione è l’opzione Window Scale (RFC 7323): un moltiplicatore fino a 2¹⁴ = 16384 × che porta la window effettiva fino a ~1 GB.

Le opzioni TCP principali

Le opzioni TCP estendono l’header base aggiungendo funzionalità negoziabili nell’handshake:

OpzioneRFCFunzione
MSS (Maximum Segment Size)RFC 793Dimensione massima del payload TCP che il mittente è disposto a ricevere. Negoziato nell’SYN. Evita la frammentazione IP. Default 536 byte; tipicamente 1460 byte su Ethernet (MTU 1500 – 20 IP – 20 TCP).
Window ScaleRFC 7323Moltiplicatore per il campo Window Size. Permette window effettive fino a ~1 GB su reti ad alta banda e latenza elevata.
SACK (Selective Acknowledgment)RFC 2018Il ricevitore segnala blocchi non contigui ricevuti. Il mittente ritrasmette solo i segmenti effettivamente mancanti invece di tutto dalla posizione del gap. Riduce drasticamente i dati ritrasmessi in caso di perdite multiple.
TimestampsRFC 7323Permette una stima più precisa del RTT e protegge da sequence number wrap-around su connessioni molto veloci (PAWS — Protection Against Wrapped Sequences).
// nota — checksum su pseudo-header

Il checksum TCP viene calcolato su un pseudo-header che include IP sorgente, IP destinazione, protocollo e lunghezza del segmento TCP — campi che tecnicamente appartengono al livello IP. Questo viola strettamente la separazione tra livelli, ma serve a rilevare eventuali errori di consegna a indirizzi errati. È una scelta pragmatica consolidata (stessa tecnica usata da UDP).

Da RFC 793 a RFC 9293 — TCP si evolve

TCP è stato definito nel 1981 con RFC 793. Nel 2022 è stato aggiornato dall’RFC 9293 che consolida decenni di correzioni, chiarimenti e best practice in un unico documento. RFC 793 è ufficialmente obsoleto. Le implementazioni moderne (Linux, Windows, BSD) seguono RFC 9293 più tutta una serie di RFC aggiuntivi per SACK, CUBIC, BBR, TFO (TCP Fast Open) e altri.

📌 Riepilogo — Punti chiave
  • TCP è connection-oriented, affidabile, full-duplex, byte-stream, con controllo del flusso e della congestione
  • Header minimo 20 byte: Source/Dest Port (16 bit), Sequence Number (32), Ack Number (32), Data Offset (4), Flag (9), Window Size (16), Checksum (16), Urgent Pointer (16)
  • Sequence Number = numero del primo byte del payload; Ack Number = prossimo byte atteso (ACK cumulativo)
  • ISN casuale per sicurezza; SYN e FIN consumano 1 numero di sequenza ciascuno
  • Flag principali: SYN (apertura), ACK (conferma), FIN (chiusura), RST (reset), PSH (push immediato)
  • Opzioni fondamentali: MSS (evita frammentazione), Window Scale (reti veloci), SACK (ritrasmissione selettiva), Timestamps (RTT preciso)

Lascia un commento