簡體   English   中英

Java .netAddress.getAllByName() 不返回 Windows 上的 IPv6 地址,即使 -Djava.net.preferIPv6Addresses=true

[英]Java InetAddress.getAllByName() not returning IPv6 address on Windows even with -Djava.net.preferIPv6Addresses=true

我的 DNS 包含 ServerA 的兩條記錄:

  • 帶有 IPv4 地址的 A 記錄:10.25.46.130
  • 帶有 IPv6 地址的 AAAA 記錄:fda8:6c3:ce53:a890::55

我無法在 Windows 服務器上獲取我的SimpleClient.java程序(本文末尾的源代碼)以使用.netAddress.getAllByName()列出ServerA的 IPv6 地址,即使在使用 -Djava.net 配置 JVM 時-Djava.net.preferIPv6Addresses=true

在啟用 IPv6 的 Linux 服務器上運行的相同測試成功。

配置詳情:

  • Windows:服務器 2019 標准版 (10.0.17763)
  • Java:OpenJDK 11.0.5+

Windows 服務器上ipconfig的 output 顯示 IPv6 似乎已啟用:

> ipconfig
Windows IP Configuration

Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . :
   IPv4 Address. . . . . . . . . . . : 10.25.0.214
   Subnet Mask . . . . . . . . . . . : X.X.X.X
   Default Gateway . . . . . . . . . : X.X.X.X

Ethernet adapter Ethernet 2:

   Connection-specific DNS Suffix  . : fr.company.com
   IPv6 Address. . . . . . . . . . . : fda8:6c3:ce53:a890::3
   Link-local IPv6 Address . . . . . : X.X.X.X::X
   Default Gateway . . . . . . . . . : X.X.X.X::X

來自 Windows 服務器的nslookup output 是預期的:

> nslookup ServerA
Server:  dns.fr.company.com
Address:  X.X.X.X

Non-authoritative answer:
Name:    ServerA.fr.company.com
Addresses:  fda8:6c3:ce53:a890::55
          10.25.46.130

我能夠從 Windows 服務器成功運行ping -6 ServerA

> ping -6 ServerA
Pinging ServerA.fr.company.com [fda8:6c3:ce53:a890::55] with 32 bytes of data:
Reply from fda8:6c3:ce53:a890::55: time<1ms
Reply from fda8:6c3:ce53:a890::55: time<1ms

以下是從啟用 IPv6 的 Linux 服務器運行的預期 output

# IPv4 (default)
$ java SimpleClient.java ServerA 12345
preferIPv6Addresses: null
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130
ServerA/fda8:6c3:ce53:a890:0:0:0:55

# IPv6
$ java -Djava.net.preferIPv6Addresses=true SimpleClient.java ServerA 12345
preferIPv6Addresses: true
InetAddress.getByName()
ServerA/fda8:6c3:ce53:a890:0:0:0:55
InetAddress.getAllByName()
ServerA/fda8:6c3:ce53:a890:0:0:0:55
ServerA/10.25.46.130

相同的測試在 Windows 服務器上失敗:

# IPv4 (default)
> java SimpleClient.java ServerA 12345
preferIPv6Addresses: null
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130

# IPv6
> java -Djava.net.preferIPv6Addresses=true SimpleClient.java ServerA 12345
preferIPv6Addresses: true
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130

在 Windows 服務器上,對.netAddress.getAllByName()的調用僅返回一個 IPv4 地址,而不是像 Linux 啟用 IPv6 的服務器上預期的那樣同時返回 IPv4 和 IPv6 地址。

我可以在禁用 IPv6 的 Linux 服務器上重現相同的行為(grub 和 kernel 設置):

# IPv4 (default)
$ java SimpleClient.java ServerA 12345
preferIPv6Addresses: null
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130

# IPv6
$ java -Djava.net.preferIPv6Addresses=true SimpleClient.java ServerA 12345
preferIPv6Addresses: true
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130

從這些測試中,我得出結論,Windows 服務器的 IPv6 配置某處有問題,但我不知道是什么。

我試過的一些筆記和東西:

  • C:\Windows\System32\drivers\etc\hosts中手動添加ServerA的 IPv6 地址會導致程序列出 IPv6 地址,但只有這一個。
  • 我沒有在路徑Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters的注冊表中找到DisabledComponents

下面是SampleClient.java的代碼:

import java.net.Socket;
import java.net.UnknownHostException;
import java.net.InetAddress;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.IOException;

public class SimpleClient {
    public static void main(String[] args) {
        if (args.length < 2) return;
        String hostname = args[0];
        System.out.println("preferIPv6Addresses: " + System.getProperty("java.net.preferIPv6Addresses"));
        try {
          System.out.println("InetAddress.getByName()");
          System.out.println(InetAddress.getByName(hostname));
          InetAddress[] addresses = InetAddress.getAllByName(hostname);
          System.out.println("InetAddress.getAllByName()");
          for (InetAddress address : addresses) {
            System.out.println(address);
          }
        } catch (UnknownHostException ex) {
            System.out.println("Server not found: " + ex.getMessage());
        }
        int port = Integer.parseInt(args[1]);
        try (Socket socket = new Socket(hostname, port)) {
            InputStream input = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            System.out.println(reader.readLine());
        } catch (UnknownHostException ex) {
            System.out.println("Server not found: " + ex.getMessage());
        } catch (IOException ex) {
            System.out.println("I/O error: " + ex.getMessage());
        }
    }
}

有人可以暗示 Windows 服務器配置可能有問題嗎?

謝謝你。

問題出在 Windows 服務器的網絡配置中。

服務器配備了兩個網絡接口以在 IPv4 和 IPv6 之間進行隔離,每個接口都配置為支持單個網絡堆棧。

保留一個單一的網絡接口並在此接口上同時配置IPv4和 IPv6 解決了這個問題。

有關 SuperUser 問題的更多詳細信息: https://superuser.com/questions/1719174/jvm-on-windows-not-returning-any-ipv6-address-in-dns-lookup

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM