Résumé

  • UDP ne comporte pas de mise en relation préalable comparable à celle de TCP. RFC 9298 impose donc au proxy de répondre sans attendre un paquet de la destination : le succès atteste l'ouverture d'une socket et la volonté de relayer.
  • La résolution d'un nom, la création de la socket, l'émission d'un datagramme, la réception d'un retour et l'acceptation par le protocole interne sont cinq faits distincts. Aucun ne doit être déduit automatiquement du précédent.
  • Le mérite éditorial du texte de David Schinazi tient à cette retenue. Il offre aux exploitants une sémantique de preuve exacte, à condition qu'ils ne la transforment pas en voyant général de disponibilité.

Un reçu délivré avant l'arrivée du destinataire

Imaginons une application qui demande à un proxy d'acheminer des datagrammes vers un serveur donné. Le proxy répond positivement en quelques millisecondes. Sur l'écran d'exploitation, la ligne devient verte. Pourtant, le serveur n'a encore rien envoyé. Il n'a peut-être même rien reçu.

Cette chronologie n'est pas une anomalie. Elle est au cœur de RFC 9298, Proxying UDP in HTTP. Le client construit une requête CONNECT-UDP à partir d'un modèle d'URI absolu contenant target_host et target_port. Le serveur HTTP qui assume le rôle de proxy extrait ces paramètres et ouvre une socket UDP vers la destination demandée. Les charges utiles circulent ensuite sous forme de HTTP Datagrams, selon le socle défini par RFC 9297.

Avec TCP, une ouverture vers un serveur distant implique ordinairement une poignée de main. UDP n'en a pas. Une socket dite « connectée » peut fixer localement un pair et faciliter le filtrage des paquets ; elle ne provoque aucune confirmation universelle de l'autre côté. Le proxy ne dispose donc d'aucune réponse nécessaire à attendre avant d'annoncer qu'il est prêt.

RFC 9298 formule son succès au millimètre : le proxy a ouvert une socket vers la cible demandée et accepte de relayer les charges UDP. Le document n'ajoute ni « la cible est joignable », ni « elle écoute », ni « elle a reçu », ni « l'application a reconnu la requête ». Le reçu décrit une opération locale orientée vers une adresse distante.

La distinction paraît modeste. Elle empêche pourtant une erreur très coûteuse : emprunter le témoignage d'une destination silencieuse pour enrichir le statut du proxy.

La résolution DNS est une preuve datée, pas une présence

Lorsqu'une adresse littérale est fournie, le proxy peut évaluer sa politique puis créer la socket. Lorsqu'il reçoit un nom DNS, RFC 9298 exige une résolution avant la réponse HTTP. Un échec de résolution impose le rejet de la requête, avec la possibilité de renseigner Proxy-Status selon le vocabulaire de RFC 9209.

Ce préalable donne un reçu utile. Il permet de dire : à telle heure, tel résolveur et telle politique ont produit telle adresse. Il ne permet pas de dire : le programme souhaité se trouve bien là et fonctionne.

Une observation sérieuse conserve le nom demandé, la réponse du résolveur, l'adresse choisie, la famille IP, l'heure, l'utilisation éventuelle d'un cache et le pair auquel la socket a effectivement été liée. Elle ne remplace pas ces données par une simple mention « DNS OK ». Si le nom change ensuite, la socket déjà créée continue de viser son état propre ; le tableau de bord doit pouvoir montrer cette divergence temporelle.

RFC 9209 nomme également des échecs de proxy tels que destination introuvable, indisponible, interdite ou non routable. Ces signaux négatifs expriment ce que l'intermédiaire sait ou décide. Leur absence n'est pas un signal positif symétrique. Un pare-feu peut éliminer sans réponse, ICMP peut ne pas revenir, un service peut ignorer une charge invalide, et certains protocoles UDP sont volontairement silencieux.

L'exploitant doit donc résister à la logique trompeuse « aucune erreur reçue, donc cible disponible ». Le silence ne signe rien.

La socket n'authentifie pas l'application

Une socket UDP connectée permet souvent au noyau de ne remettre au proxy que les datagrammes correspondant au bon quintuplet. Si le proxy emploie une socket non connectée, RFC 9298 lui impose de vérifier l'adresse IP et le port source de chaque retour, puis de jeter les paquets non conformes.

Cette exigence ferme une voie d'injection évidente. Elle ne transforme pas l'adresse et le port en identité applicative. Un datagramme provenant du bon couple peut être ancien, malveillant, incompréhensible ou dépourvu de toute authentification. C'est au protocole interne—QUIC, DNS ou un protocole métier—de dire qui a parlé et ce que signifie sa réponse.

La durée de la socket suit celle du flux HTTP. Tant que le flux reste ouvert, le proxy doit conserver la socket. S'il apprend que celle-ci est devenue inutilisable, par exemple après un ICMP Destination Unreachable transmis par le système, il ferme le flux. Il peut aussi appliquer un délai d'inactivité, que la RFC recommande de ne pas fixer sous deux minutes.

Ces règles permettent de produire un journal précis : création, mode connecté ou non connecté, pair, flux propriétaire, dernière activité et motif de fermeture. Elles ne permettent pas de certifier que le service est resté sain durant tout l'intervalle. Une socket ouverte témoigne de l'absence d'un motif de fermeture observé, pas d'un échange réussi en permanence.

Les datagrammes disposent de leur propre histoire

Le statut du tunnel ne raconte pas le trajet de chaque paquet. Dans RFC 9298, l'identifiant de contexte zéro porte les charges UDP. D'autres identifiants sont réservés à des extensions et vivent dans l'espace d'une requête donnée.

L'ordre d'arrivée n'est pas garanti. Un datagramme portant un contexte encore inconnu peut être éliminé en silence ou conservé brièvement dans l'attente de son enregistrement. Un datagramme arrivé avant la requête correspondante connaît le même sort. Le client peut d'ailleurs envoyer de manière optimiste avant d'avoir reçu la réponse CONNECT-UDP, tout en sachant que ces paquets risquent de ne jamais être traités.

La taille ouvre une autre brèche entre acceptation et livraison. Une charge Context ID zéro ne peut dépasser 65 527 octets. Même en dessous, le MTU du chemin peut imposer une limite plus basse. Le proxy n'a pas le droit d'introduire lui-même une fragmentation IP et peut devoir jeter silencieusement le datagramme trop grand.

Ainsi, une requête acceptée peut coexister avec zéro datagramme transmis, ou avec des envois sans retour, ou avec un retour éliminé par validation de source, ou avec un échange réseau que l'application refuse. L'architecture n'est compréhensible que si ces étapes restent visibles séparément.

Situer David Schinazi sans lui prêter tout MASQUE

RFC 9298 a été publiée en août 2022 sur la voie Standards Track de l'IETF et porte le nom de David Schinazi comme auteur. La fiche écrite de l'IETF, capturée le 2 septembre 2026, le présente comme ingénieur principal et cadre chez Google, principalement actif sur Privacy Proxy, MASQUE et OHTTP. Elle mentionne aussi ses responsabilités antérieures dans QUIC, Chrome Networking et des technologies réseau chez Apple. Ces éléments décrivent un moment ; ils peuvent évoluer.

Le portrait officiel de l'IETF sert ici à établir l'identité visuelle, pas à prouver une responsabilité sur une mise en production. De même, l'environnement technique est collectif. RFC 9297 a deux auteurs, Schinazi et Lucas Pardue. RFC 9484, qui étend le domaine au proxy IP et ajuste l'enregistrement de l'URI bien connue masque, en compte cinq. Le groupe de travail MASQUE est une communauté d'ingénierie, non l'œuvre d'une seule personne.

Le profil pertinent est donc celui d'un auteur qui a formulé correctement une limite. La force de RFC 9298 n'est pas d'obtenir un statut plus spectaculaire que la réalité ; elle réside dans le refus de confondre l'état du proxy et celui du destinataire.

Cette retenue rejoint la primauté du code en fonctionnement défendue par Heng Lu : un système doit recevoir le crédit correspondant à sa fonction déterministe, pas l'autorité symbolique d'une couche voisine. La spécification initiale minimale fournit l'autre moitié du raisonnement. Le tunnel expose une base commune étroite ; chaque protocole interne conserve la responsabilité de son authentification, de ses acquittements, de ses pertes et de son succès.

Construire une chaîne de reçus, non un super-statut

La première pièce concerne l'autorisation du proxy. Elle identifie la classe de client, la cible demandée, la règle appliquée, les budgets de débit ou de volume et la décision. Le contrôle est indispensable parce que le serveur distant voit normalement l'adresse du proxy. Sans restrictions, un client peut faire attribuer au proxy une activité nuisible ou atteindre des adresses locales, multicast, broadcast ou link-local qui lui seraient autrement fermées.

La deuxième pièce décrit la résolution. La troisième décrit la socket. La quatrième compte les datagrammes sortants, entrants et jetés, avec un motif lorsque celui-ci est connu : taille, contexte, tampon, validation du pair ou erreur système. Ces mesures peuvent rester agrégées ; conserver le contenu n'est pas nécessaire pour prouver un passage.

La cinquième pièce appartient au protocole interne. Une poignée de main QUIC authentifiée, une réponse DNS corrélée, un accusé métier ou une erreur explicite répondent à des questions que HTTP ne peut pas trancher. Un délai expiré et un nouvel essai doivent également être décrits à ce niveau, car répéter un paquet n'a pas le même effet dans toutes les applications.

Le tableau de bord obtient alors des états honnêtes : proxy prêt ; nom résolu ; datagramme sortant observé ; datagramme entrant observé ; pair authentifié ; opération acceptée. Un incident n'a plus à deviner où la chaîne s'est interrompue.

Une réussite qui ne parle que pour elle-même

Les systèmes d'observabilité préfèrent les catégories peu nombreuses. Ils transforment volontiers un événement facile à obtenir en résultat global. Le succès CONNECT-UDP arrive tôt, il est standardisé et simple à compter. Il est donc tentant d'en faire la mesure de santé de bout en bout.

Ce raccourci détruit l'information contenue dans la RFC. Il peut maintenir du trafic vers une destination muette, attribuer à l'application une perte due au MTU, prendre un filtrage de quintuplet pour une authentification ou classer une socket sans retour comme usage sain. Plus l'automatisation agit vite, plus l'erreur s'amplifie.

Schinazi a donné au proxy une phrase exacte à prononcer. Le proxy peut dire qu'il a autorisé, résolu, ouvert et qu'il est prêt à transmettre. Il ne peut pas dire que l'autre côté a répondu. Pour prononcer cette seconde phrase, il faut attendre le reçu d'un autre acteur.

Sources