# TCP-handshake

Met een TCP-handshake kan een netwerkverbinding tussen client en server gecreëerd of verbroken worden. Een TCP-handshake is nodig om stabiele en betrouwbare netwerkverbindingen in de transport-, sessie-, presentatie- en applicatielaag (de lagen 4 t/m 7 in het OSI-model) te creëren of te verbreken. Tijdens een TCP-handshake worden gegevens via de netwerklaag (laag 3 in het OSI-model) uitgewisseld tussen computers met verschillende internet sockets.

## TCP/IP-pakketten en gegevensoverdracht
### Metadata en payload

Met behulp van TCP/IP-pakketten kunnen clients en servers gegevens uitwisselen. Een TCP/IP-pakket is een IPv4- of een IPv6-pakket waarmee een TCP-segment over een IP-netwerk verstuurd wordt. Het gegevensblok bevat de payload en de IP- en TCP-headers bevatten metadata. Als het gegevensblok leeg is dan worden met het TCP/IP-pakket alleen metadata in de IP-header en de TCP-header overgedragen. De metadata in de IP-headers bevatten bijna geen informatie die van belang is voor de netwerkverbinding of het verdere verloop van de sessie. Tijdens een TCP-handshake wordt via de metadata in TCP-headers de belangrijkste informatie tussen client en server uitgewisseld. Die metadata hebben de beide partijen nodig om tijdens de TCP-sessie de dataTransmissie te Controleren.

### TCP-header

Een aantal velden in de TCP-header spelen een hoofdrol tijdens een TCP-handshake. Dat zijn de eerste twee 16 bits velden met de nummers van de bronpoort en de bestemmingspoort, de twee volgende 32 bit velden met het sequentie- en het bevestigingsnummer en de drie bits van de SYN-, FIN- en ACK-vlaggen.
TCP Header :
| Bit offset | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
| 0 | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bronpoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort | Bestemmingspoort |
| 32 | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer | Sequentienummer |
| 64 | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer | Bevestigingsnummer |
| 96 | Headerlengte | Headerlengte | Headerlengte | Headerlengte | 0 | 0 | 0 | N S | C W R | E C E | U R G | A C K | P S H | R S T | S Y N | F I N | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte | Window-grootte |
| 128 | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Controlesom | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens | Verwijzing naar urgente gegevens |
| 160 ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... | Opties (if Headerlengte > 5) ... |

#### Bestemmingspoort en bronpoort

De bestemmingspoort (of doelpoort) is het poortnummer dat de client moet gebruiken om een netwerkverbinding met een server te kunnen maken. De service draait op een bepaalde TCP-systeempoort of TCP-gebruikerspoort, zoals de poortnummers 80, 143, 389 en 3306 voor resp. HTTP, IMAP, LDAP en MySQL-databases. De bronpoort is een (willekeurig) dynamisch poortnummer dat door client gekozen wordt uit de reeks van 49152 t/m 65535. Het poortnummer van de bronpoort wordt tijdens de hele sessie gebruikt. De bronpoort van de client is hetzelfde als de bestemmingspoort in de TCP/IP-pakketten die de server naar de client verstuurt.

#### Sequentienummer en bevestigingsnummer

Het eerste sequentienummer (of volgnummer) is een willekeurig 32 bits getal dat door de toevalsgenerator van de client wordt gekozen. Dat sequentienummer wordt door de client in met het eerste TCP/IP-pakket naar de server verstuurd. De server verhoogt het sequentienummer en stuurt het resultaat als nieuw sequentienummer samen met het eerste bevestigingsnummer in een TCP/IP-pakket naar de client. Het eerste bevestigingsnummer is een willekeurig 32 bits getal dat door de toevalsgenerator van de server wordt gekozen. Na ontvangst van het pakketje verhoogt de client het bevestigingsnummer en stuurt dat als nieuw bevestigingsnummer in het volgende TCP/IP-pakket naar de server.
Tijdens een TCP-sessie verhoogt de client bij elke transactie het bevestigingsnummer en verhoogt de server bij elke transactie het sequentienummer. Op deze manier worden de pakketjes automatisch genummerd zodat de pakketjes door beide partijen geordend kunnen worden en de beide partijen de volgorde van versturen kunnen controleren.

#### SYN-, FIN- en ACK-vlag

De SYN- en FIN-vlaggen worden alleen aan het begin van een handshake gebruikt. De client stuurt een eerste pakketje met een SYN-vlag naar de server als verzoek om een TCP-sessie op te starten. Als de server de aanvraag accepteert dan stuurt hij als antwoord een pakketje met een SYN-vlag en een ACK-vlag naar de client terug. Tijdens een sessie heeft de SYN-vlag alleen in het eerste pakketje dat de client naar de server verstuurt, en in het eerste pakketje dat de server naar de client verstuurt, de waarde 1.
Een TCP-verbinding is een asymmetrisch, half-duplex communicatiekanaal. Zowel de client als de server kan de FIN-vlag gebruiken om de verbinding te verbreken. De FIN-vlag heeft alleen de waarde 1 in het voorlaatste of het laatste pakketje dat client en server naar elkaar opsturen.
De ACK-vlag wordt gebruikt voor alle pakketjes waarin het sequentienummer of het bevestigingsnummer opgehoogd is.

## Handshakes
### Netwerkverbinding maken

De client neemt het initiatief om een netwerkverbinding met een server tot stand te brengen door de server een SYN-pakket, een TCP/IP-pakket met een SYN-vlag en een sequentienummer, toe te sturen. Als de server reageert door een SYN-ACK-pakket, een TCP/IP-pakket met een SYN- en een ACK-vlag, een bevestigingsnummer en een opgehoogd sequentienummer, terug te sturen dan kan de uitwisseling van TCP/IP-pakketten voor datatransport voortgezet worden.
De TCP-handshake om een netverbinding te maken verloopt in drie stappen:
* De client verstuurt een TCP-header met SYN = 1, een sequentienummer = x, een bronpoort en een bestemmingspoort naar de server. De tweede stap kan volgen als op het IP-adres een server draait die reageert op TCP/IP-pakketten met het poortnummer van de bestemmingspoort in de TCP-header.
* De server stuurt een TCP/IP-pakket met SYN = 1, ACK = 1, sequentienummer = y en bevestigingsnummer = x + 1 terug naar de client om de ontvangst van het eerste TCP/IP-pakket te bevestigen. De derde stap volgt nadat de ontvangstgegevens door de client zijn gecontroleerd.
* De client stuurt een tweede pakket met SYN = 0, ACK = 1, sequentienummer = x + 1 en bevestigingsnummer = y + 1 en aanvullende gegevens, terug naar de server. Als de gegevens in het TCP/IP-pakket door de client gecontroleerd zijn dan kan de sessie voortgezet worden.
Na de derde stap is de verbindingstoestand ESTABLISHED waarna processen in de applicatielaag opgestart kunnen worden.
Tijdens de TCP-handshake kunnen zich verschillende problemen voordoen. De client kan met een SYN flood een crash van een server of een denial of service veroorzaken door foute bronadressen aan SYN-pakketjes mee te geven.

### Netwerkverbinding verbreken

Omdat een TCP-netwerkverbinding veel op een (vrij traag, asymmetrisch) full-duplex TDMA-communicatiekanaal lijkt, kan de verbinding op elk moment zowel op verzoek van de server als op verzoek van de client verbroken worden. De partij die de verbinding wil verbreken wordt de initiator van de handshake genoemd en de andere partij wordt de ontvanger van de handshake genoemd. Een verzoek om de verbinding te verbreken wordt door de initiator gedaan door een FIN-pakket, ofwel een TCP/IP-pakket met een FIN-vlag, naar de ontvanger te versturen.
Het verbreken van een TCP-netwerkverbinding verloopt in vier stappen:
* De initiator verstuurt een TCP-header met een FIN-vlag naar de ontvanger.
* Nadat de ontvanger de FIN-vlag heeft ontvangen, stuurt de ontvanger zijn laatste TCP/IP-pakket met een ACK-vlag naar de initiator.
* De ontvanger stuurt vervolgens een FIN-vlag naar de initiator om de initiator te laten weten dat de verbinding verbroken kan worden.
* Vervolgens stuurt de initiator een TCP-header met een ACK-vlag naar de ontvanger om de verbinding definitief te verbreken.
Nadat de ontvanger de ACK-vlag heeft ontvangen is de netwerkverbinding definitief verbroken.

## Verbindingstoestanden

Netwerkverbinding, server en client bevinden zich tijdens de handshakes in verschillende verbindingstoestanden of connection states.

### Verbinding maken
#### LISTEN (Server)

    Server wacht op een verbindingsverzoek van een client.

#### SYN-SENT (Client)

    Na het verzenden van een SYN-pakket wacht de client op een passend antwoord van de server.

#### SYN-RECEIVED (Server)

    Na het verzenden van een SYN-ACK-pakket aan de client wacht de server op een ontvangstbevestiging van de client.

#### ESTABLISHED (Verbinding)

    Nadat de server een ACK-pakket van de client heeft ontvangen staat de TCP/IP-verbinding open de datacommunicatie tussen client en server.

### Stabiele verbinding gemaakt

Nu de netwerkverbinding gemaakt is en zich in de ESTABLISHED verbindingstoestand bevindt, kunnen client en server ACK-pakketjes met elkaar uitwisselen. Daarbij zorgen de sequentie- en bevestigingsnummers ervoor dat de datacommunicatie aan beide zijden van de verbinding gesynchroniseerd wordt. De TCP-sessie kan nu in de applicatielaag opgestart worden tot de client of de server de verbinding verbreekt.

### Verbinding verbreken
#### FIN-WAIT-1 (Initiator)

    De initiator wacht op een ACK-pakketje van de ontvanger ter bevestiging dat het verstuurde FIN-pakketje is ontvangen.

#### FIN-WAIT-2 (Initiator)

    Initiator wacht op een FIN-pakketje van de ontvanger na de ontvangst van het ACK-pakketje van de ontvanger ter bevestiging dat de verbinding wordt verbroken.

#### CLOSE-WAIT (Ontvanger)

    Ontvanger wacht na ontvangst van het FIN-pakkerje op een laatste ACK-pakketje waarmee de verbinding wordt verbroken.

#### CLOSING (Verbinding)

    Initiator verstuurt een laatste ACK-pakketje naar de ontvanger.

#### LAST-ACK (Ontvanger)

    De ontvanger verstuurt een laatste FIN-pakketje en wacht vervolgens op het laatste ACK-pakketje ter bevestiging dat het eerder verzonden FIN-pakketje is ontvangen.

#### TIME-WAIT (Initiator)

    De initiator wacht tot de ontvanger het laatste ACK-pakketje heeft ontvangen. Volgens RFC 793 kan een verbinding in TIME-WAIT blijven staan voor maximaal vier minuten, bekend als twee MSL, de maximale levensduur van een TCP-segment.

#### CLOSED (Verbinding)

    De verbinding is verbroken.
Nadat de ontvanger het laatste ACK-pakketje heeft ontvangen is de netwerkverbinding definitief verbroken.

### netstat

De toestand van alle actieve sockets met TCP/IPv4- en TCP/IPv6-verbindingen kunnen zichtbaar gemaakt worden met een netstat-opdracht.
De Linux netstat opdracht met de -t-optie geeft bijvoorbeeld:
* ↑ (en) RFC 7323: TCP Extensions for High Performance
* ↑ (en) TCP/IP Basics - Episode 025 - TCP headers continued op YouTube
* ↑ (en) TCP Handshake op YouTube
* ↑ (en) What Is a Three-Way Handshake in TCP? op YouTube
* ↑ (en) TCP connection walkthrough op YouTube
* ↑ (en) netstat(8) - Linux man page
* ↑ (en) Netstat op Microsoft TechNet
* ↑ (en) NETSTAT(1) - FreeBSD General Commands Manual