似乎这个话题对其他人来说也很有趣,所以我描述了我目前的解决方案。
- 该软件会检测 IPv6 是否工作并记住状态 -> 这是通过 TCP 连接到已知的 IPv6 地址来完成的(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();
}
}