8. SSRC Identifier Allocation and Use (Allocation et utilisation de l'identificateur SSRC)
L'identificateur SSRC porté dans l'en-tête RTP et dans divers champs des paquets RTCP est un nombre aléatoire de 32 bits qui doit être globalement unique au sein d'une session RTP. Il est crucial que le nombre soit choisi avec soin afin que les participants sur le même réseau ou démarrant au même moment n'aient pas de forte probabilité de choisir le même nombre.
Il n'est pas suffisant d'utiliser l'adresse réseau locale (telle qu'une adresse IPv4) comme identificateur car l'adresse peut ne pas être unique. Puisque les traducteurs et mélangeurs RTP permettent l'interopérabilité entre de multiples réseaux avec des espaces d'adressage différents, les motifs d'allocation pour les adresses au sein de deux espaces pourraient résulter en un taux de collision beaucoup plus élevé que ne le produirait une allocation aléatoire.
Plusieurs sources s'exécutant sur un même hôte entreraient aussi en conflit.
Il n'est pas non plus suffisant d'obtenir un identificateur SSRC simplement en appelant random() sans initialiser soigneusement l'état. Un exemple de comment générer un identificateur aléatoire est présenté à l'appendice A.6.
8.1 Probability of Collision (Probabilité de collision)
Puisque les identificateurs sont choisis aléatoirement, il est possible que deux sources ou plus choisissent le même nombre. Une collision survient avec la probabilité la plus élevée lorsque toutes les sources sont démarrées simultanément, par exemple quand elles sont déclenchées automatiquement par un événement de gestion de session. Si N est le nombre de sources et L la longueur de l'identificateur (ici, 32 bits), la probabilité que deux sources choisissent indépendamment la même valeur peut être approximée pour un N grand [26] par 1 - exp(-N2 / 2(L+1)). Pour N=1000, la probabilité est à peu près de 10**-4.
La probabilité de collision typique est beaucoup plus faible que le pire cas ci-dessus. Quand une nouvelle source rejoint une session RTP dans laquelle toutes les autres sources ont déjà des identificateurs uniques, la probabilité de collision n'est que la fraction des nombres utilisés dans l'espace. Encore une fois, si N est le nombre de sources et L la longueur de l'identificateur, la probabilité de collision est N / 2L. Pour N=1000, la probabilité est à peu près de 2*10-7.
La probabilité de collision est en outre réduite par la possibilité pour une nouvelle source de recevoir des paquets d'autres participants avant d'envoyer son premier paquet (de données ou de contrôle). Si la nouvelle source garde la trace des autres participants (par identificateur SSRC), alors avant de transmettre son premier paquet, la nouvelle source peut vérifier que son identificateur n'entre pas en conflit avec ceux qui ont été reçus, sinon en choisir un autre.
8.2 Collision Resolution and Loop Detection (Résolution de collision et détection de boucle)
Bien que la probabilité de collision d'identificateur SSRC soit faible, toutes les implémentations RTP DOIVENT être prêtes à détecter les collisions et prendre les mesures appropriées pour les résoudre. Si une source découvre à tout moment qu'une autre source utilise le même identificateur SSRC que le sien, elle DOIT envoyer un paquet RTCP BYE pour l'ancien identificateur et en choisir un autre aléatoirement. (Comme expliqué ci-dessous, cette étape n'est prise qu'une seule fois en cas de boucle.) Si un récepteur découvre que deux autres sources entrent en collision, il PEUT garder les paquets de l'une et écarter les paquets de l'autre quand cela peut être détecté par des adresses de transport de source différentes ou des CNAME. Les deux sources sont censées résoudre la collision afin que la situation ne dure pas.
Parce que les identificateurs SSRC aléatoires sont maintenus globalement uniques pour chaque session RTP, ils peuvent aussi être utilisés pour détecter les boucles qui pourraient être introduites par des mélangeurs ou des traducteurs. Une boucle cause la duplication des données et de l'information de contrôle, soit non modifiée soit éventuellement mélangée, comme dans les exemples suivants :
-
Un traducteur peut transférer incorrectement un paquet vers le même groupe multicast à partir duquel il a reçu le paquet, soit directement soit à travers une chaîne de traducteurs. Dans ce cas, le même paquet apparaît plusieurs fois, provenant de différentes sources réseau.
-
Deux traducteurs configurés incorrectement en parallèle, c'est-à-dire avec les mêmes groupes multicast des deux côtés, transféreraient tous deux les paquets d'un groupe multicast vers l'autre. Des traducteurs unidirectionnels produiraient deux copies ; des traducteurs bidirectionnels formeraient une boucle.
-
Un mélangeur peut fermer une boucle en envoyant vers la même destination de transport sur laquelle il reçoit des paquets, soit directement soit à travers un autre mélangeur ou traducteur. Dans ce cas, une source pourrait apparaître à la fois comme un SSRC sur un paquet de données et comme un CSRC dans un paquet de données mélangé.
Une source peut découvrir que ses propres paquets sont bouclés, ou que des paquets d'une autre source sont bouclés (une boucle tierce). Tant les boucles que les collisions dans le choix aléatoire d'un identificateur de source entraînent des paquets arrivant avec le même identificateur SSRC mais une adresse de transport de source différente, qui peut être celle du système terminal à l'origine du paquet ou d'un système intermédiaire.
Par conséquent, si une source change son adresse de transport de source, elle PEUT aussi choisir un nouvel identificateur SSRC pour éviter d'être interprétée comme une source bouclée. (Ce n'est pas un MUST car dans certaines applications de RTP on peut s'attendre à ce que des sources changent d'adresses au cours d'une session.) Notez que si un traducteur redémarre et change par conséquent l'adresse de transport de source (par exemple change le numéro de port source UDP) sur laquelle il transfère les paquets, alors tous ces paquets apparaîtront aux récepteurs comme bouclés car les identificateurs SSRC sont appliqués par la source originale et ne changeront pas. Ce problème peut être évité en gardant l'adresse de transport de source fixe à travers les redémarrages, mais dans tous les cas il sera résolu après un délai d'expiration aux récepteurs.
Les boucles ou collisions sur le côté éloigné d'un traducteur ou d'un mélangeur ne peuvent pas être détectées en utilisant l'adresse de transport de source si toutes les copies des paquets passent par le traducteur ou le mélangeur ; toutefois, les collisions peuvent encore être détectées quand des morceaux de deux paquets RTCP SDES contiennent le même identificateur SSRC mais des CNAME différents.
Pour détecter et résoudre ces conflits, une implémentation RTP DOIT inclure un algorithme similaire à celui décrit ci-dessous, bien que l'implémentation PEUVE choisir une politique différente quant aux paquets des sources tierces entrant en collision qui sont conservés. L'algorithme décrit ci-dessous ignore les paquets d'une nouvelle source ou d'une boucle qui entrent en collision avec une source établie. Il résout les collisions avec le propre identificateur SSRC du participant en envoyant un RTCP BYE pour l'ancien identificateur et en en choisissant un nouveau. Toutefois, quand la collision a été induite par une boucle des propres paquets du participant, l'algorithme choisira un nouvel identificateur une seule fois puis ignorera par la suite les paquets de l'adresse de transport de source bouclée. Cela est requis pour éviter une inondation de paquets BYE.
Cet algorithme requiert la tenue d'une table indexée par l'identificateur de source et contenant les adresses de transport de source du premier paquet RTP et du premier paquet RTCP reçus avec cet identificateur, ainsi que d'autres états pour cette source. Deux adresses de transport de source sont requises car, par exemple, les numéros de port source UDP peuvent être différents sur les paquets RTP et RTCP. Toutefois, on peut supposer que l'adresse réseau est la même dans les deux adresses de transport de source.
Chaque identificateur SSRC ou CSRC reçu dans un paquet RTP ou RTCP est recherché dans la table des identificateurs de source afin de traiter ces données ou cette information de contrôle. L'adresse de transport de source du paquet est comparée à l'adresse de transport de source correspondante dans la table pour détecter une boucle ou une collision si elles ne correspondent pas. Pour les paquets de contrôle, chaque élément avec son propre identificateur SSRC, par exemple un morceau SDES, requiert une recherche séparée. (L'identificateur SSRC dans un bloc de rapport de réception est une exception parce qu'il identifie une source entendue par le rapporteur, et cet identificateur SSRC est sans rapport avec l'adresse de transport de source du paquet RTCP envoyé par le rapporteur.) Si le SSRC ou le CSRC n'est pas trouvé, une nouvelle entrée est créée. Ces entrées de table sont retirées quand un paquet RTCP BYE est reçu avec l'identificateur SSRC correspondant et validé par une adresse de transport de source correspondante, ou après qu'aucun paquet n'est arrivé depuis un temps relativement long (voir la section 6.2.1).
Notez que si deux sources sur le même hôte transmettent avec le même identificateur de source au moment où un récepteur commence à fonctionner, il serait possible que le premier paquet RTP reçu vienne de l'une des sources tandis que le premier paquet RTCP reçu vienne de l'autre. Cela causerait l'association de la mauvaise information RTCP avec les données RTP, mais cette situation devrait être suffisamment rare et inoffensive pour pouvoir être ignorée.
Afin de suivre les boucles des propres paquets de données du participant, l'implémentation DOIT aussi tenir une liste séparée des adresses de transport de source (et non des identificateurs) qui se sont révélées conflictuelles. Comme dans la table des identificateurs de source, deux adresses de transport de source DOIVENT être tenues pour suivre séparément les paquets RTP et RTCP conflictuels. Notez que la liste des adresses conflictuelles devrait être courte, habituellement vide. Chaque élément de cette liste stocke les adresses source plus le moment où le paquet conflictuel le plus récent a été reçu. Un élément PEUT être retiré de la liste quand aucun paquet conflictuel n'est arrivé de cette source depuis un temps de l'ordre de 10 intervalles de rapport RTCP (voir la section 6.2).
Pour l'algorithme tel que présenté, on suppose que le propre identificateur et état de source du participant sont inclus dans la table des identificateurs de source. L'algorithme pourrait être restructuré pour d'abord faire une comparaison séparée contre le propre identificateur de source du participant.
if (SSRC or CSRC identifier is not found in the source
identifier table) {
create a new entry storing the data or control source
transport address, the SSRC or CSRC and other state;
}
/* Identifier is found in the table */
else if (table entry was created on receipt of a control packet
and this is the first data packet or vice versa) {
store the source transport address from this packet;
}
else if (source transport address from the packet does not match
the one saved in the table entry for this identifier) {
/* An identifier collision or a loop is indicated */
if (source identifier is not the participant's own) {
/* OPTIONAL error counter step */
if (source identifier is from an RTCP SDES chunk
containing a CNAME item that differs from the CNAME
in the table entry) {
count a third-party collision;
} else {
count a third-party loop;
}
abort processing of data packet or control element;
/* MAY choose a different policy to keep new source */
}
/* A collision or loop of the participant's own packets */
else if (source transport address is found in the list of
conflicting data or control source transport
addresses) {
/* OPTIONAL error counter step */
if (source identifier is not from an RTCP SDES chunk
containing a CNAME item or CNAME is the
participant's own) {
count occurrence of own traffic looped;
}
mark current time in conflicting address list entry;
abort processing of data packet or control element;
}
/* New collision, change SSRC identifier */
else {
log occurrence of a collision;
create a new entry in the conflicting data or control
source transport address list and mark current time;
send an RTCP BYE packet with the old SSRC identifier;
choose a new SSRC identifier;
create a new entry in the source identifier table with
the old SSRC plus the source transport address from
the data or control packet being processed;
}
}
Dans cet algorithme, les paquets d'une nouvelle adresse source conflictuelle seront ignorés et les paquets de l'adresse source originale seront conservés. Si aucun paquet n'arrive de la source originale pendant une longue période, l'entrée de la table expirera et la nouvelle source pourra prendre la relève. Cela pourrait survenir si la source originale détecte la collision et passe à un nouvel identificateur de source, mais dans le cas habituel un paquet RTCP BYE sera reçu de la source originale pour supprimer l'état sans avoir à attendre une expiration.
Si l'adresse source originale a été reçue à travers un mélangeur (c'est-à-dire, apprise comme un CSRC) et que plus tard la même source est reçue directement, le récepteur a bien intérêt à basculer vers la nouvelle adresse source à moins que d'autres sources dans le mélange ne soient perdues. En outre, pour des applications telles que la téléphonie où certaines sources telles que des entités mobiles peuvent changer d'adresses au cours d'une session RTP, l'implémentation RTP DEVRAIT modifier l'algorithme de détection de collision pour accepter les paquets de la nouvelle adresse de transport de source. Pour se prémunir contre un va-et-vient entre adresses si une véritable collision survient, l'algorithme DEVRAIT inclure un moyen de détecter ce cas et d'éviter le basculement.
Quand un nouvel identificateur SSRC est choisi à cause d'une collision, le candidat identifiant DEVRAIT d'abord être recherché dans la table des identificateurs de source pour voir s'il était déjà utilisé par une autre source. Si c'est le cas, un autre candidat DOIT être généré et le processus répété.
Une boucle de paquets de données vers une destination multicast peut causer une grave inondation du réseau. Tous les mélangeurs et traducteurs DOIVENT implémenter un algorithme de détection de boucle comme celui-ci afin de pouvoir briser les boucles. Cela devrait limiter le trafic excessif à pas plus d'une copie dupliquée du trafic original, ce qui peut permettre à la session de continuer afin que la cause de la boucle puisse être trouvée et corrigée. Toutefois, dans des cas extrêmes où un mélangeur ou un traducteur ne brise pas correctement la boucle et que des niveaux de trafic élevés en résultent, il peut être nécessaire pour les systèmes terminaux de cesser totalement de transmettre des paquets de données ou de contrôle. Cette décision peut dépendre de l'application. Une condition d'erreur DEVRAIT être indiquée de manière appropriée. Une transmission PEUT être tentée à nouveau périodiquement après un temps long et aléatoire (de l'ordre de minutes).
8.3 Use with Layered Encodings (Utilisation avec les encodages en couches)
Pour les encodages en couches transmis sur des sessions RTP séparées (voir la section 2.4), un espace d'identificateur SSRC unique DEVRAIT être utilisé à travers les sessions de toutes les couches et la couche (de base) cœur DEVRAIT être utilisée pour l'allocation d'identificateur SSRC et la résolution de collision. Quand une source découvre qu'elle est entrée en collision, elle transmet un paquet RTCP BYE seulement sur la couche de base mais change l'identificateur SSRC à la nouvelle valeur dans toutes les couches.