6. STUN Message Structure (Structure des messages STUN)
Les messages STUN sont encodés en binaire en utilisant un format orienté réseau (octet ou byte le plus significatif en premier, également communément appelé big-endian). L'ordre de transmission est décrit en détail dans l'annexe B du RFC 791 [RFC0791]. Sauf indication contraire, les constantes numériques sont en décimal (base 10).
Tous les messages STUN doivent (MUST) commencer par un en-tête de 20 octets suivi de zéro ou plusieurs attributs (Attributes). L'en-tête STUN contient un type de message STUN, un cookie magique (magic cookie), un ID de transaction (transaction ID) et la longueur du message.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0| STUN Message Type | Message Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic Cookie |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Transaction ID (96 bits) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 2 : Format de l'en-tête de message STUN
Les 2 bits les plus significatifs de chaque message STUN doivent (MUST) être des zéros. Ceci peut être utilisé pour différencier les paquets STUN des autres protocoles lorsque STUN est multiplexé avec d'autres protocoles sur le même port.
Le type de message définit la classe de message (request, success response, failure response ou indication) et la méthode de message (message method) (fonction principale) du message STUN. Bien qu'il existe quatre classes de messages, il n'existe que deux types de transactions dans STUN : les transactions requête/réponse (request/response transactions) (qui consistent en un message de requête et un message de réponse) et les transactions d'indication (indication transactions) (qui consistent en un seul message d'indication). Les classes de réponse sont divisées en réponses d'erreur et réponses de succès pour faciliter le traitement rapide du message STUN.
Le champ de type de message est subdivisé dans la structure suivante :
0 1
2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 3 : Format du champ de type de message STUN
Ici, les bits dans le champ de type de message sont affichés du plus significatif (M11) au moins significatif (M0). M11 à M0 représentent un encodage sur 12 bits de la méthode. C1 et C0 représentent un encodage sur 2 bits de la classe. Une classe de 0b00 est une requête (request), une classe de 0b01 est une indication, une classe de 0b10 est une réponse de succès (success response) et une classe de 0b11 est une réponse d'erreur (error response). Cette spécification définit une seule méthode, Binding. La méthode et la classe sont orthogonales, de sorte que pour chaque méthode, une requête, une réponse de succès, une réponse d'erreur et une indication sont possibles pour cette méthode. Les extensions définissant de nouvelles méthodes doivent (MUST) indiquer quelles classes sont autorisées pour cette méthode.
Par exemple, une requête de liaison (Binding request) a class=0b00 (request) et method=0b000000000001 (Binding) et est encodée dans les 16 premiers bits comme 0x0001. Une réponse de liaison (Binding response) a class=0b10 (success response) et method=0b000000000001, et est encodée dans les 16 premiers bits comme 0x0101.
Le champ de cookie magique doit (MUST) contenir la valeur fixe 0x2112A442 dans l'ordre des octets du réseau. Dans RFC 3489 [RFC3489], ce champ faisait partie de l'ID de transaction ; placer le cookie magique à cet emplacement permet à un serveur de détecter si le client comprendra certains attributs qui ont été ajoutés dans cette spécification révisée. De plus, il aide à distinguer les paquets STUN des paquets d'autres protocoles lorsque STUN est multiplexé avec ces autres protocoles sur le même port.
L'ID de transaction (transaction ID) est un identifiant de 96 bits, utilisé pour identifier de manière unique les transactions STUN. Pour les transactions requête/réponse, l'ID de transaction est choisi par le client STUN pour la requête et renvoyé en écho par le serveur dans la réponse. Pour les indications, il est choisi par l'agent envoyant l'indication. Il sert principalement à corréler les requêtes avec les réponses, bien qu'il joue également un petit rôle dans la prévention de certains types d'attaques. Le serveur utilise également l'ID de transaction comme clé pour identifier chaque transaction de manière unique parmi tous les clients. En tant que tel, l'ID de transaction doit (MUST) être choisi de manière uniforme et aléatoire dans l'intervalle 0 .. 2**96-1, et devrait (SHOULD) être cryptographiquement aléatoire. Les retransmissions de la même requête réutilisent le même ID de transaction, mais le client doit (MUST) choisir un nouvel ID de transaction pour les nouvelles transactions, sauf si la nouvelle requête est identique bit à bit à la requête précédente et envoyée depuis la même adresse de transport vers la même adresse IP. Les réponses de succès et d'erreur doivent (MUST) porter le même ID de transaction que leur requête correspondante. Lorsqu'un agent agit en tant que serveur STUN et client STUN sur le même port, l'ID de transaction dans les requêtes que l'agent envoie n'a aucun rapport avec l'ID de transaction dans les requêtes qu'il reçoit.
La longueur du message (message length) doit (MUST) contenir la taille, en octets, du message sans inclure l'en-tête STUN de 20 octets. Étant donné que tous les attributs STUN sont complétés à un multiple de 4 octets, les 2 derniers bits de ce champ sont toujours zéro. Cela fournit un autre moyen de distinguer les paquets STUN des paquets d'autres protocoles.
Après l'en-tête fixe STUN suivent zéro ou plusieurs attributs. Chaque attribut est encodé en TLV (Type-Longueur-Valeur). Les détails de l'encodage et les attributs eux-mêmes sont donnés dans la Section 15.