Résumé

  • RFC 3018 décrivait un espace d’adressage réparti de 128 bits dans lequel une machine virtuelle pouvait lire, écrire, allouer, libérer ou transférer le contrôle vers un autre nœud.
  • La transaction garantissait l’exécution groupée ou l’absence d’exécution, mais le texte excluait l’annulation après coup. L’atomicité du départ n’était donc ni une restauration, ni une preuve de sécurité, ni un constat du résultat final.

Tant que le lot attendait dans la mémoire du destinataire, le choix restait net. Une instruction pouvait ordonner son exécution. Une autre pouvait l’effacer. La difficulté commençait au moment précis où le lot cessait d’être un objet en attente pour devenir une série d’effets.

RFC 3018 ne contourne pas cette difficulté par le vocabulaire. La section consacrée aux transactions dit que l’annulation après exécution n’est pas prévue. Si une compensation est nécessaire, elle relève de la machine virtuelle, car certaines instructions, notamment un transfert de contrôle, peuvent être impossibles à annuler.

Cette phrase donne sa mesure historique à l’Unified Memory Space Protocol Specification, publiée en décembre 2000 avec le statut Experimental. UMSP ne cherchait pas seulement à envoyer une requête à un service. Il proposait un espace mémoire de 128 bits réparti entre des nœuds Internet. Une application devait pouvoir manier une adresse distante comme une instruction : lire, écrire, réserver de la mémoire, la libérer, déplacer du code, appeler une procédure d’objet ou sauter vers une autre machine.

Le réseau disparaissait de l’interface de l’application. Il ne disparaissait pas du régime de panne.

Une adresse commune ne créait pas un propriétaire commun

Le modèle distinguait trois niveaux : le job distribué, sa tâche locale sur chaque nœud et les fils de contrôle exécutés par les machines virtuelles. Un Job Control Point, ou JCP, suivait la création et la fin des tâches et attribuait les identifiants de contrôle.

La carte paraissait unifiée, mais les responsabilités demeuraient fractionnées. Le JCP coordonnait le job. Chaque nœud gardait sa mémoire. La VM contrôlait les pointeurs, les ressources et l’ordre d’exécution. Le transport déplaçait les octets. Le code utilisateur lançait des opérations dont le résultat pouvait émerger ailleurs.

Le RFC indique lui-même que le protocole ne gère pas la mémoire locale du job et ne suit pas les fils de contrôle de l’utilisateur. Lorsqu’une tâche se termine, c’est la VM qui doit invalider les pointeurs qui la concernent. Un segment de code continu ne peut pas être réparti sur plusieurs nœuds, même si un transfert vers une adresse distante crée un nouveau fil sur le nœud visé.

Le pointeur de seize octets réunissait donc des espaces de noms. Il ne réunissait ni les horloges, ni les journaux, ni les autorités de reprise.

Recevoir, retenir et exécuter étaient trois états

UMSP organisait les instructions en chaînes. Une séquence imposait un ordre de dépendance : si une étape échouait, les suivantes étaient annulées. Une transaction pouvait rassembler des instructions sans dépendance directe, mais exigeait que toutes s’exécutent ensemble ou qu’aucune ne s’exécute.

Pour obtenir cette propriété, le destinataire devait connaître la longueur du lot et souvent le conserver en mémoire jusqu’à réception complète. _BEGIN_TR portait les paramètres ; _END_CHAIN marquait la dernière instruction.

Ensuite venait la décision. Avec TRR=1, l’arrivée de la fin du lot déclenchait immédiatement l’exécution. Avec TRR=0, il fallait un EXEC_TR distinct. Avant ce départ, CANCEL_TR pouvait supprimer les instructions retenues, sans possibilité de les restaurer.

Un autre drapeau, TRE, modifiait le comportement face au temps et à la rupture. Si le lot était complet mais encore en attente, TRE=1 pouvait imposer son exécution à l’expiration de sa durée de vie ou lors d’une fin anormale de session. Avec TRE=0, la même situation conduisait à l’annulation. Le compteur de durée ne commençait qu’après réception de toutes les instructions ; zéro signifiait aucune limite.

Un incident de transport pouvait donc rencontrer plusieurs réalités. Le lot pouvait être incomplet. Il pouvait être complet et retenu. Il pouvait avoir été libéré par un ordre explicite. Il pouvait aussi avoir été déclenché par la règle d’expiration ou la rupture de session.

Le mot « transaction » ne suffit pas à distinguer ces cas. Il faut conserver l’identité et l’empreinte du lot, l’accusé de réception complet, l’état tamponné, la cause de libération ou d’annulation, puis le résultat de chaque instruction ayant un effet.

Tout exécuter ensemble ne signifiait pas tout défaire ensemble

La promesse de RFC 3018 porte sur l’entrée en exécution. Elle ne construit pas automatiquement l’inverse de ce qui a été exécuté.

Une écriture distante peut être lue par un autre fil avant toute tentative de compensation. FREE peut rendre invalide un pointeur qui circule encore. MVRUN ou le déplacement de code peut créer un comportement nouveau. Un CALL peut appeler une procédure qui envoie un message, commande un équipement ou modifie un état extérieur. Un JUMP peut créer un nouveau fil de contrôle qui poursuit son travail après la disparition de la chaîne initiale.

Même une exécution parfaitement atomique peut donc produire un monde qui n’a pas d’opération inverse générique.

Imaginons un lot qui réserve une zone, y installe du code et lui transfère le contrôle. Le protocole peut décider que ces instructions commencent comme une unité. Mais si le nouveau fil publie une donnée ou déclenche une action extérieure, effacer le lot original n’efface pas l’action. L’atomicité règle l’admission ; elle ne remonte pas le temps.

Cette frontière distingue aussi la commande du constat. EXEC_TR désigne une chaîne et demande son exécution. Il ne prouve pas à lui seul que chaque effet a abouti, que l’application a atteint son but, que les états extérieurs sont cohérents ou qu’une compensation ultérieure a réussi.

TCP transportait les octets, pas le verdict de la VM

UMSP exigeait que TCP soit disponible pour les échanges fiables et permettait UDP pour certaines données sans accusé de réception. RFC 793 fournit précisément un flux d’octets fiable et ordonné, avec récupération des pertes, des doublons, du désordre et des dommages détectés.

Cette garantie est nécessaire et limitée. L’accusé TCP établit un fait au niveau du transport. Il ne dit pas que l’instruction a été validée, rangée dans la bonne transaction, relâchée par la bonne autorité, exécutée sur la bonne version de mémoire ou suivie de l’effet attendu.

RFC 1831, sur ONC RPC, expose une incertitude voisine. Une réponse reçue au-dessus de TCP peut permettre d’inférer une exécution selon son modèle. L’absence de réponse ne permet pas d’inférer l’absence d’exécution : le serveur peut avoir agi avant la panne. Le texte rappelle aussi qu’un appel distant se distingue d’un appel local par la gestion des pannes, les effets de bord, la performance et l’authentification.

UMSP renforçait encore l’illusion locale en donnant à ces opérations la forme d’instructions de mémoire et de contrôle. Cette élégance d’interface augmentait la nécessité de journaux explicites.

Le centre de contrôle n’était pas un témoin omniscient

Le JCP apportait une autorité centrale au cycle de vie du job. Il attribuait l’identifiant global, suivait les tâches et pouvait participer à l’identification des utilisateurs et à la protection contre les attaques.

Un centre facilite la corrélation, mais sa position ne crée pas les observations qui lui manquent. La VM demeurait responsable de la mémoire et des pointeurs. Le fil distant pouvait agir hors du champ immédiat du JCP. Une connexion pouvait se rompre après l’effet et avant la réponse. Un nœud pouvait redémarrer alors que l’identification des anciens segments de session restait une exigence.

« Job terminé » décrit donc le cycle de vie du job. Ce n’est pas encore la preuve que toutes les écritures utiles ont persisté, que chaque procédure a agi une seule fois ou que le résultat extérieur recherché a été observé.

La sécurité figurait parmi les extensions futures

La section de sécurité commence par une limitation sans ambiguïté : les questions de sûreté ne sont pas incluses dans le mécanisme initial afin d’en réduire la complexité. Les propositions qui suivent sont des pistes d’extension.

Le document évoque les protections de TCP/IP, des chaînes soumises à un traitement spécial pour l’intégrité ou le chiffrement, et des paramètres d’authentification dans des en-têtes d’extension. Il imagine des authentifications entre les deux nœuds et le JCP. Pour détecter une attaque intermédiaire, il s’appuie sur des routes distinctes entre ces parties et admet qu’une passerelle commune affaiblit cette défense.

Il identifie aussi JUMP et CALL comme sources possibles de déni de service et confie à la VM le contrôle des ressources. Il juge le téléchargement de code actif risqué pour le client et l’exécution du code du client risquée pour le serveur.

Ces observations dessinent la surface d’attaque. Elles ne fixent pas les algorithmes, les clés, les identités, les autorisations, la prévention du rejeu, la révocation ou l’audit.

RFC 3552, publié plus tard, fournit un contraste utile : son modèle Internet suppose qu’un attaquant puisse lire, supprimer, modifier ou injecter du trafic. Il ne faut pas appliquer rétroactivement ce texte comme une obligation de 2000. Il montre toutefois pourquoi une séparation de routes ou un en-tête non spécifié ne peut devenir, par simple déduction, une preuve de sécurité complète.

Un RFC Experimental conservait une proposition, pas une adoption

RFC 2026 classe les documents Experimental hors de la filière des normes et précise qu’ils ne sont pas des Internet Standards. Ils peuvent archiver un travail de recherche ou de développement. RFC 2119 et RFC 2234 fournissaient à RFC 3018 son vocabulaire normatif et sa syntaxe ABNF ; RFC 768 et RFC 793 bornent les propriétés de transport ; RFC 1831 offre un voisinage conceptuel pour l’appel distant.

Ces sources établissent le dessin du protocole. Elles n’établissent aucune mise en production, implémentation, interopérabilité, panne ou adoption d’UMSP.

L’intérêt historique est ailleurs. RFC 3018 a poussé très loin l’idée que le réseau pouvait se cacher derrière une abstraction de calcul. En chemin, il a rendu visible ce que l’abstraction ne pouvait pas supprimer : une adresse commune ne crée pas une garde commune ; un lot atomique ne crée pas une restauration ; des octets livrés ne créent pas un résultat ; une coordination centrale ne crée pas une observation totale.

Les lectures de Lu Heng permettent de nommer ces étages. Running-Code Primacy sépare l’instruction publiée de son effet dans un système actif. Reality Layers empêche le lot encodé, le tampon, la libération, l’exécution et l’issue de se prêter mutuellement leurs preuves. Minimum Initial Specification explique comment un noyau mince peut réserver des extensions, à condition que les contrats absents—sécurité, compensation, observation—restent visibles.

Ce sont des grilles d’analyse ultérieures, non des intentions attribuées à l’auteur.

Le lot était atomique. Le monde qu’il touchait ne l’était pas nécessairement.

Sources