8

最近ではIPv6の使用が徐々に始まっているため、IPv6に備えてすべてのアプリケーションを修正および更新している最中です。

アプリケーションの 1 つは、Java エディター JOSM ( http://josm.openstreetmap.de/ ) です。Java は、OS が IPv6 を使用していても、デフォルト構成では実際には IPv6 を使用しません。

http://docs.oracle.com/javase/1.5.0/docs/guide/net/ipv6_guide/#usingによると、 IPv6を使用できるよう に設定java.net.preferIPv6Addressesしました。trueその結果、インターネット接続の切断に関するユーザーのバグ報告がありました。

JavaはIPv4の代わりにIPv6アドレスを使用するように切り替えるだけのようですが、他には何もしません。私が維持しているすべての C/C++ ベースのソフトウェアは、利用可能なすべての IP アドレスをチェックして試すように変更されているため、アドレスの 1 つが機能する限り、壊れた IPv6 (または IPv4) アドレスはスキップされます。私にとっては、Java は 1 回しか試行しないように見えますが、これは実際には機能しません。

また、通常、IPv6 がトンネリングされている場合、OS は IPv6 よりも IPv4 を優先します。Javaもこの設定を無視しているようです。

だから私の質問は次のとおりです。IPv4ユーザーのアプリケーションを壊すことなく、Javaアプリケーションが利用可能な場合にデフォルトでIPV6を使用する良い方法はありますか?

ユーザー バグ レポート: http://josm.openstreetmap.de/ticket/8562http://josm.openstreetmap.de/ticket/8627

4

2 に答える 2

1

トピックは他の人にとっても興味深いようですので、現在の解決策について説明します。

  • ソフトウェアは、IPv6 が機能しているかどうかを検出し、状態を記憶します -> これは、既知の IPv6 アドレスに TCP 接続することによって行われます (isReachable() の Ping は信頼できません。次のバグ レポートを参照してください: https://josm. openstreetmap.de/ticket/11452 )。
  • 記憶された状態に基づいて、ソフトウェアは「java.net.preferIPv6Addresses」を「true」に設定して開始します。
  • これは、IPv4 から IPv6 ネットワークへの切り替えの場合、次の再起動まで IPv4 を使用することを意味します。
  • IPv6 が有効なネットワークから IPv4 のみのネットワークへの切り替えでは、まったく機能しません。これは、ソフトウェアを再起動することで解決されます。
  • 疑わしい場合は、IPv6 が機能しないと想定します。
  • 検出を行った後に「java.net.preferIPv6Addresses」を変更することはできません。その値は、最初のネットワーク接続の前にのみ読み取られるように見えるためです。実行時にその状態をリセットする方法があれば、それについて知りたいです。

このソリューションは機能しているように見えます。ログ ATM には約 4% の IPv6 接続がありますが、実際には満足のいくソリューションではありません。

/**
 * 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();
  }
}
于 2016-02-14T13:48:56.150 に答える
0

したがって、ここに 2 つの問題があります。

  1. オペレーティング システム ベンダーは、デフォルトの IPv6 構成が壊れた状態で OS を出荷したり、ユーザーが壊れた IPv6 構成を有効にしたりします。

  2. それがうまくいかないとき、彼らは誤ってあなたを責めます。

ここでできることは 2 つあります。

  1. Teredo、ISATAP、6to4 などの不要で壊れた IPv6 移行メカニズムを無効にする方法について、ユーザーにアドバイスします。これらの手順は、インターネット上で広く入手できます。

    また、特定の OS ベンダーがデフォルトでこのがらくたを有効にしないとよいのですが、それはおそらく要求が多すぎます。

  2. アプリケーションにHappy Eyeballs ( RFC 6555 ) を実装します。これが、最新の Web ブラウザーがこの問題を解決する方法です。

    Happy Eyeballs は、アプリケーションが IPv6 と IPv4 を介して (ほぼ) 同時に接続を試み、IPv6 が短時間で機能しない場合は IPv4 接続にフォールバックするアルゴリズムを指定します。この試行の結果も数分間キャッシュされます。

    残念ながら、私は Java に精通しておらず、Oracle がデフォルトで隠しているすべての興味深い機能を回避するための特定のコードを提供できませんが、実行可能なはずです。

于 2013-04-23T17:27:20.213 に答える