Aller au contenu principal

11. Canaux (Channels)

Les canaux (Channels) offrent un moyen pour le client et le serveur d'envoyer des données d'application en utilisant des messages ChannelData, qui ont moins de surcharge que les indications Send et Data.

Le message ChannelData (voir Section 11.4) commence par un champ de deux octets qui porte le numéro de canal (Channel Number). Les valeurs de ce champ sont allouées comme suit :

  • 0x0000 à 0x3FFF : Ces valeurs ne peuvent jamais être utilisées pour les numéros de canal.

  • 0x4000 à 0x7FFF : Ce sont les numéros de canal autorisés (16 383 valeurs possibles).

  • 0x8000 à 0xFFFF : Ces valeurs sont réservées pour une utilisation future.

En raison de cette division, les messages ChannelData peuvent être distingués des messages au format STUN (par exemple, requête Allocate, indication Send, etc.) en examinant les deux premiers bits du message :

  • 0b00 : Message au format STUN (car les deux premiers bits d'un message au format STUN sont toujours zéro).

  • 0b01 : Message ChannelData (car le numéro de canal est le premier champ dans un message ChannelData et les numéros de canal sont dans la plage 0x4000 - 0x7FFF).

  • 0b10 : Réservé

  • 0b11 : Réservé

Les valeurs réservées peuvent être utilisées à l'avenir pour étendre la plage des numéros de canal. Ainsi, une implémentation NE DOIT PAS (MUST NOT) supposer qu'un message TURN commence toujours par un bit 0.

Les liaisons de canal (Channel Bindings) sont toujours initiées par le client. Le client peut lier un canal à un pair à tout moment pendant la durée de vie de l'allocation. Le client peut lier un canal à un pair avant d'échanger des données avec lui, ou après avoir échangé des données (en utilisant les indications Send et Data) pendant un certain temps, ou peut choisir de ne jamais lier de canal à celui-ci. Le client peut également lier des canaux à certains pairs tout en ne liant pas de canaux à d'autres pairs.

Les liaisons de canal sont spécifiques à une allocation, donc un numéro de canal ou une adresse de transport de pair utilisé dans la liaison de canal d'une allocation n'a aucun impact sur leur utilisation dans la liaison de canal d'une allocation différente. Si une allocation expire, toutes ses liaisons de canal expirent avec elle.

Une liaison de canal se compose de :

  • Un numéro de canal.

  • Une adresse de transport (du pair).

  • Un minuteur de temps d'expiration.

Dans le contexte d'une allocation, une liaison de canal est identifiée de manière unique soit par le numéro de canal, soit par l'adresse de transport du pair. Ainsi, le même canal ne peut pas être lié à deux adresses de transport différentes, et la même adresse de transport ne peut pas être liée à deux canaux différents.

Les liaisons de canal durent 10 minutes à moins d'être rafraîchies. Le rafraîchissement de la liaison (par le serveur recevant une requête ChannelBind reliant à nouveau le canal au même pair) réinitialise le minuteur de temps d'expiration à 10 minutes.

Lorsqu'une liaison de canal expire, le canal devient non lié. Une fois non lié, le numéro de canal peut être lié à une adresse de transport différente, et l'adresse de transport peut être liée à un numéro de canal différent. Pour éviter les conditions de course, le client DOIT (MUST) attendre 5 minutes après l'expiration d'une liaison de canal avant de tenter de lier le numéro de canal à une adresse de transport différente ou l'adresse de transport à un numéro de canal différent.

Lors de la liaison d'un canal à un pair, le client DEVRAIT (SHOULD) être prêt à recevoir des messages ChannelData sur le canal depuis le serveur dès qu'il a envoyé la requête ChannelBind. Sur UDP, le client PEUT (MAY) recevoir des messages ChannelData du serveur avant de recevoir la réponse de succès ChannelBind.

Dans l'autre direction, le client PEUT (MAY) choisir d'envoyer des messages ChannelData avant de recevoir la réponse de succès ChannelBind. Cependant, cela comporte le risque que les messages ChannelData soient abandonnés par le serveur si la requête ChannelBind n'aboutit pas pour une raison quelconque (par exemple, perte de paquet si la requête est envoyée sur UDP, ou le serveur étant incapable de satisfaire la requête). Un client qui souhaite être sûr devrait soit mettre les données en file d'attente, soit utiliser des indications Send jusqu'à ce que la liaison de canal soit confirmée.

11.1. Envoi d'une requête ChannelBind (Sending a ChannelBind Request)

Une transaction ChannelBind est utilisée pour créer ou rafraîchir une liaison de canal. Une transaction ChannelBind crée ou rafraîchit également la permission vers le pair (voir Section 8).

Pour initier la transaction ChannelBind, le client forme une requête ChannelBind. Le canal à lier est spécifié dans l'attribut CHANNEL-NUMBER, et l'adresse de transport du pair est spécifiée dans l'attribut XOR-PEER-ADDRESS. La Section 11.2 décrit les restrictions sur ces attributs.

Relier à nouveau un canal à la même adresse de transport à laquelle il est déjà lié fournit un moyen de rafraîchir la liaison de canal et la permission correspondante sans envoyer de données au pair. Notez cependant que les permissions doivent être rafraîchies plus fréquemment que les canaux.

11.2. Réception d'une requête ChannelBind (Receiving a ChannelBind Request)

Lorsque le serveur reçoit une requête ChannelBind, il la traite selon la Section 4 plus les règles spécifiques mentionnées ici.

Le serveur vérifie ce qui suit :

  • La requête contient à la fois un attribut CHANNEL-NUMBER et un attribut XOR-PEER-ADDRESS.

  • Le numéro de canal est dans la plage 0x4000 à 0x7FFE (inclus).

  • Le numéro de canal n'est pas actuellement lié à une adresse de transport différente (la même adresse de transport est acceptable).

  • L'adresse de transport n'est pas actuellement liée à un numéro de canal différent.

Si l'un de ces tests échoue, le serveur répond avec une erreur 400 (Bad Request).

Le serveur PEUT (MAY) imposer des restrictions sur les valeurs d'adresse IP et de port autorisées dans l'attribut XOR-PEER-ADDRESS -- si une valeur n'est pas autorisée, le serveur rejette la requête avec une erreur 403 (Forbidden).

Si la requête est valide, mais que le serveur est incapable de satisfaire la requête en raison d'une limite de capacité ou similaire, le serveur répond avec une erreur 508 (Insufficient Capacity).

Sinon, le serveur répond avec une réponse de succès ChannelBind. Il n'y a pas d'attributs requis dans une réponse de succès ChannelBind.

Si le serveur peut satisfaire la requête, alors le serveur crée ou rafraîchit la liaison de canal en utilisant le numéro de canal dans l'attribut CHANNEL-NUMBER et l'adresse de transport dans l'attribut XOR-PEER-ADDRESS. Le serveur installe ou rafraîchit également la permission pour l'adresse IP dans l'attribut XOR-PEER-ADDRESS comme décrit dans la Section 8.

NOTE : Le serveur n'a pas besoin de faire quelque chose de spécial pour implémenter l'idempotence des requêtes ChannelBind sur UDP en utilisant l'« approche de pile sans état ». Les requêtes ChannelBind retransmises rafraîchiront simplement la liaison de canal et la permission correspondante. De plus, le client doit attendre 5 minutes avant de lier un numéro de canal ou une adresse de pair précédemment lié à un canal différent, éliminant la possibilité que la transaction échoue initialement mais réussisse lors d'une retransmission.

11.3. Réception d'une réponse ChannelBind (Receiving a ChannelBind Response)

Lorsque le client reçoit une réponse de succès ChannelBind, il met à jour ses structures de données pour enregistrer que la liaison de canal est maintenant active. Il met également à jour ses structures de données pour enregistrer que la permission correspondante a été installée ou rafraîchie.

Si le client reçoit une réponse d'échec ChannelBind qui indique que les informations de canal sont désynchronisées entre le client et le serveur (par exemple, une réponse inattendue 400 « Bad Request »), alors il est RECOMMANDÉ (RECOMMENDED) que le client supprime immédiatement l'allocation et recommence avec une nouvelle allocation.

11.4. Le message ChannelData (The ChannelData Message)

Le message ChannelData est utilisé pour transporter des données d'application entre le client et le serveur. Il a le format suivant :

 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Channel Number | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
/ Application Data /
/ /
| |
| +-------------------------------+
| |
+-------------------------------+

Le champ Channel Number spécifie le numéro de canal sur lequel les données transitent, et donc l'adresse du pair qui envoie ou doit recevoir les données.

Le champ Length spécifie la longueur en octets du champ Application Data (c'est-à-dire qu'il n'inclut pas la taille de l'en-tête ChannelData). Notez que 0 est une longueur valide.

Le champ Application Data transporte les données que le client essaie d'envoyer au pair, ou que le pair envoie au client.

11.5. Envoi d'un message ChannelData (Sending a ChannelData Message)

Une fois qu'un client a lié un canal à un pair, alors lorsque le client a des données à envoyer à ce pair, il peut utiliser soit un message ChannelData, soit une indication Send ; c'est-à-dire que le client n'est pas obligé d'utiliser le canal lorsqu'il existe et est libre d'utiliser l'un ou l'autre type de message lors de l'envoi de données au pair. Le serveur, d'autre part, DOIT (MUST) utiliser le message ChannelData si un canal a été lié au pair.

Les champs du message ChannelData sont remplis comme décrit dans la Section 11.4.

Sur TCP et TLS-over-TCP, le message ChannelData DOIT (MUST) être complété à un multiple de quatre octets afin d'assurer l'alignement des messages suivants. Le remplissage n'est pas reflété dans le champ de longueur du message ChannelData, donc la taille réelle d'un message ChannelData (y compris le remplissage) est (4 + Length) arrondi au multiple de 4 le plus proche. Sur UDP, le remplissage n'est pas requis mais PEUT (MAY) être inclus.

Le message ChannelData est ensuite envoyé sur le 5-tuple associé à l'allocation.

11.6. Réception d'un message ChannelData (Receiving a ChannelData Message)

Le récepteur d'un message ChannelData utilise les deux premiers bits pour le distinguer d'un message au format STUN, comme décrit ci-dessus. Si le message utilise une valeur dans la plage réservée (0x8000 à 0xFFFF), alors le message est silencieusement abandonné.

Si le message ChannelData est reçu dans un datagramme UDP, et si le datagramme UDP est trop court pour contenir la longueur de données que le message ChannelData prétend transporter (c'est-à-dire que la valeur du champ de longueur de l'en-tête UDP est inférieure au champ de longueur de l'en-tête ChannelData + 4 + 8), alors le message est silencieusement abandonné.

Si le message ChannelData est reçu sur TCP ou TLS-over-TCP, alors la longueur réelle du message ChannelData est comme décrit dans la Section 11.5.

Si le message ChannelData est reçu sur un canal qui n'est lié à aucun pair, alors le message est silencieusement abandonné.

Sur le client, il est RECOMMANDÉ (RECOMMENDED) que le client abandonne le message ChannelData si le client pense qu'il n'y a pas de permission active vers le pair. Sur le serveur, la réception d'un message ChannelData NE DOIT PAS (MUST NOT) rafraîchir ni la liaison de canal ni la permission vers le pair.

Sur le serveur, si aucune erreur n'est détectée, le serveur relaie les données d'application au pair en formant un datagramme UDP comme suit :

  • L'adresse de transport source est l'adresse de transport relayée de l'allocation, où l'allocation est déterminée par le 5-tuple sur lequel le message ChannelData est arrivé.

  • L'adresse de transport de destination est l'adresse de transport à laquelle le canal est lié.

  • Les données suivant l'en-tête UDP sont le contenu du champ de données du message ChannelData.

Le datagramme UDP résultant est ensuite envoyé au pair. Notez que si le champ Length dans le message ChannelData est 0, alors il n'y aura pas de données dans le datagramme UDP, mais le datagramme UDP est quand même formé et envoyé.

11.7. Relais de données depuis le pair (Relaying Data from the Peer)

Lorsque le serveur reçoit un datagramme UDP sur l'adresse de transport relayée associée à une allocation, il le traite comme décrit dans la Section 10.3. Si cette section indique qu'un message ChannelData doit être envoyé (parce qu'il y a un canal lié au pair qui a envoyé le datagramme UDP), alors le serveur forme et envoie un message ChannelData comme décrit dans la Section 11.5.