La détermination du moment d'essayer une connexion IPv6 et quand utiliser IPv4

StackOverflow https://stackoverflow.com/questions/1350592

  •  20-09-2019
  •  | 
  •  

Question

Je travaille sur un programme client de réseau qui se connecte aux serveurs publics, définis par l'utilisateur. Si l'utilisateur me donne un nom d'hôte pour se connecter à possédant à la fois les adresses IPv4 et IPv6 (généralement, un nom DNS avec les deux enregistrements A et AAAA), je ne sais pas comment je dois décider de quelle adresse je connecter.

Le problème est qu'il est assez courant pour les machines à supporter à la fois IPv4 et IPv6, mais seulement d'avoir une connectivité globale sur IPv4. Le cas le plus courant est lorsque les adresses ne lien local IPv6 sont configurés. À l'heure actuelle les meilleures alternatives que je peux trouver sont:

  1. Essayez l'adresse IPv6 (s) premier - si la connexion échoue, essayez l'adresse IPv4 (s); ou
  2. Il suffit de laisser l'utilisateur spécifier comme un paramètre de configuration ( "de prefer_ipv6" contre "prefer_ipv4").

Le problème que je peux voir avec l'option 1 est que la connexion ne défaille tout de suite - il peut prendre un certain temps en temps sur

.
Était-ce utile?

La solution

S'il vous plaît ne pas essayer IPv6. Dans la grande majorité des installations, en essayant de créer une connexion IPv6 ne pas tout de suite si elle ne peut réussir pour une raison:

  • si le système ne supporte pas les sockets IPv6, la création de la socket échouera
  • si le système prend en charge IPv6, et a des adresses locales de liaison configurées, il n'y aura pas une entrée de table de routage pour les adresses IPv6 globales. Encore une fois, le noyau local signaler l'échec sans envoyer de paquets.
  • si le système a une adresse IP globale, mais un lien nécessaire pour le routage est manquant, la source devrait soit obtenir un message d'erreur ICMPv6, indiquant que ne peut pas être atteint la destination; De même, si la destination a une adresse IPv6, mais le service n'écoute pas là-dessus.

Il y a naturellement des cas où les choses peuvent se briser, par exemple si une adresse globale (ou tunnel) est configuré, et quelque chose filtre faussement des messages d'erreur ICMPv6. Vous ne devriez pas vous soucier de ce cas -. Il peut être tout aussi bien que la connectivité IPv4 est en quelque sorte brisé

Bien sûr, il peut se demander si vous avez vraiment besoin d'essayer les adresses IPv6 premier - vous pourriez tout aussi bien les essayer seconde. En général, vous devriez essayer adresses dans l'ordre dans lequel ils sont renvoyés de getaddrinfo. Aujourd'hui, les systèmes prennent en charge les options de configuration qui permettent administators décider dans quelles adresses ordre doit être retourné de getaddrinfo.

Autres conseils

A la suite de la question posée l'IETF a proposé une réponse à cette question RFC6555 , alias Bonne Eyeballs .

Le point pertinent étant le client et le serveur peuvent avoir à la fois IPv4 et IPv6, mais un saut entre ne peut donc il est impossible de prédire avec certitude quel chemin fonctionnera.

Vous devez laisser la configuration du système à l'échelle décider grâce à getaddrinfo(). Tout comme Java. Demander à chaque configuration application unique pour tenter de répondre à chaque IPv6 possible (MIS) est vraiment pas extensible! Dans le cas d'une mauvaise configuration, il est beaucoup plus intuitif à l'utilisateur si tout ou rien applications pause.

D'autre part, vous voulez essayer de Journal délais et des délais d'attente avec effusion, afin que les utilisateurs peuvent rapidement identifier ce qu'il faut blâmer. Comme tous les autres retards dans l'idéal, y compris (très fréquent) DNS temporisations.

Cette conférence a la solution. Pour résumer;

  • Parfois, il y a des problèmes avec soit des requêtes DNS ou la connexion ultérieure à l'adresse résolue
  • Vous ne voulez pas attendre pour se connecter à une adresse IPv6 à délai d'attente avant de se connecter à l'adresse IPv4, ou vice versa
  • Vous ne voulez pas attendre une recherche pour un enregistrement à délai d'attente avant AAAA la recherche d'un enregistrement A ou vice versa
  • Vous ne voulez pas bloquer en attendant les deux enregistrements et AAAA avant de tenter de se connecter avec quel dossier vous en premier.

La solution consiste à rechercher des enregistrements AAAA et A simultanément et indépendamment, et pour relier de manière indépendante aux adresses résolues. Utilisez tout d'abord la connexion réussit.


La meilleure façon de le faire est de permettre à l'API de réseau le faire pour vous connecter à l'aide par nom des API de réseau. Par exemple, en Java:

InetSocketAddress socketAddress = new InetSocketAddress("www.example.com", 80);
SocketChannel channel = SocketChannel.open(socketAddress);
channel.write(buffer);

Les notes de diapositives disent à ce moment:

  

nous faisons ici un objet opaque appelé InetSocketAddress d'un hôte   et le port, et quand nous ouvrons ce SocketChannel, qui peut compléter   sous les couvertures, faire tout ce qui est nécessaire, sans   demande jamais voir une adresse IP.

     

Windows a également se connecter par nom API. Je n'ai pas des fragments de code pour   ceux qui sont ici.

     

Maintenant, je ne dis pas que toutes les implémentations de ces API nécessairement   faire la bonne chose aujourd'hui, mais si les applications utilisent ces API,   puis les mises en œuvre peuvent être améliorées au fil du temps.

     

Le di! Érence avec getaddrinfo () et API similaires est qu'ils   fondamentalement ne peut pas être améliorée au fil du temps. L'API de définition est que   ils vous retourner une liste complète des adresses, de sorte qu'ils doivent attendre   ils ont cette liste complète pour vous donner. Il n'y a pas getaddrinfo de façon peut   vous renvoie une liste partielle et puis plus tard vous donner un peu plus.

Quelques idées:

  1. Permettre à l'utilisateur de spécifier la préférence sur une base par site.
  2. Essayez IPv4 d'abord.
  3. Tentative IPv6 en parallèle lors de la première connexion.
  4. Lors des connexions suivantes, utilisez IPv6 si la connexion a réussi auparavant.

Je dis d'essayer IPv4 d'abord parce que c'est le protocole qui est mieux établi et testé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top