Résumé

  • La RFC 2391 faisait d'une adresse virtuelle l'entrée d'un pool et liait chaque nouvelle session à un serveur dont les paramètres de traduction gouvernaient tous les paquets suivants.
  • Le nombre de sessions, le trafic, les pondérations, le coût de route ou un ping alimentaient un choix local ; aucun ne constituait une mesure certaine de la capacité applicative.
  • Déclarer un hôte mort empêchait de lui attribuer de nouvelles sessions, sans transférer celles qui lui étaient déjà liées : évitement, continuité et reprise restaient trois problèmes différents.

La simplicité vue depuis le client

Le client ne voulait pas connaître l'inventaire d'une ferme de serveurs. Il voulait joindre un service. La RFC 2391 partait de cette asymétrie : la demande augmentait, un seul serveur ne suffisait plus, mais modifier tous les clients pour leur apprendre l'organisation du pool aurait déplacé la complexité au mauvais endroit.

Le LSNAT offrait donc une adresse de serveur virtuelle. Derrière elle, plusieurs machines pouvaient fournir le même service. Le traducteur recevait le début d'une session, choisissait un membre selon un algorithme de répartition, puis redirigeait les paquets. Les nœuds du pool pouvaient être ajoutés, retirés ou remplacés sans rendre ces changements visibles au client.

Cette transparence était une transformation, non une disparition de la complexité. L'adresse publique cessait d'identifier la machine qui allait exécuter la requête. Elle identifiait le point où une décision serait prise. L'autorité opérationnelle passait du routage ordinaire à un intermédiaire chargé de choisir, de réécrire et de se souvenir.

Ce mécanisme ne répétait pas l'anycast de la RFC 1546. Dans l'anycast, l'ambiguïté vient d'une adresse de service que le routage peut conduire vers plusieurs instances, parfois différemment d'un datagramme au suivant. Ici, l'intermédiaire créait une relation persistante pour une session. La question historique propre à la RFC 2391 est donc celle de l'état conservé après la sélection.

Le premier paquet engageait les suivants

La RFC distinguait trois phases. La liaison de session associait une nouvelle conversation à l'adresse d'un serveur du pool. Cette association fixait les paramètres de traduction de tous les datagrammes ultérieurs. La recherche et la traduction retrouvaient ensuite cette association pour chaque paquet. La déliaison mettait fin à la responsabilité du serveur lorsque la session était jugée terminée.

Le mot « liaison » mérite son poids. La décision n'était pas un conseil que le paquet suivant pouvait ignorer. Les champs de destination étaient modifiés à l'aller ; les champs de source pouvaient l'être au retour, avec les ports et sommes de contrôle nécessaires. Le client continuait à voir l'adresse virtuelle parce que le traducteur reconstruisait cette apparence à chaque passage.

Tous les paquets de la session, requêtes comme réponses, devaient donc traverser le même LSNAT. Un retour qui évitait l'intermédiaire exposait une identité que le client n'attendait pas. Un autre traducteur, dépourvu de la table, ne connaissait pas le serveur choisi. Une simple route de remplacement ne recréait pas l'état.

La limite énoncée par le texte était nette : une fois affectée à un hôte, la session ne pouvait pas être déplacée vers un autre avant sa fin. Le pool distribuait les admissions. Il ne migrait ni l'état TCP, ni le contexte applicatif, ni l'opération en cours.

Les algorithmes comptaient ce qu'ils pouvaient voir

La forme la plus simple, le tourniquet, ne mesurait aucune charge. Elle supposait implicitement qu'une distribution régulière des arrivées produirait une distribution acceptable du travail. Cette hypothèse pouvait suffire dans un pool homogène et devenir fausse dès qu'une requête longue suivait une requête triviale.

Le choix du serveur ayant le moins de sessions semblait plus informé. Il supposait néanmoins que deux sessions coûtaient à peu près la même chose et que les machines avaient des capacités comparables. Or une connexion presque inactive peut rester ouverte longtemps, tandis qu'une courte opération peut saturer le processeur ou le disque.

Le comptage des paquets ou des octets rapprochait l'observation du trafic réel, sans mesurer la charge du système. La RFC le qualifiait d'approximation raisonnable, non d'équivalence. Un petit message pouvait déclencher un calcul coûteux ; un grand transfert pouvait être servi efficacement depuis un cache.

Les pondérations rendaient le modèle explicite. L'opérateur attribuait un coût aux types de sessions et une puissance relative aux serveurs. Le calcul devenait adaptable, mais il incorporait un jugement humain sur le futur. Une pondération n'était pas une télémétrie ; c'était une estimation mise en production.

Le document reconnaissait qu'une connaissance précise et instantanée de la capacité inutilisée d'une machine distante était difficile. Les serveurs pouvaient participer et annoncer leurs ressources. Cette amélioration créait à son tour des questions de fraîcheur, de confiance et de cadence. Entre le signal et la décision, le monde pouvait déjà avoir changé.

Le coût de route ne réservait aucune ressource

Lorsque les membres du pool étaient éloignés, la sélection pouvait consulter les coûts fournis par le routage. La RFC proposait de combiner proximité et charge attribuée. Si un serveur devenait inaccessible, son coût pouvait être porté à l'infini afin qu'il ne reçoive plus de nouvelles sessions.

Ce calcul décrivait un chemin connu par le sélecteur. Il ne réservait ni bande passante, ni mémoire, ni file applicative. C'est précisément la frontière qui sépare cette histoire de la RFC 2386 : une carte de ressources QoS y restait distincte de l'admission et de la livraison ; ici, une métrique de route ou de charge restait distincte de la liaison et de l'issue de la session.

La chaîne de preuve était plus longue que le tableau du répartiteur. Configuration du pool, métrique observée, règle de choix, liaison créée, traduction effective, réponse du serveur et résultat utilisateur formaient des étapes séparées. La première ne pouvait pas délivrer le reçu de la dernière.

Retirer un serveur du futur ne réparait pas son passé

La RFC 2391 prévoyait le cas du serveur silencieux. Le LSNAT pouvait envoyer des pings ou vérifier si un membre répondait après l'attribution d'une nouvelle session. Après quelques secondes sans réponse, il pouvait déclarer l'hôte mort et cesser de lui affecter de nouvelles conversations.

Le retour dans le pool restait lui aussi expérimental. Après une pause, l'intermédiaire pouvait confier de nouvelles sessions au serveur et observer à nouveau son délai de réponse. L'état « vivant » résultait d'un signal et d'une politique locale. Il ne certifiait pas que chaque service écoutait, que ses dépendances fonctionnaient ou qu'une transaction particulière réussirait.

La portée du dispositif se lit dans ses verbes. Le serveur mort ne recevait plus de nouvelles sessions. Ailleurs, le même document interdisait de déplacer une session déjà affectée avant sa fin. On peut donc conclure, sans attribuer au texte une promesse qu'il ne fait pas, que la détection protégeait les admissions futures. Elle n'offrait pas de reprise transparente pour les conversations existantes.

Le pool pouvait afficher trois machines saines pendant que cent sessions attachées à la quatrième échouaient. L'indicateur agrégé « service disponible » effaçait alors le bon objet d'observation : la liaison particulière et l'état qu'elle rendait irremplaçable.

La RFC 3022 montrera plus tard le même problème lors de la panne d'un NAT. Rediriger les paquets vers un autre boîtier pouvait casser les flux si la configuration et l'état de session n'étaient pas partagés. La RFC 3234 distinguera le redémarrage d'une véritable bascule : l'état dur exige une copie utilisable, pas seulement une autre machine allumée.

Même la fin devait être interprétée

La déliaison supposait que le LSNAT sache quand la session était finie. TCP fournissait des indices comme FIN et RST, mais une disparition brutale ou une perte de paquets pouvait laisser la table sans conclusion propre. UDP n'avait pas de fin universelle. Le silence pouvait signifier l'attente, la panne ou l'abandon.

Un délai d'inactivité transformait ce silence en décision. Trop court, il supprimait une liaison encore utile. Trop long, il retenait des entrées mortes et consommait des ressources. La RFC 2663 précisera que la session vue par le NAT ne coïncide pas nécessairement avec celle de l'application et qu'aucune valeur de délai ne convient dans tous les cas.

La RFC 4787 encadrera plus tard certains délais UDP. Elle documentera aussi leur variation et les différentes manières de les rafraîchir. Normaliser un minimum ne transformait pas l'absence de paquet en connaissance certaine de l'application.

La liaison avait ainsi deux décisions difficiles : quand la créer et quand la détruire. Entre les deux, elle détenait une autorité réelle sur l'identité des paquets. Une table interne apparemment administrative était devenue un élément du service.

Une autre topologie, davantage de traduction

Le premier modèle plaçait le pool dans un domaine où le passage par le LSNAT était naturel. La variante LS-NAPT allait plus loin : en traduisant les deux côtés, elle forçait clients et serveurs à renvoyer leurs paquets par l'intermédiaire. Les serveurs pouvaient alors être répartis plus librement et les liens d'accès pouvaient évoluer.

La souplesse s'achetait avec plus de traitement. Davantage de champs étaient modifiés. Le cas décrit se limitait à TCP et UDP. L'espace de ports disponibles bornait le nombre de sessions simultanées par adresse et par serveur. La contrainte topologique ne disparaissait pas sans laisser de trace ; elle était remplacée par une contrainte de table, de ports et de calcul.

Cette conversion caractérise les middleboxes. RFC 1631 vantait l'installation de NAT sans modification des hôtes, tout en notant la perte de signification de bout en bout de l'adresse IP. RFC 2391 appliquait cette propriété à la répartition : la simplicité des extrémités dépendait d'un état plus riche dans le réseau.

La RFC 7098 parlera plus tard de « persistance » pour la garantie qu'une session reste sur un même serveur jusqu'à son achèvement. Le mot éclaire le mécanisme de 1998. Mais persister n'est pas migrer. La liaison stabilise la destination ; elle n'assure pas sa survie.

Ce que l'adresse ne disait pas

L'adresse virtuelle disait où commencer. La liste du pool disait qui pouvait être choisi. Le signal de charge disait ce que le sélecteur croyait voir. L'algorithme disait comment cette observation serait convertie en décision. La liaison disait quel serveur avait été retenu. Les paquets traduits prouvaient que le chemin fonctionnait. Seule l'application pouvait prouver que le travail demandé avait abouti.

Confondre ces niveaux produit des promesses trompeuses. Un serveur enregistré peut être indisponible. Un ping répondant peut masquer une application morte. Une machine peu chargée peut manquer d'une dépendance. Une liaison valide peut conduire à une erreur. Un flux stable peut livrer un résultat incorrect.

Les notes de Heng Lu invitent à conserver cette hiérarchie des réalités : un document ou un registre coordonne des symboles ; il ne fabrique pas l'état vivant qu'il décrit. La RFC 2391 avait justement créé une surface très simple pour le client. Sa rigueur tient à ce qu'elle n'a pas transformé cette simplicité en magie. Elle a exposé le prix : sélection locale, état durable, passage obligé et observations imparfaites.

Le serveur de réserve était bien réel. Pour la session déjà liée, il était pourtant hors du mécanisme. La répartition avait distribué les débuts ; elle n'avait pas rendu les histoires interchangeables.

Sources