2. Overview of ICE (Aperçu d'ICE)
Dans un déploiement ICE typique, nous avons deux points de terminaison (appelés AGENTS dans la terminologie RFC 3264) qui souhaitent communiquer. Ils sont capables de communiquer indirectement via un protocole de signalisation (tel que SIP), par lequel ils peuvent effectuer un échange offre/réponse de messages SDP [RFC3264]. Notez qu'ICE n'est pas destiné à la traversée de NAT pour SIP, qui est supposée être fournie via un autre mécanisme [RFC5626]. Au début du processus ICE, les agents ignorent leurs propres topologies. En particulier, ils peuvent ou non être derrière un NAT (ou plusieurs niveaux de NAT). ICE permet aux agents de découvrir suffisamment d'informations sur leurs topologies pour trouver potentiellement un ou plusieurs chemins par lesquels ils peuvent communiquer.
La figure 1 montre un environnement typique pour le déploiement d'ICE. Les deux points de terminaison sont étiquetés L et R (pour gauche et droite, ce qui aide à visualiser les flux d'appels). L et R sont tous deux derrière leurs NAT respectifs, bien qu'ils puissent ne pas en être conscients. Le type de NAT et ses propriétés sont également inconnus. Les agents L et R sont capables de s'engager dans un échange offre/réponse par lequel ils peuvent échanger des messages SDP, dont le but est d'établir une session multimédia entre L et R. Typiquement, cet échange se produira via un serveur SIP.
En plus des agents, d'un serveur SIP et des NAT, ICE est généralement utilisé de concert avec des serveurs STUN ou TURN dans le réseau. Chaque agent peut avoir son propre serveur STUN ou TURN, ou ils peuvent être les mêmes.
+-------+
| SIP |
+-------+ | Srvr | +-------+
| STUN | | | | STUN |
| Srvr | +-------+ | Srvr |
| | / \ | |
+-------+ / \ +-------+
/ \
/ \
/ \
/ \
/ <- Signaling -> \
/ \
/ \
+--------+ +--------+
| NAT | | NAT |
+--------+ +--------+
/ \
/ \
/ \
+-------+ +-------+
| Agent | | Agent |
| L | | R |
| | | |
+-------+ +-------+
Figure 1: ICE Deployment Scenario
L'idée de base derrière ICE est la suivante : chaque agent dispose d'une variété de candidats TRANSPORT ADDRESSES (adresses de transport) (combinaison d'adresse IP et de port pour un protocole de transport particulier, qui est toujours UDP dans cette spécification) qu'il pourrait utiliser pour communiquer avec l'autre agent. Ceux-ci pourraient inclure :
- Une adresse de transport sur une interface réseau directement connectée
- Une adresse de transport traduite du côté public d'un NAT (une adresse "server reflexive" (réflexive serveur))
- Une adresse de transport allouée à partir d'un serveur TURN (une adresse "relayed" (relayée)).
Potentiellement, n'importe laquelle des adresses de transport candidates de L peut être utilisée pour communiquer avec n'importe laquelle des adresses de transport candidates de R. En pratique, cependant, de nombreuses combinaisons ne fonctionneront pas. Par exemple, si L et R sont tous deux derrière des NAT, leurs adresses d'interface directement connectées ont peu de chances de pouvoir communiquer directement (c'est pourquoi ICE est nécessaire, après tout !). Le but d'ICE est de découvrir quelles paires d'adresses fonctionneront. La manière dont ICE fait cela est d'essayer systématiquement toutes les paires possibles (dans un ordre soigneusement trié) jusqu'à ce qu'il en trouve une ou plusieurs qui fonctionnent.
2.1. Gathering Candidate Addresses (Collecte des adresses candidates)
Afin d'exécuter ICE, un agent doit identifier tous ses candidats d'adresse. Un CANDIDATE (candidat) est une adresse de transport -- une combinaison d'adresse IP et de port pour un protocole de transport particulier (avec seulement UDP spécifié ici). Ce document définit trois types de candidats, certains dérivés d'interfaces réseau physiques ou logiques, d'autres découvrables via STUN et TURN. Naturellement, un candidat viable est une adresse de transport obtenue directement à partir d'une interface locale. Un tel candidat est appelé un HOST CANDIDATE (candidat hôte). L'interface locale pourrait être Ethernet ou WiFi, ou elle pourrait être obtenue via un mécanisme de tunnel, tel qu'un réseau privé virtuel (VPN) ou Mobile IP (MIP). Dans tous les cas, une telle interface réseau apparaît à l'agent comme une interface locale à partir de laquelle des ports (et donc des candidats) peuvent être alloués.
Si un agent est multi-hébergé (multihomed), il obtient un candidat à partir de chaque adresse IP. Selon l'emplacement du PEER (pair) (l'autre agent dans la session) sur le réseau IP par rapport à l'agent, l'agent peut être accessible par le pair via une ou plusieurs de ces adresses IP. Considérons, par exemple, un agent qui a une adresse IP locale sur un réseau privé net 10 (I1), et une seconde connectée à l'Internet public (I2). Un candidat de I1 sera directement accessible lors de la communication avec un pair sur le même réseau privé net 10, tandis qu'un candidat de I2 sera directement accessible lors de la communication avec un pair sur l'Internet public. Plutôt que d'essayer de deviner quelle adresse IP fonctionnera avant d'envoyer une offre, l'agent offrant inclut les deux candidats dans son offre.
Ensuite, l'agent utilise STUN ou TURN pour obtenir des candidats supplémentaires. Ceux-ci se présentent sous deux formes : des adresses traduites du côté public d'un NAT (SERVER REFLEXIVE CANDIDATES (candidats réflexifs serveur)) et des adresses sur des serveurs TURN (RELAYED CANDIDATES (candidats relayés)). Lorsque des serveurs TURN sont utilisés, les deux types de candidats sont obtenus à partir du serveur TURN. Si seuls des serveurs STUN sont utilisés, seuls des candidats réflexifs serveur sont obtenus à partir d'eux. La relation de ces candidats avec le candidat hôte est illustrée à la figure 2. Dans cette figure, les deux types de candidats sont découverts à l'aide de TURN. Dans la figure, la notation X:x signifie l'adresse IP X et le port UDP x.
To Internet
|
|
| /------------ Relayed
Y:y | / Address
+--------+
| |
| TURN |
| Server |
| |
+--------+
|
|
| /------------ Server
X1':x1'|/ Reflexive
+------------+ Address
| NAT |
+------------+
|
| /------------ Local
X:x |/ Address
+--------+
| |
| Agent |
| |
+--------+
Figure 2: Candidate Relationships
Lorsque l'agent envoie la requête TURN Allocate depuis l'adresse IP et le port X:x, le NAT (en supposant qu'il y en ait un) créera une liaison X1':x1', mappant ce candidat réflexif serveur au candidat hôte X:x. Les paquets sortants envoyés depuis le candidat hôte seront traduits par le NAT vers le candidat réflexif serveur. Les paquets entrants envoyés au candidat réflexif serveur seront traduits par le NAT vers le candidat hôte et transmis à l'agent. Nous appelons le candidat hôte associé à un candidat réflexif serveur donné la BASE (base).
Note : "Base" fait référence à l'adresse à partir de laquelle un agent envoie pour un candidat particulier. Ainsi, comme cas dégénéré, les candidats hôtes ont également une base, mais c'est la même que le candidat hôte.
Lorsqu'il y a plusieurs NAT entre l'agent et le serveur TURN, la requête TURN créera une liaison sur chaque NAT, mais seul le candidat réflexif serveur le plus externe (celui le plus proche du serveur TURN) sera découvert par l'agent. Si l'agent n'est pas derrière un NAT, alors le candidat de base sera le même que le candidat réflexif serveur et le candidat réflexif serveur est redondant et sera éliminé.
La requête Allocate arrive ensuite au serveur TURN. Le serveur TURN alloue un port y à partir de son adresse IP locale Y, et génère une réponse Allocate, informant l'agent de ce candidat relayé. Le serveur TURN informe également l'agent du candidat réflexif serveur, X1':x1' en copiant l'adresse de transport source de la requête Allocate dans la réponse Allocate. Le serveur TURN agit comme un relais de paquets, transmettant le trafic entre L et R. Afin d'envoyer du trafic à L, R envoie du trafic au serveur TURN à Y:y, et le serveur TURN transmet cela à X1':x1', qui passe à travers le NAT où il est mappé à X:x et livré à L.
Lorsque seuls des serveurs STUN sont utilisés, l'agent envoie une requête STUN Binding [RFC5389] à son serveur STUN. Le serveur STUN informera l'agent du candidat réflexif serveur X1':x1' en copiant l'adresse de transport source de la requête Binding dans la réponse Binding.
2.2. Connectivity Checks (Vérifications de connectivité)
Une fois que L a rassemblé tous ses candidats, il les ordonne de la priorité la plus élevée à la plus basse et les envoie à R via le canal de signalisation. Les candidats sont transportés dans des attributs de l'offre SDP. Lorsque R reçoit l'offre, il effectue le même processus de collecte et répond avec sa propre liste de candidats. À la fin de ce processus, chaque agent dispose d'une liste complète de ses candidats et des candidats de son pair. Il les apparie, ce qui donne des CANDIDATE PAIRS (paires de candidats). Pour voir quelles paires fonctionnent, chaque agent planifie une série de CHECKS (vérifications). Chaque vérification est une transaction requête/réponse STUN que le client effectuera sur une paire de candidats particulière en envoyant une requête STUN du candidat local au candidat distant.
Le principe de base des vérifications de connectivité est simple :
- Trier les paires de candidats par ordre de priorité.
- Envoyer des vérifications sur chaque paire de candidats par ordre de priorité.
- Acquitter les vérifications reçues de l'autre agent.
Avec les deux agents effectuant une vérification sur une paire de candidats, le résultat est une poignée de main à 4 voies :
L R
- -
STUN request -> \ L's
<- STUN response / check
<- STUN request \ R's
STUN response -> / check
Figure 3: Basic Connectivity Check
Il est important de noter que les requêtes STUN sont envoyées vers et depuis exactement les mêmes adresses IP et ports qui seront utilisés pour les médias (par exemple, RTP et RTCP). Par conséquent, les agents démultiplexent STUN et RTP/RTCP en utilisant le contenu des paquets, plutôt que le port sur lequel ils sont reçus. Heureusement, ce démultiplexage est facile à faire, en particulier pour RTP et RTCP.
Parce qu'une requête STUN Binding est utilisée pour la vérification de connectivité, la réponse STUN Binding contiendra l'adresse de transport traduite de l'agent du côté public de tout NAT entre l'agent et son pair. Si cette adresse de transport est différente des autres candidats que l'agent a déjà appris, elle représente un nouveau candidat, appelé un PEER REFLEXIVE CANDIDATE (candidat réflexif pair), qui est ensuite testé par ICE tout comme n'importe quel autre candidat.
À titre d'optimisation, dès que R reçoit le message de vérification de L, R planifie un message de vérification de connectivité à envoyer à L sur la même paire de candidats. Cela accélère le processus de recherche d'un candidat valide, et est appelé un TRIGGERED CHECK (vérification déclenchée).
À la fin de cette poignée de main, L et R savent tous deux qu'ils peuvent envoyer (et recevoir) des messages de bout en bout dans les deux sens.
2.3. Sorting Candidates (Tri des candidats)
Parce que l'algorithme ci-dessus recherche toutes les paires de candidats, s'il existe une paire fonctionnelle, il finira par la trouver quel que soit l'ordre dans lequel les candidats sont essayés. Afin de produire des résultats plus rapides (et meilleurs), les candidats sont triés dans un ordre spécifié. La liste résultante de paires de candidats triées est appelée la CHECK LIST (liste de vérification). L'algorithme est décrit dans la section 4.1.2 mais suit deux principes généraux :
- Chaque agent donne à ses candidats une priorité numérique, qui est envoyée avec le candidat au pair.
- Les priorités locales et distantes sont combinées de sorte que chaque agent ait le même ordre pour les paires de candidats.
La deuxième propriété est importante pour faire fonctionner ICE lorsqu'il y a des NAT devant L et R. Fréquemment, les NAT ne permettront pas aux paquets d'entrer depuis un hôte tant que l'agent derrière le NAT n'a pas envoyé un paquet vers cet hôte. Par conséquent, les vérifications ICE dans chaque direction ne réussiront pas tant que les deux côtés n'auront pas envoyé une vérification à travers leurs NAT respectifs.
L'agent travaille à travers cette liste de vérification en envoyant périodiquement une requête STUN pour la paire de candidats suivante sur la liste. Celles-ci sont appelées ORDINARY CHECKS (vérifications ordinaires).
En général, l'algorithme de priorité est conçu de sorte que les candidats de type similaire obtiennent des priorités similaires et que les routes plus directes (c'est-à-dire, à travers moins de relais médias et à travers moins de NAT) soient préférées aux routes indirectes (celles avec plus de relais médias et plus de NAT). Dans le cadre de ces directives, cependant, les agents ont une certaine latitude quant à la manière d'ajuster leurs algorithmes.
2.4. Frozen Candidates (Candidats gelés)
La description précédente ne traite que le cas où les agents souhaitent établir une session multimédia avec un COMPONENT (composant) (un morceau d'un flux multimédia nécessitant une seule adresse de transport ; un flux multimédia peut nécessiter plusieurs composants, chacun devant fonctionner pour que le flux multimédia dans son ensemble fonctionne). Typiquement (par exemple, avec RTP et RTCP), les agents doivent en fait établir la connectivité pour plus d'un flux.
Les propriétés du réseau sont susceptibles d'être très similaires pour chaque composant (surtout parce que RTP et RTCP sont envoyés et reçus depuis la même adresse IP). Il est généralement possible de tirer parti des informations d'un composant multimédia afin de déterminer les meilleurs candidats pour un autre. ICE fait cela avec un mécanisme appelé "frozen candidates" (candidats gelés).
Chaque candidat est associé à une propriété appelée sa FOUNDATION (fondation). Deux candidats ont la même fondation lorsqu'ils sont "similaires" -- du même type et obtenus à partir du même candidat hôte et serveur STUN utilisant le même protocole. Sinon, leur fondation est différente. Une paire de candidats a aussi une fondation, qui est simplement la concaténation des fondations de ses deux candidats. Initialement, seules les paires de candidats avec des fondations uniques sont testées. Les autres paires de candidats sont marquées "frozen" (gelées). Lorsque les vérifications de connectivité pour une paire de candidats réussissent, les autres paires de candidats avec la même fondation sont dégelées. Cela évite la vérification répétée de composants qui sont superficiellement plus attrayants mais qui sont en fait susceptibles d'échouer.
Bien que nous ayons décrit "gelé" ici comme un mécanisme séparé à des fins d'exposé, il s'agit en fait d'une partie intégrante d'ICE et l'algorithme de priorisation d'ICE garantit automatiquement que les bons candidats sont dégelés et vérifiés dans le bon ordre.
2.5. Security for Checks (Sécurité des vérifications)
Parce qu'ICE est utilisé pour découvrir quelles adresses peuvent être utilisées pour envoyer des médias entre deux agents, il est important de s'assurer que le processus ne peut pas être détourné pour envoyer des médias au mauvais endroit. Chaque vérification de connectivité STUN est couverte par un code d'authentification de message (MAC) calculé à l'aide d'une clé échangée dans le canal de signalisation. Ce MAC fournit l'intégrité du message et l'authentification de l'origine des données, empêchant ainsi un attaquant de forger ou de modifier des messages de vérification de connectivité. De plus, si l'appelant SIP [RFC3261] utilise ICE, et que son appel bifurque (forks), les échanges ICE se produisent indépendamment avec chaque destinataire bifurqué. Dans un tel cas, les clés échangées dans la signalisation aident à associer chaque échange ICE à chaque destinataire bifurqué.
2.6. Concluding ICE (Conclusion d'ICE)
Les vérifications ICE sont effectuées dans une séquence spécifique, de sorte que les paires de candidats de haute priorité sont vérifiées en premier, suivies par celles de priorité inférieure. Une façon de conclure ICE est de déclarer victoire dès qu'une vérification pour chaque composant de chaque flux multimédia se termine avec succès. En effet, c'est un algorithme raisonnable, et des détails à ce sujet sont fournis ci-dessous. Cependant, il est possible qu'une perte de paquet entraîne une vérification de priorité plus élevée à prendre plus de temps pour se terminer. Dans ce cas, permettre à ICE de s'exécuter un peu plus longtemps pourrait produire de meilleurs résultats. Plus fondamentalement, cependant, la priorisation définie par cette spécification peut ne pas donner des résultats "optimaux". À titre d'exemple, si le but est de sélectionner des chemins multimédias à faible latence, l'utilisation d'un relais est un indice que les latences peuvent être plus élevées, mais ce n'est rien de plus qu'un indice. Une mesure réelle du temps aller-retour (RTT) pourrait être effectuée, et elle pourrait démontrer qu'une paire avec une priorité plus faible est en fait meilleure qu'une paire avec une priorité plus élevée.
Par conséquent, ICE attribue à l'un des agents le rôle d'AGENT CONTRÔLEUR (CONTROLLING AGENT), et à l'autre le rôle d'AGENT CONTRÔLÉ (CONTROLLED AGENT). L'agent contrôleur peut nommer quelles paires de candidats seront utilisées pour les médias parmi celles qui sont valides. Il peut le faire de l'une des deux manières suivantes -- en utilisant la NOMINATION RÉGULIÈRE (REGULAR NOMINATION) ou la NOMINATION AGRESSIVE (AGGRESSIVE NOMINATION).
Avec la nomination régulière, l'agent contrôleur laisse les vérifications continuer jusqu'à ce qu'au moins une paire de candidats valide pour chaque flux multimédia soit trouvée. Ensuite, il choisit parmi celles qui sont valides, et envoie une deuxième requête STUN sur sa paire de candidats NOMMÉE (NOMINATED), mais cette fois avec un indicateur (flag) défini pour dire au pair que cette paire a été nommée pour utilisation. Ceci est illustré à la figure 4.
L R
- -
STUN request -> \ L's
<- STUN response / check
<- STUN request \ R's
STUN response -> / check
STUN request + flag -> \ L's
<- STUN response / check
Figure 4: Regular Nomination
Une fois que la transaction STUN avec l'indicateur est terminée, les deux côtés annulent toutes les vérifications futures pour ce flux multimédia. ICE va maintenant envoyer des médias en utilisant cette paire. La paire qu'un agent ICE utilise pour les médias est appelée la PAIRE SÉLECTIONNÉE (SELECTED PAIR).
Dans la nomination agressive, l'agent contrôleur met l'indicateur dans chaque requête STUN qu'il envoie. De cette façon, une fois que la première vérification réussit, le traitement ICE est terminé pour ce flux multimédia et l'agent contrôleur n'a pas à envoyer une deuxième requête STUN. La paire sélectionnée sera la paire valide de priorité la plus élevée dont la vérification a réussi. La nomination agressive est plus rapide que la nomination régulière, mais donne moins de flexibilité. La nomination agressive est illustrée à la figure 5.
L R
- -
STUN request + flag -> \ L's
<- STUN response / check
<- STUN request \ R's
STUN response -> / check
Figure 5: Aggressive Nomination
Une fois que tous les flux multimédias sont terminés, le point de terminaison contrôleur envoie une offre mise à jour si les candidats dans les lignes m et c pour le flux multimédia (appelés CANDIDATS PAR DÉFAUT (DEFAULT CANDIDATES)) ne correspondent pas aux CANDIDATS SÉLECTIONNÉS (SELECTED CANDIDATES) par ICE.
Une fois ICE conclu, il peut être redémarré à tout moment pour un ou tous les flux multimédias par l'un ou l'autre des agents. Cela se fait en envoyant une offre mise à jour indiquant un redémarrage.
2.7. Lite Implementations (Implémentations légères)
Pour qu'ICE soit utilisé dans un appel, les deux agents doivent le supporter. Cependant, certains agents seront toujours connectés à l'Internet public et auront une adresse IP publique à laquelle ils peuvent recevoir des paquets de n'importe quel correspondant. Pour faciliter la prise en charge d'ICE par ces appareils, ICE définit un type spécial d'implémentation appelé LITE (légère) (par opposition à l'implémentation FULL (complète) normale). Une implémentation légère ne rassemble pas de candidats ; elle inclut uniquement des candidats hôtes pour tout flux multimédia. Les agents légers ne génèrent pas de vérifications de connectivité ni n'exécutent les machines d'état, bien qu'ils doivent être capables de répondre aux vérifications de connectivité. Lorsqu'une implémentation légère se connecte à une implémentation complète, l'agent complet prend le rôle de l'agent contrôleur, et l'agent léger prend le rôle contrôlé. Lorsque deux implémentations légères se connectent, aucune vérification n'est envoyée.
Pour des conseils sur le moment où une implémentation légère est appropriée, voir la discussion à l'annexe A.
Il est important de noter que l'implémentation légère a été ajoutée à cette spécification pour fournir un tremplin vers une implémentation complète. Même pour les appareils qui sont toujours connectés à l'Internet public, une implémentation complète est préférable si elle est réalisable.