Résumé

  • TFTP réservait le port 69 au rendez-vous initial ; le client et le serveur choisissaient ensuite chacun un TID, porté comme numéro de port, pour toute la durée du transfert.
  • Cette frontière locale permettait de rejeter un paquet venu d’un autre TID sans casser l’échange légitime ; la correction des retransmissions en cascade et les options ultérieures ont conservé cette séparation.

Deux réponses à une seule intention

RFC 1350 donne à l’apparente anomalie une fonction exacte. Un client choisit son identifiant de transfert et adresse une RRQ ou une WRQ au TID connu 69 du serveur. Si la demande est admise, le serveur ne continue pas nécessairement depuis 69. Il choisit son propre TID. Le premier DATA d’une lecture, ou l’ACK zéro d’une écriture, révèle ce deuxième nombre ; le couple devient ensuite la référence de tous les paquets.

Une duplication de la demande peut donc produire deux réponses valides du point de vue du serveur, mais issues de deux TID différents. Le client fixe le transfert sur la première réponse qu’il accepte. La seconde n’est pas une nouvelle étape du même échange. Elle reçoit l’erreur 5, « Unknown transfer ID », tandis que la conversation retenue continue.

Cette exception est remarquable. La plupart des erreurs TFTP terminent l’opération et leur paquet ERROR n’est ni acquitté ni retransmis. Le mauvais TID, lui, ne condamne pas le transfert en cours, parce que l’erreur concerne justement ce qui reste hors de sa frontière.

Le port public ne possédait pas le fichier

La simplicité était une intention de conception. RFC 783 décrivait un outil capable de lire ou d’écrire un fichier avec peu de code, sans liste de répertoires ni mécanisme d’authentification utilisateur. Le port connu offrait un endroit stable où demander un service. Il n’avait pas à concentrer tous les fichiers et tous les accusés de tous les clients.

Les TID reportaient l’état dans l’en-tête du datagramme. Ils étaient utilisés comme ports source et destination. Le serveur pouvait écouter les nouvelles demandes sur 69 tout en isolant chaque transfert par un autre endpoint. Une règle réseau qui attend les données depuis 69 confond le guichet avec le dossier qu’il vient d’ouvrir.

Il faut cependant limiter le sens de cette isolation. Un TID aléatoire réduit la réutilisation immédiate et distingue des conversations. Il n’authentifie pas le serveur, ne chiffre rien et n’atteste ni l’origine ni l’intégrité du fichier. Il répond seulement à la question : « ce paquet appartient-il au couple que cet échange a retenu ? »

Un seul bloc définissait l’avancement

Le TFTP d’origine avançait en verrouillage alterné. Le DATA numéro un attendait son ACK avant que le numéro deux puisse partir. Avec des blocs de 512 octets, le côté émetteur ne gardait que le bloc courant ; le côté récepteur n’avait pas à réordonner une fenêtre. Un bloc plus court marquait la fin. Pour un fichier exactement multiple de 512, un bloc final vide rendait cette fin explicite.

Le dernier ACK n’était pourtant pas une preuve éternelle. Son émetteur était invité à patienter : si le dernier DATA revenait, cela signifiait que l’ACK avait pu se perdre et qu’il fallait le répéter. La clôture était donc une petite période de responsabilité, pas un bouton instantané.

Cette économie donnait aux numéros de bloc, aux deux TID et au temporisateur un rôle commun. Ensemble, ils disaient si le paquet faisait progresser le transfert, répétait un état déjà vu, provenait d’une autre conversation ou appelait une récupération.

Quand chaque doublon engendrait son apprenti

La première règle de retransmission avait une faiblesse. Après un délai, un côté pouvait renvoyer son dernier datagramme. Si une vieille copie finissait ensuite par arriver et provoquait une nouvelle réponse, les deux pairs pouvaient se mettre à répondre à chaque doublon par un autre doublon.

RFC 1123 a nommé le phénomène syndrome de l’apprenti sorcier. Le fichier restait éventuellement correct, mais la quantité de DATA et d’ACK doublait. Le trafic supplémentaire renforçait la congestion à l’origine du retard et pouvait conduire à l’expiration du transfert.

La correction obligatoire retirait une autorité au vieil ACK : l’émetteur des DATA ne devait jamais renvoyer le bloc courant seulement parce qu’un ACK dupliqué arrivait. Un temporisateur ou l’état attendu pouvait autoriser la retransmission ; un signal périmé ne le pouvait pas. RFC 1350 a remplacé RFC 783 en intégrant cette correction.

Négocier davantage sans déplacer la frontière

La petite fenêtre d’un bloc était adaptée à une mémoire limitée, moins à un réseau capable de garder plusieurs blocs en vol. RFC 2347 a introduit une négociation attachée à la demande. Seul le client propose. Le serveur peut acquiescer à certaines options dans OACK, en omettre d’autres ou refuser une valeur invalide selon la règle de l’option. Il ne peut pas ajouter une préférence que le client n’a jamais demandée.

Dans une lecture, ACK zéro confirme l’OACK ; dans une écriture, le premier DATA le fait. Une option absente de l’OACK est traitée comme si elle n’avait jamais été proposée. RFC 2348 a permis de changer la taille de bloc, RFC 2349 le délai et l’annonce de la taille totale. RFC 7440 a permis une fenêtre de blocs consécutifs, acquittée par son dernier numéro.

Ces extensions ont accru le travail autorisé avant un ACK. Elles n’ont pas transformé le port 69 en canal de données, ni le TID en identité durable. L’accord de paramètres restait dans le transfert délimité par les deux endpoints.

La sécurité se trouvait ailleurs

Le protocole pouvait rejeter un port source inattendu et reconnaître un numéro de bloc. Il ne savait pas si un chemin de fichier devait être exposé, si un client pouvait écrire, si une image de démarrage avait été approuvée ou si la machine située à l’adresse annoncée était digne de confiance.

Ces responsabilités appartiennent aux racines de fichiers autorisées, aux permissions, au filtrage d’adresses, à la provenance des artefacts, aux dispositifs réseau qui suivent le changement de port et aux journaux qui relient la demande initiale au couple dynamique. Ouvrir tous les ports UDP parce que TFTP en choisit un revient à supprimer la limite que le protocole avait précisément créée.

L’histoire conserve ainsi une leçon subtile : un nom public peut donner le droit de frapper à la porte sans gouverner la conversation qui suit. L’erreur correcte peut sauver le transfert légitime au lieu de tout arrêter. Et une amélioration de débit reste compatible seulement si l’accord, l’ordre et les extrémités restent observables.

Sources et limites

RFC 783 décrit la première révision étudiée, RFC 1123 la correction des doublons et RFC 1350 le protocole révisé. Les options sont définies par RFC 2347, RFC 2348, RFC 2349 et RFC 7440. Le registre IANA consigne le port 69. Ces textes ne fournissent pas de recensement actuel et ne font d’un TID ni une authentification, ni une autorisation, ni une preuve du contenu.