Date de publication du RFC : Avril 2012
Auteur(s) du RFC : D. Wing, A. Yourtchenko (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 7 avril 2012
Une question récurrente qu'IPv6 pose aux développeurs d'application et aux administrateurs système qui déploieront ces applications ensuite est celle d'une machine accessible à la fois en IPv4 et IPv6. Si le pair cherchant à joindre cette machine croit avoir IPv6 mais que sa connectivité ne marche pas, ou mal, l'application arrivera-t-elle à se rabattre en IPv4 très vite ou bien imposera-t-elle à l'utilisateur un long délai avant de détecter enfin le problème ? Cette question est connue comme « le bonheur des globes oculaires » (les dits globes étant les yeux de l'utilisateur qui attend avec impatience la page d'accueil de YouPorn) et ce RFC spécifie les exigences pour l'algorithme de connexion du client, afin de rendre les globes oculaires le plus heureux possible. (Il a depuis été remplacé par un RFC plus général, ne se limitant pas à IPv6, le RFC 8305.)
La section 1 rappelle les données du problème : on veut évidemment que cela marche aussi bien en IPv6 qu'en IPv4 (pas question d'accepter des performances inférieures) or, dans l'état actuel du déploiement d'IPv6, bien des sites ont une connexion IPv6 totalement ou partiellement cassée. Si un serveur a IPv4 et IPv6 et que son client n'a qu'IPv4, pas de problème. Mais si le client a IPv6, tente de l'utiliser, mais que sa connexion est plus ou moins en panne, ses globes oculaires vont souffrir d'impatience. Certains fournisseurs (notamment Google) ont résolu le problème en n'annonçant leur connectivité IPv6 (via le DNS et les enregistrements AAAA) qu'à certains réseaux, configurés manuellement après examen de la qualité effective de leur connectivité. Cette approche, nommée « whitelisting » ne passe évidemment pas à l'échelle. Même pour Google, c'est un travail colossal que d'évaluer le réseau de tous les sites Internet.
(À noter que deux lecteurs m'ont fait remarquer que YouPorn n'est pas un bon exemple, puisqu'il ne publie pas d'adresse IPv6. C'est vrai et cela montre que mes lecteurs connaissent bien YouPorn.)
La bonne solution est donc que l'application elle-même gère le problème (ou, sinon l'application elle-même, la bibliothèque logicielle qu'elle utilise et où se trouve la fonction de connexion). Il existe plusieurs algorithmes pour cela, déjà largement déployés. Ce RFC normalise les caractéristiques que doivent avoir ces algorithmes. Si on suit ce RFC, le trafic (IP et DNS) va légèrement augmenter (surtout si la connectivité IPv6 marche mal ou pas du tout) mais la qualité du vécu de l'utilisateur va être maintenue, même en présence de problèmes, ce qui compense largement. Autrement, il existerait un risque élevé que certains utilisateurs coupent complètement IPv6, plutôt que de supporter ces problèmes de délai de connexion.
La section 3 revient dans l'histoire, pour montrer que le problème n'est pas nouveau. En 1994, le RFC 1671 disait « The dual-stack code may get two addresses back from DNS; which does it use? During the many years of transition the Internet will contain black holes. » (Au passage, cela montre la stupidité de la légende, fréquemment entendue, comme quoi les problèmes de la transition IPv4->IPv6 n'auraient pas été étudiés à l'avance.) Tout le reste de notre RFC 6555 est consacré à répondre à cette question. La cible principale est composée des protocoles de transport avec connexion (TCP, SCTP), les protocoles sans connexion comme UDP soulevant d'autres questions (s'ils ont une sémantique requête/réponse, comme dans ICE, les algorithmes de ce RFC peuvent être utilisés).
Le RFC rejette l'idée d'utiliser des noms différents pour les deux familles (comme
www.ipv6.example.com
), car cela complique le
partage de noms (envoi d'un URL à un copain,
par exemple).
Donc, on a un nom de machine qu'on veut contacter, mettons
www.example.com
, avec deux adresses associées,
une par famille (voir les sections 5.3 et 5.4 pour le cas avec plus de deux adresses). Avec l'algorithme naïf
qu'utilisent certains logiciels, et une connexion IPv6 qui marche mal,
voici la séquence d'évenements :
192.0.2.1
et
2001:db8::1
./etc/gai.conf
). L'initiateur envoie un paquet
TCP SYN
à
2001:db8::1
.SYN
à 192.0.2.1
.SYN+ACK
en échange,
l'initiateur réplique par un ACK
et la connexion
TCP est établie.Le problème de cet algorithme naïf est donc la longue attente lors des essais IPv6. On veut au contraire un algorithme qui bascule rapidement en IPv4 lorsqu'IPv6 ne marche pas, sans pour autant gaspiller les ressources réseau en essayant par exemple toutes les adresses en même temps.
L'algorithme recommandé (section 4, cœur de ce RFC) aura donc la tête :
192.0.2.1
et
2001:db8::1
. Il sait donc qu'il a plusieurs
adresses, de famille différente.SYN
à
2001:db8::1
, avec un très court délai de garde.SYN
à 192.0.2.1
.SYN+ACK
en échange,
l'initiateur réplique par un ACK
et la connexion
TCP est établie.Si le répondeur réagit à une vitesse normale en IPv6, la connexion sera établie en IPv6. Sinon, on passera vite en IPv4, et l'utilisateur humain ne s'apercevra de rien. Naturellement, si le DNS n'avait rapporté qu'une seule adresse (v4 ou v6), on reste à l'algorithme traditionnel (« essayer, patienter, ré-essayer »).
La section 4 précise ensuite les exigences auxquelles doit obéir
l'algorithme. D'abord, il est important de ne pas tester IPv4 tout de
suite. Les premiers algorithmes « bonheur des globes oculaires »
envoyaient les deux paquets SYN
en même
temps,
gaspillant des ressources réseau et serveur. Ce double essai faisait
que les équipements IPv4 du réseau avaient autant de travail qu'avant,
alors qu'on aurait souhaité les retirer du service petit à petit. En
outre, ce test simultané fait que, dans la moitié des cas, la
connexion sera établie en IPv4, empêchant de tirer profit des
avantages d'IPv6 (cf. RFC 6269). Donc, on
doit tester en IPv6 d'abord, sauf si on se
souvient des tentatives précédentes (voir plus loin la variante « avec
état ») ou bien si l'administrateur système a délibérement configuré
la machine pour préférer IPv4.
L'avantage de cet algorithme « IPv6 d'abord puis rapidement basculer en IPv4 » est qu'il est sans état : l'initiateur n'a pas à garder en mémoire les caractéristiques de tous ses correspondants. Mais son inconvénient est qu'on recommence le test à chaque connexion. Il existe donc un algorithme avec état, où l'initiateur peut garder en mémoire le fait qu'une machine (ou bien un préfixe entier) a une adresse IPv6 mais ne répond pas aux demandes de connexion de cette famille. Le RFC recommande toutefois de re-essayer IPv6 au moins toutes les dix minutes, pour voir si la situation a changé. De plus, un changement de connectivité (détecté par le DNA des RFC 4436 ou RFC 6059) doit entraîner un vidage complet de l'état (on doit oublier ce qu'on a appris, qui n'est plus pertinent).
Une conséquence de l'algorithme recommandé est que, dans certains
cas, les deux connexions TCP (v4 et v6) seront
établies (si le SYN
IPv6 voyage lentement et que
la réponse arrive après que l'initiateur de la connexion se soit
impatienté et soit passé à IPv4). Cela peut être intéressant dans certains cas rares, mais le
RFC recommande plutôt d'abandonner la connexion perdante (la
deuxième). Autrement, cela pourrait entraîner des problèmes avec, par
exemple, les sites Web qui lient un
cookie à l'adresse IP du
client, et seraient surpris de voir deux connexions avec des adresses différentes.
Voilà, l'essentiel du RFC est là. La section 5 donne quelques détails en plus. Par exemple, l'algorithme des globes oculaires heureux est astucieux, mais tend à masquer les problèmes. Si un site Web publie les deux adresses mais que sa connectivité IPv6 est défaillante, aucun utilisateur ne lui signalera puisque, pour eux, tout va bien. Il est donc recommandé que le logiciel permette de débrayer cet algorithme, afin de tester la connectivité avec seulement v4 ou seulement v6, ou bien que le logiciel indique quelque part ce qu'il a choisi, pour mieux identifier d'éventuels problèmes v6.
D'autre part, vous avez peut-être remarqué que j'ai utilisé des
termes vagues (« un certain temps ») pour parler du délai entre, par
exemple, le premier SYN
IPv6 et le premier
SYN
IPv4. La section 5.5 donne des idées
quantitatives en suggérant entre 150 et 250 ms entre deux
essais (les navigateurs actuels sont plutôt du côté de 300 ms). C'est quasiment imperceptible à un utilisateur humain devant
son navigateur Web, tout en évitant de surcharger le réseau
inutilement. Les algorithmes avec état ont le droit d'être plus
impatients, puisqu'ils peuvent se souvenir des durées d'établissement
de connexion précédents.
Autre problème pratique, l'interaction avec la politique de sécurité des navigateurs Web (RFC 6454). Pour limiter les risques d'attaque par changement DNS (croire qu'on se connecte au même serveur HTTP alors que c'est en fait un autre), les navigateurs ne doivent pas changer de famille d'adresse (v4 en v6 ou réciproquement) une fois la session commencée.
Enfin, les implémentations. La section 6 donne les exemples de
Firefox et Chrome, très
proches de ce que décrit le RFC. D'autres
possibilités sont disponibles en ligne, en
Erlang ou en
C. Une version pour
Go avait été affichée en http://www.pastie.org/1528545
(en voici une sauvegarde locale).
Enfin, pour un exemple de test du malheur des globes oculaires, voir « Experiences of host behavior in broken IPv6 networks ». Ou bien « Evaluating the Effectiveness of Happy Eyeballs » qui contient d'intéressantes mesures.
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)