Résumé
- Un ACK arrivé en retard pouvait pousser les deux extrémités à répéter leurs paquets courants et entretenir une chaîne de doublons.
- Le RFC 1123 a interdit à l’émetteur DATA de répondre à un ACK dupliqué en renvoyant le bloc actuel. Le risque était l’expiration du transfert sous congestion, pas l’altération d’un fichier achevé.
Un seul bloc en mémoire
En juin 1981, Karen Sollins publia la deuxième révision du Trivial File Transfer Protocol. « Trivial » décrivait une interface volontairement réduite : lire ou écrire un fichier distant, sans explorer de répertoires ni authentifier un utilisateur. Les données avançaient par blocs de 512 octets. Chaque bloc non final devait être acquitté avant l’envoi du suivant. Un émetteur n’avait donc qu’un paquet courant à conserver pour le renvoyer si nécessaire. Ce mécanisme d’arrêt et d’attente assurait aussi le contrôle de flux et évitait de réordonner les blocs.
Cette économie comptait pour les machines qui devaient obtenir leur système avant de disposer d’une configuration réseau complète. Le RFC 1123, publié en 1989, rappelle que l’usage essentiel de TFTP était l’amorçage d’un hôte sur un réseau local : le protocole était assez petit pour tenir en EPROM. BOOTP pouvait fournir la configuration; TFTP transportait ensuite l’image. Ce sont deux étapes distinctes, et le transfert dépendait toujours des délais et des acquittements.
TFTP fonctionnait au-dessus d’UDP et gérait lui-même la fiabilité. Si la réponse attendue n’arrivait pas avant l’expiration du temporisateur, l’émetteur pouvait renvoyer le paquet en attente. La règle paraissait simple tant qu’un paquet était perdu. Un paquet retardé créait une situation différente.
Le vieil ACK qui déclenche de nouveaux doublons
Supposons que l’hôte A reçoive l’ACK X−1 et envoie DATA X. L’hôte B reçoit ce bloc et répond ACK X, mais l’ACK tarde sur le réseau. Le délai de A expire et il renvoie DATA X. B a déjà accepté le bloc; il reconnaît le doublon et envoie de nouveau ACK X. Lorsque le premier ACK, retardé, arrive enfin, A passe au bloc suivant et émet DATA X+1. Puis le second ACK X arrive. Selon l’ancienne règle, A répond à cet ACK périmé en retransmettant le paquet qu’il a maintenant en cours : DATA X+1.
B reçoit deux fois le bloc X+1 et renvoie deux ACK X+1. Si l’un de ces anciens acquittements arrive après que A est passé à DATA X+2, il peut provoquer un nouveau doublon du bloc courant. Le paquet ancien ne rejoue donc pas seulement l’ancien bloc : il suscite une réponse fondée sur l’état courant de chaque extrémité. Un doublon produit ainsi un doublon nouveau chez l’autre hôte.
Le RFC 1123 nomme ce phénomène « Sorcerer’s Apprentice syndrome ». Son exemple montre les paquets suivants du transfert répétés, à moins qu’une perte ne rompe la répétition. Le problème ne signifiait pas que les octets d’un fichier achevé étaient faux. Le RFC précise qu’un transfert terminé reste correct; en revanche, les répétitions peuvent le faire expirer avant son terme.
« Fiable » ne signifiait donc pas « insensible au délai ». Les numéros de bloc permettent de reconnaître l’acquittement visé, mais ne rendent pas inoffensive toute réponse à un bloc ancien. L’émetteur des données et celui des ACK pouvaient tous deux répondre aux doublons en répétant leur paquet courant. Chaque geste semblait raisonnable isolément; ensemble, ils formaient une boucle.
Le délai qui nourrit la congestion
Le document de 1989 décrit précisément le mécanisme. Un ACK retardé peut arriver après une expiration et une retransmission. Le DATA répété produit un autre ACK. Si le premier ACK apparaît après que l’émetteur a avancé, celui-ci peut répéter le nouveau bloc, qui génère encore des ACK. À moins qu’un paquet soit perdu, cette chaîne peut continuer dans les blocs suivants.
La congestion peut être à la fois le déclencheur et la conséquence. Un chemin chargé retarde l’ACK assez longtemps pour lancer la séquence. Les DATA et ACK dupliqués prennent ensuite davantage de capacité, ce qui augmente le risque de nouveaux retards. Le RFC avertit que cela peut accroître la congestion et provoquer d’autres délais. Il ne dit pas que tout transfert lent subissait ce syndrome ni qu’une panne historique particulière lui était due; il décrit un mécanisme de rétroaction au niveau du protocole.
Le RFC 1123 distingue aussi ce défaut de la politique de temporisation ordinaire. Il exige un délai adaptatif et recommande au minimum une croissance exponentielle du délai de retransmission. De meilleurs temporisateurs aident à supporter des délais variables; ils ne retirent pas la règle qui autorise un ACK ancien à provoquer un nouveau DATA. Il fallait modifier la réaction à l’acquittement dupliqué.
Une petite règle avant la révision
Le RFC 1123 impose la correction : l’émetteur DATA ne doit jamais renvoyer son bloc courant après avoir reçu un ACK dupliqué. Une fois cette réponse supprimée, l’ACK répété ne déclenche plus le DATA suivant en double et la boucle ne peut pas se propager. Le temporisateur du récepteur peut alors être supprimé, puisque renvoyer un ACK n’entraîne plus d’action; il peut aussi rester pour remplacer un ACK réellement perdu. L’émetteur DATA, lui, a toujours besoin de son propre délai de retransmission.
Pour un protocole destiné à un programme d’amorçage, cette correction pouvait aussi simplifier le récepteur. Elle n’exigeait ni fenêtre plus large, ni blocs de 512 octets différents, ni remplacement d’UDP. Elle coupait la rétroaction dangereuse tout en conservant le modèle d’un seul paquet en mémoire.
En juillet 1992, le RFC 1350 a remplacé le RFC 783 et est devenu STD 33. Il indique qu’une révision de mai 1992, réalisée par Noel Chiappa, a corrigé le bug de l’apprenti sorcier. Il faut distinguer les dates : le RFC 1123 avait déjà rendu le comportement obligatoire pour les implémentations; le document de 1992 a intégré la correction à la révision du protocole. La date de la nouvelle spécification ne prouve ni que toutes les implémentations étaient défectueuses jusque-là, ni qu’elles avaient toutes été mises à jour dès 1989.
Les extensions ultérieures ont traité une autre limite. L’option de taille de bloc de 1998 et les options suivantes ont amélioré le débit lorsque l’arrêt et l’attente étaient inefficaces; une fenêtre a ensuite autorisé plusieurs blocs en vol. Elles n’étaient pas la correction de l’ACK dupliqué. Augmenter le débit et empêcher un ancien ACK de multiplier les paquets courants sont deux changements distincts.
L’histoire de TFTP montre qu’une conception minimale peut déplacer sa complexité des formats vers les transitions d’état. Garder un seul bloc actif réduisait la mémoire et le travail d’implémentation. Mais le délai faisait diverger les notions de « paquet courant » des deux hôtes. La correction était tout aussi modeste : ne pas laisser un ACK dupliqué ordonner à l’émetteur DATA de répéter le bloc courant. La fiabilité dépendait autant de savoir quand ne plus retransmettre que de savoir quand recommencer.
Sources
- RFC 783 — The TFTP Protocol (Revision 2), 1981
- RFC 1123 — Requirements for Internet Hosts, 1989, §§4.2.1–4.2.3
- RFC 1350 — The TFTP Protocol (Revision 2), 1992
- RFC 768 — User Datagram Protocol
- RFC 951 — Bootstrap Protocol
- RFC 1542 — BOOTP Clarifications and Extensions
- RFC 2347 — TFTP Option Extension
- RFC 2348 — TFTP Blocksize Option
- RFC 2349 — TFTP Timeout and Transfer Size Options
- RFC 7440 — TFTP Windowsize Option
Briefing des membres
Contexte approfondi du profil
Connectez-vous avec le bon niveau d'adhésion pour débloquer le briefing complet et les notes de source.
Réservé à Strategic Circle
Strategic Circle
Ouvert à tous les lecteurs. Débloquez les briefings de profil après adhésion et connexion.
Rejoindre Strategic CircleRéservé aux membres de Leadership Alliance
Leadership Alliance
Réservé aux propriétaires et dirigeants qualifiés d'actifs IP ; connectez-vous pour débloquer les briefings Alliance.
Rejoindre Leadership Alliance
