Première rédaction de cet article le 4 mai 2012
Tout le monde a envie que les réseaux aillent plus vite. Surtout Google. Un article de 2011, par des employés de cette société, « TCP Fast Open » explique un des mécanismes qui peuvent être utilisés, notamment pour les sessions TCP de courte durée. (Cette technique a, depuis, été décrite dans le RFC 7413.)
Un paradoxe de TCP,
connu depuis longtemps, est que le temps complet d'une session (par
exemple, de récupération d'un fichier) dépend souvent essentiellement
du temps d'ouverture de la session. En effet, beaucoup de sessions TCP
sont courtes (par exemple, en HTTP, on
GET /machintruc.html
, on récupère une page de
cinq kilo-octets et c'est tout). Le temps de transfert des données est
négligeable par rapport au temps d'ouverture de la session, qui est
causé par la latence.
Car il faut oublier les stupides publicités des FAI qui promettent toutes des capacités mirifiques (et, en prime, ils se trompent et parlent de « bande passante », voire, pire, de « débit », notez que la capacité est définie dans le RFC 5136), des Mb/s en quantité. La capacité est bien pratique quand on télécharge la saison 2 de Rome mais, pour beaucoup d'interactions sur le Web, c'est la latence qui compte. En effet, l'ouverture d'une session TCP (RFC 793) nécessite l'échange de trois paquets :
SYN
),SYN+ACK
),ACK
).L'acheminement de chaque paquet prend un temps certain (dixit Fernand Raynaud, mais on trouve une définition plus rigoureuse dans le RFC 7679) et le temps total d'ouverture est trois fois ce temps.
Vous ne me croyez pas ? Ce n'est pas grave, Google a mesuré pour cet article, en utilisant à la fois leurs serveurs HTTP et les mesures faites par Chrome. Première observation : la page Web moyenne fait 300 ko mais la plupart des fichiers qu'on télécharge sont petits, avec une taille moyenne de 7,3 ko et surtout une médiane de 2,4 ko. Un objet de 2,4 ko ne prend que deux paquets pour être transmis, la majorité des paquets seront donc pour l'ouverture de la connexion. Si le RTT est long, c'est lui, et pas la capacité, qui fixera le temps d'attente.
L'article montre ensuite que certaines solutions à ce problème, comme les connexions persistantes d'HTTP (RFC 7230, section 6.3), n'aident pas souvent, en pratique.
Alors, une solution évidente à ce problème de performances serait de permettre au premier paquet envoyé de porter des données. Le dialogue, pour un objet qui tient dans un seul paquet, deviendrait :
GET /machintruc.html
» (paquet SYN
),machintruc.html
] » (paquet
SYN+ACK
),Mais cela ouvre une énorme faille de sécurité. Le premier paquet peut mentir sur son adresse IP source (au premier paquet, TCP n'a pas encore testé la réversibilité) et forcer le serveur HTTP à envoyer des données à la victime dont il a usurpé l'adresse (une attaque par réflexion et amplification, la réponse étant plus grosse que la requête).
Donc, comme Google est très fort, comment fait-il ?
Fast Open Cookie
Request
(les options TCP sont décrites dans la section 3.1
du RFC 793, les options de TCP Fast
Open sont enregistrées dans le
registre IANA des options expérimentales),
On le voit, TCP Fast Open ne traite pas le cas de
la première connexion. Mais ce n'est pas grave : on fait en général
beaucoup de connexions TCP avec un serveur Web.
Pour les connexions ultérieures, le client enverra le
cookie dans le premier paquet, dans l'option TCP
Fast Open Cookie
. Le serveur vérifiera ledit
gâteau et, s'il est correct, acceptera les données transmises dans le
premier paquet (typiquement un GET
/machintruc.html
HTTP).
Naturellement, ça, ce sont les généralités. En pratique, il y a
plein de détails dont il faut s'occuper. Par exemple, TCP
Fast Open va devoir se battre contre les
middleboxes, cette plaie de
l'Internet, cf. l'excellente étude de Google « Probing the
viability of TCP extensions ». Et il y a la taille
(limitée) dans l'en-tête TCP pour les options. Et le fait qu'un accusé
de réception peut se perdre, amenant à la réémission d'un paquet
SYN
(et donc à un GET
reçu
deux fois : TCP Fast Open ne doit être utilisé
qu'avec des requêtes idempotentes). Mais tout cela n'a pas
arrêté les auteurs qui ont programmé cette option dans
Linux (dans les 2 000 lignes de code) et
Chrome. Résultat, avec une latence de 100 ms,
entre 6 et 16 % de gain, montant à 11-41 % pour 200 ms de latence.
À noter que cette idée d'accélérer TCP en mettant davantage d'informations plus tôt était à la base de T/TCP (RFC 1644). Ce protocole avait de sérieux défauts (cf. RFC 4614) et a officiellement été abandonné dans le RFC 6247.
L'actuel TFO (TCP Fast Open) a ensuite été décrit dans un RFC de statut « expérimental » (donc pas une « vraie » norme) en décembre 2014, dans le RFC 7413) . Mais TFO avait déjà fait l'objet de pas mal de buzz, voir par exemple l'article du Monde Informatique, celui de 01 Net ou celui de Développez. Ces articles (et surtout leurs commentaires) comportant pas mal d'erreurs, il vaut mieux revenir vers l'article du blog de Google (où TCP Fast Open n'est qu'une partie des changements proposés à TCP). L'ouverture rapide a été intégrée au noyau Linux officiel en septembre 2012, voir cet article dans LWN et cet autre, plus détaillé, avec exemple de code C. Le tout est apparu dans la version 3.6 de Linux.
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)