Prima di effettuare lo scambio di dati, il mittente e il destinatario effettuano un handshake, dove viene determinata la disponibilità dell’uno e dell’altro ad accettare di stabilire una connessione, concordando i parametri di quest’ultima (es: l’inizio del numero di sequenza).
Una prima implementazione dell’handshake è l’handshake a 2 vie (two-way handshake), dove il mittente invia la richiesta di connessione al destinatario, il quale invia successivamente l’accettazione di tale richiesta, assumendo lo stato di connessione ESTAB (established).
Una volta ricevuta l’accettazione, anche il mittente assumerà lo stato ESTAB, per poi
procedere con l’invio effettivo dei dati.
Tuttavia, in tale implementazione il destinatario non è a conoscenza della ricezione da parte del mittente del pacchetto di accettazione della connessione, presentando quindi due problematiche fondamentali:
- Nel caso in cui il mittente rinvii la richiesta di connessione allo scadere del timer TCP e l’accettazione del destinatario inerente alla prima richiesta giunge comunque dopo lo scadere del timer, il mittente suppone che la connessione sia andata a buon fine (nonostante il RTT sia estremamente basso), stabilendo quindi una prima connessione.
- Se tale connessione viene terminata prima che la seconda richiesta del mittente sia giunta al destinatario, quest’ultimo interpreterà la richiesta come una richiesta appartenente ad una seconda connessione.
- Tuttavia, poiché tale richiesta era solo un rinvio della prima richiesta connessione, il client ignorerà la seconda richiesta di accettazione del server, creando quindi una connessione fantasma senza client
- Inoltre, nel caso in cui venga stabilita una connessione fantasma, si potrebbe andare incontro ad accettazioni di pacchetti dati duplicati.
Di conseguenza, l’handshake TCP viene implementato attraverso uno scambio di 3 mes- saggi (handshake a 3 vie):
-
Il mittente sceglie un numero di sequenza iniziale x e invia un pacchetto di tipo SYN (synchronize) al destinatario, richiedendo di stabilire una connessione. Per inviare un pacchetto di tipo SYN, è sufficiente impostare il campo SYN = 1 all’interno dell’header
-
Una volta ricevuto il pacchetto SYN, il destinatario sceglie un numero di sequenza iniziale y e invia un pacchetto di tipo SYN/ACK (synchronize and ACK) al mittente, impostando i campi SYN = 1 e ACK = 1 nell’header
-
Una volta ricevuto il pacchetto SYN/ACK, il mittente invia un pacchetto di tipo ACK (dunque con solo ACK = 1), passando in stato ESTAB. Infine, una volta ricevuto il pacchetto ACK, il destinatario passerĂ in stato ESTAB
In questo modo, il destinatario sarĂ a conoscenza dello stato finale del mittente, risolvendo le due problematiche. Per effettuare la chiusura di una connessione, il primo dispositivo (mittente o destinatario che sia) invia al secondo dispositivo un pacchetto di tipo FIN (finished). Una volta ricevuto il pacchetto FIN, il secondo dispositivo risponderĂ con un pacchetto FIN/ACK, per poi inviare, dopo un breve lasso di tempo, un secondo pacchetto FIN. Analogamente, anche il primo dispositivo una volta ricevuto il pacchetto FIN invierĂ un pacchetto FIN/ACK. Utilizzando tale handshake a 4 vie, entrambi i dispositivi riescono accertarsi il corretto termine della connessione. Inoltre, in tal modo entrambi i dispositivi possono terminare la connessione simultaneamente (creando una sorta di doppio handshake a 2 vie)