Précédent Latence et bande passante
Suivant UDP

TCP

Ce billet fait partie d'une série en 10 volets : #1, #2, #3, #4, #5, #6, #7, #8, #9 et #10.

Notes de lecture de Building Blocks of TCP.

TCP

Deux protocoles sont au cœur d'Internet, IP et TCP. IP (Internet Protocol) fournit le routage et l'adressage. TCP (Transmission Control Protocol) fournit l'abstraction d'un réseau fiable fonctionnant sur un canal non fiable.

Même si ses spécifications ne rendent pas TCP obligatoire, tout le trafic du protocole HTTP (avant la version 3) passe par TCP en raison de ses nombreuses fonctions pratiques : vérification et correction des erreurs de paquets, livraison dans l'ordre, retransmission des paquets perdus, contrôle des flux, contrôle et évitement de la congestion.

Three-way handshake

Toutes les connexions TCP commencent par une séquence three-way handshake :

  • SYN (Synchronize Sequence Number)
  • SYN ACK (Synchronize Sequence Number, Acknowledgement)
  • ACK  (Acknowledgement)

Chaque nouvelle connexion TCP est coûteuse et implique un aller-retour complet de latence avant que des données puissent être transférées.

La réutilisation des connexions est une optimisation critique pour toute application s'exécutant sur TCP.

Contrôle du débit/flux (flow control)

TCP propose plusieurs mécanismes pour régir le débit avec lequel les données peuvent être envoyées dans les deux sens.

Le contrôle de flux permet d'éviter qu'un émetteur ne submerge un récepteur avec des données qu'il n'est pas en mesure de traiter.

De chaque côté de la connexion TCP, chaque partie annonce une fenêtre de réception (rwnd, receive window) qui donne la taille de la mémoire tampon disponible pouvant contenir les données entrantes.

Si l'un des côtés n'est pas en mesure de suivre, il peut annoncer une fenêtre plus petite.

Si la fenêtre atteint zéro, aucune autre donnée ne doit être envoyée tant que les données existantes dans la mémoire tampon n'ont pas été effacées.

Ce contrôle se poursuit pendant toute la durée de vie des connexions TCP : chaque paquet ACK porte sa dernière valeur rwnd, ce qui permet aux deux côtés d'ajuster dynamiquement le débit de données à la capacité et à la vitesse de traitement des parties.

La taille maximale de cette fenêtre a évolué avec le temps.

Slow-Start

Ni l'émetteur ni le récepteur ne connaissent la largeur de bande passante disponible au début d'une nouvelle connexion.

Ils ont besoin d'un mécanisme pour estimer la capacité du réseau sous-jacent et pour adapter leurs vitesses aux conditions en constante évolution.

Pour estimer la bande passante disponible, il faut la mesurer par un échange de données, c'est le rôle du slow-start.

Lors d'une nouvelle connexion TCP, la quantité maximale de données envoyées correspond à la plus petite des valeurs entre rwnd (receive window) et cwnd (congestion window) dont la valeur initiale est initcwnd (initial congestion window) sous Linux.

Puis pour chaque ACK reçu, la taille de la fenêtre cwnd augmente d'1 segment. Pour chaque paquet ACKé, deux nouveaux paquets peuvent être envoyés. La fenêtre est doublée à chaque aller-retour (croissance exponentielle).

Puisque HTTP fonctionne au dessus de TCP, chaque connexion TCP doit passer par la phase slow-start et nous ne pouvons pas utiliser la pleine capacité de la liaison immédiatement.

Pour les applications Web, slow-start limite le débit de la bande passante disponible, ce qui a un effet négatif sur les performances des petits transferts.

La taille de la fenêtre initiale évolue avec le temps.

Évitement de congestion

La quantité transmise double à chaque aller-retour jusqu'à ce qu'elle dépasse le seuil de congestion configurée par le système (ssthresh) ou jusqu'à ce qu'un paquet soit perdu.

Un algorithme d'évitement de congestion prend le relais. L'hypothèse faite est que la perte de paquets témoigne de la congestion du réseau. Il faut ajuster la fenêtre de congestion pour éviter davantage de pertes de paquets et une saturation du réseau.

Il existe différents algorithmes d’évitement de congestion et c'est un domaine en évolution perpétuelle.

Head-of-Line Blocking

Chaque paquet TCP porte un numéro de séquence unique, et les données doivent être transmises au récepteur dans l'ordre.

Si l'un des paquets est perdu en route, tous les paquets suivants doivent être conservés dans la mémoire tampon du récepteur jusqu'à ce que le paquet perdu soit retransmis et arrive au récepteur.

La couche applicative n'a aucune visibilité sur la couche TCP et doit attendre la séquence complète avant de pouvoir accéder aux données.

Cet effet est connu sous le nom de blocage en tête de ligne (head-of-line blocking).

Le délai engendré par le head-of-line blocking est appelé jitter.

Impact de TCP sur la performance web

En résumé :

  • la séquence TCP three-way handshake implique un aller-retour complet de latence
  • TCP slow-start est appliqué à chaque nouvelle connexion
  • les contrôles de flux et de congestion TCP permettent de réguler le débit des connexions
  • le débit TCP est régulé par la taille de la fenêtre de congestion

Dans la plupart des cas, c'est la latence, et non la bande passante, qui constitue le goulot d'étranglement du protocole TCP.