Résumé

  • RFC 5118 protège les messages d’essai par la convention allOneLine et par une archive binaire exacte : un copier-coller depuis la mise en page ne suffit pas à établir les octets testés.
  • Une URI peut être syntaxiquement valide tout en absorbant le port visé dans le dernier groupe de l’adresse IPv6 ; le parseur réussit, mais l’intention de destination n’est pas conservée.
  • L’acceptation tolérante d’un paramètre Via received entre crochets est une exception d’interopérabilité bornée, assortie d’une sortie canonique, et non une permission générale de réparer silencieusement les messages.

Sur la page, l’en-tête occupe deux lignes. Sur le réseau, il n’en occupe qu’une. Entre les deux, un espace ajouté au mauvais endroit suffit à créer un autre message, une autre longueur de corps ou une autre branche de grammaire.

RFC 5118 prend ce problème au sérieux. Comme RFC 4475, il encadre les longues lignes dans allOneLine et prescrit leur reconstruction. Il ajoute une archive encodée contenant les représentations exactes. La publication reste lisible par un humain ; la pièce d’essai reste reproductible par une machine.

La garde des octets précède le verdict

Un laboratoire qui copie un exemple depuis un navigateur ne peut pas encore dire qu’il a exécuté le test du RFC. Le repli visuel, les fins de ligne, les espaces initiaux et Content-Length peuvent avoir changé. Il faut d’abord conserver l’archive, la méthode d’extraction et le hachage de chaque fixture. Le verdict du parseur vient ensuite.

Cette discipline paraît administrative. Elle est en réalité technique : une sortie rouge obtenue sur des octets différents ne réfute rien ; une sortie verte obtenue après normalisation préalable ne prouve pas que le produit accepte l’entrée originale. La chaîne d’observation doit distinguer la source, la transformation et l’exécution.

Le RFC lui-même borne son autorité. Il est informatif, non normatif pour SIP, et ne cherche ni toutes les formes invalides ni toutes les formes valides inhabituelles. Certains messages ne sollicitent que le parseur ; d’autres sollicitent aussi l’application. Un score global écrase ces différences.

Le port était devenu une partie de l’adresse

Le cas le plus révélateur écrit une URI semblable à ceci :

sip:[2001:db8::10:5070]

L’auteur voulait probablement l’hôte 2001:db8::10 et le port 5070. Or le crochet se ferme après 5070. La grammaire attribue donc cette valeur au littéral IPv6. Le port n’est pas mal décodé ; il n’existe pas comme composant port.

Le message reste bien formé du point de vue du parseur. Il ne produira pourtant pas le résultat souhaité. L’erratum vérifié 1311 précise que la valeur devient la dernière paire d’octets de l’adresse IPv6, et non le dernier octet. Conserver cette correction évite de transformer un exemple de précision en nouvelle approximation.

La forme intentionnelle ferme d’abord le littéral, puis ajoute le port :

sip:[2001:db8::10]:5070

Deux chaînes acceptées, deux arbres de composants, deux destinations. Le bit valid ne peut pas dire laquelle était voulue. Il faut une attente indépendante : hôte prévu, port prévu, adresse finalement choisie et socket observé.

La robustesse n’efface pas la grammaire

RFC 5118 montre aussi un cas où l’application stricte de la grammaire ne suffit pas à l’interopérabilité. Dans Via, sent-by utilise une référence IPv6 entre crochets, tandis que le paramètre received de RFC 3261 utilise une adresse IPv6 nue. Des implémentations historiques avaient pourtant envoyé et accepté les deux formes.

La recommandation est précise : recevoir received avec ou sans crochets, mais émettre sans crochets. La tolérance se trouve à l’entrée ; la sortie reste canonique. Il s’agit d’une décision limitée à un champ et à une divergence connue.

Si cette règle devient « enlever tout crochet », elle détruit les URI. Si elle devient « rejeter tout ce qui n’est pas canonique », elle casse les pairs tolérés. Une mise en œuvre gouvernable doit journaliser l’exception invoquée, la valeur structurée produite et la sérialisation transmise.

Le contexte décide de la ponctuation

Une adresse IPv6 dans une URI SIP exige des crochets. Une adresse de connexion dans le corps SDP n’en utilise pas. RFC 5118 combine aussi IPv4 et IPv6 dans plusieurs champs Via, place des familles différentes sur des lignes média distinctes et teste les adresses IPv4 représentées dans l’espace IPv6.

Un service de nettoyage qui juge les chaînes par leur apparence peut donc rendre invalides des messages corrects. La règle appartient à la production grammaticale : en-tête, URI, paramètre Via ou corps SDP. La normalisation centrale n’a d’autorité que si elle conserve ce contexte.

Le document expose même une voie ABNF susceptible d’accepter un deux-points supplémentaire devant une partie IPv4 incorporée. Un récepteur peut être robuste et l’accepter ; s’il retransmet, il devrait supprimer ce caractère. L’acceptation de l’entrée et la qualité de la sortie sont encore deux reçus.

Le test ne termine pas l’appel

Après le parseur, un proxy choisit une prochaine étape. Une transaction SIP reçoit ou non une réponse. Un dialogue peut s’établir. Le SDP peut désigner des adresses média joignables. Les paquets média peuvent circuler sans que l’expérience utilisateur soit correcte.

La réussite d’un test de syntaxe ne prouve aucune de ces étapes. Inversement, un appel réussi peut masquer un parseur divergent : un contact alternatif, une normalisation en amont ou une politique de secours a pu sauver le chemin. Lorsque la topologie change, la divergence réapparaît.

Il faut donc une échelle : octets exacts, règle grammaticale, arbre produit, intention déclarée, message transmis, prochaine étape, transaction, dialogue, média, résultat visible. Chaque niveau répond à une question différente.

Une cartographie des coutures

Le meilleur usage de RFC 5118 n’est pas de vendre une conformité. C’est d’identifier les coutures : page et fil, hôte et port, syntaxe et intention, réception tolérante et émission canonique, signalisation et corps, parseur et application.

Ces coutures sont aussi des frontières de responsabilité. Le fournisseur du parseur peut prouver son arbre. L’opérateur doit prouver sa politique de routage. L’application doit prouver son état. Le média doit être observé séparément. Le corpus commun reste minimal ; les décisions futures restent locales et explicites.

Sources