Utilisation d'IPv6 dans un programme Java réel


L'utilisation d'IPv6 commence lentement de nos jours, donc je suis actuellement en train de réparer et de mettre à jour toutes les applications à préparer pour IPv6.

L'une des applications est l'éditeur Java JOSM (http://josm.openstreetmap.de / ). Java n'utilise pas vraiment IPv6 dans la configuration par défaut même si le système d'exploitation utilise IPv6.

Selon http://docs.oracle.com/javase/1.5.0/docs/guide/net/ipv6_guide/#using J'ai défini java.net.preferIPv6Addresses sur true pour le laisser utiliser IPv6. Résultat ont été utilisateur rapports de bogue sur la connexion Internet cassée.

Il semble que Java ne commute que pour utiliser l'adresse IPv6 au lieu d'IPv4, mais ne fait rien d'autre. Tous les logiciels basés sur C/C++ que je maintiens ont été modifiés pour vérifier et essayer toutes les adresses IP disponibles, donc les adresses IPv6 (ou IPv4) cassées sont ignorées tant que l'une des adresses fonctionne. Pour moi, il semble que Java n'essaie qu'une seule fois, ce qui ne fonctionne pas dans le monde réel.

De plus, le système d'exploitation préfère généralement IPv4 à IPv6, lorsque IPv6 est tunnelisé. Il semble que Java ignore également ces paramètres.

Ma question est donc la suivante: Existe-t-il de bons moyens d'obtenir une application Java pour utiliser IPV6 par défaut lorsqu'elle est disponible sans casser l'application pour les utilisateurs IPv4.

Rapports de bogue utilisateur: http://josm.openstreetmap.de/ticket/8562, http://josm.openstreetmap.de/ticket/8627 .

Author: Dirk Stöcker, 2013-04-23

2 answers

Vous avez donc deux problèmes ici:

  1. Les fournisseurs de systèmes d'exploitation expédient des systèmes d'exploitation avec des configurations IPv6 par défaut cassées et/ou les utilisateurs activent des configurations IPv6 cassées.

  2. Quand cela ne fonctionne pas, ils vous blâment à tort.

Il y a deux choses que vous pouvez faire ici:

  1. Conseiller les utilisateurs sur la façon de désactiver les mécanismes de transition IPv6 inutiles et cassés tels que Teredo, ISATAP et 6to4. Les instructions pour ceux-ci sont largement disponibles sur Internet.

    Ce serait également bien si certains fournisseurs de systèmes d'exploitation n'activaient pas cette merde par défaut, mais cela en demande probablement trop.

  2. Mettre en Œuvre Heureux Globes oculaires (RFC 6555) dans votre application. C'est ainsi que les navigateurs Web modernes résolvent ce problème.

    Happy Eyeballs spécifie un algorithme par lequel une application essaie de se connecter via IPv6 et IPv4 (presque) en même temps, et si IPv6 ne fonctionne pas dans un court laps de temps, de revenir à la Connexion IPv4. Les résultats de cet essai sont également mis en cache pendant quelques minutes.

    Malheureusement, je ne suis pas assez familier avec Java pour vous donner du code spécifique pour contourner toutes les choses intéressantes qu'Oracle vous cache par défaut, mais il devrait être faisable.

 0
Author: Michael Hampton, 2013-04-23 17:27:20

Il semble que le sujet soit également intéressant pour les autres, donc je décris ma solution actuelle.

  • Le logiciel fait une détection si IPv6 fonctionne ou non et se souvient de l'état- > Cela se fait en effectuant une connexion TCP à une adresse IPv6 connue (le ping de isReachable () n'est pas fiable, voir ce rapport de bogue: https://josm.openstreetmap.de/ticket/11452).
  • Basé sur l'état mémorisé, le logiciel commence par "java. net. preferIPv6Addresses" défini sur "vrai".
  • Cela signifie que pour un passage d'IPv4 à un réseau IPv6, il utilisera IPv4 jusqu'au prochain redémarrage, ce qui est ok.
  • Pour un passage d'un réseau IPv6 activé à un réseau IPv4 uniquement, cela ne fonctionnera pas du tout, ce qui est résolu en redémarrant le logiciel.
  • En cas de doute, nous supposons que IPv6 ne fonctionne pas.
  • Il n'est pas possible de modifier "java.net.preferIPv6Addresses" après avoir effectué la détection, car ces valeurs semblent être en lecture seule avant la première connexion réseau. Si il y a un façon de réinitialiser cet état pendant l'exécution, je voudrais le savoir.

Cette solution semble fonctionner, nous avons environ 4% de connexions IPv6 dans nos logs ATM, mais ce n'est pas vraiment une solution satisfaisante.

/**
 * Check if IPv6 can be safely enabled and do so. Because this cannot be done after network activation,
 * disabling or enabling IPV6 may only be done with next start.
 */
private static void checkIPv6() {
  if ("auto".equals(Main.pref.get("prefer.ipv6", "auto"))) {
    new Thread(new Runnable() { /* this may take some time (DNS, Connect) */
      public void run() {
        boolean hasv6 = false;
        boolean wasv6 = Main.pref.getBoolean("validated.ipv6", false);
        try {
          /* Use the check result from last run of the software, as after the test, value
             changes have no effect anymore */
          if (wasv6) {
            Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
          }
          for (InetAddress a : InetAddress.getAllByName("josm.openstreetmap.de")) {
            if (a instanceof Inet6Address) {
              if (a.isReachable(1000)) {
                /* be sure it REALLY works */
                Socket s = new Socket();
                s.connect(new InetSocketAddress(a, 80), 1000);
                s.close();
                Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
                if (!wasv6) {
                  Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4 after next restart."));
                } else {
                  Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4."));
                }
                hasv6 = true;
              }
              break; /* we're done */
            }
          }
        } catch (IOException | SecurityException e) {
          if (Main.isDebugEnabled()) {
            Main.debug("Exception while checking IPv6 connectivity: "+e);
          }
        }
        if (wasv6 && !hasv6) {
          Main.info(tr("Detected no useable IPv6 network, prefering IPv4 over IPv6 after next restart."));
          Main.pref.put("validated.ipv6", hasv6); // be sure it is stored before the restart!
          new RestartAction().actionPerformed(null);
        }
        Main.pref.put("validated.ipv6", hasv6);
      }
    }, "IPv6-checker").start();
  }
}
 0
Author: Dirk Stöcker, 2016-02-14 13:48:56