Relates :
|
|
Relates :
|
I wonder why the implementations of Inet6AddressImpl_getLocalHostName() and Inet4AddressImpl_getLocalHostName() are different . It seems to me that this is simply copy/paste error since the very first 1.4 version. Here's what we currently have: Inet4AddressImpl_getLocalHostName() if (gethostname(hostname, NI_MAXHOST)) { /* Something went wrong, maybe networking is not setup? */ strcpy(hostname, "localhost"); } else { ... error = getaddrinfo(hostname, NULL, &hints, &res); ... error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, ... } We first call gethostname(). If that succeeds we call getaddrinfo() with the host name returned by gethostname() and if that succeeds again we call getnameinfo() with the address returned by getaddrinfo() to get the final hostname. This is uniformly done on all Unix platforms. And here's how the corresponding IPv6 version looks like: Inet6AddressImpl_getLocalHostName() ret = gethostname(hostname, NI_MAXHOST); #if defined(__solaris__) && defined(AF_INET6) ... error = getaddrinfo(hostname, NULL, &hints, &res); ... error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, #endif As you can see, for the IPv6 version we only do the getaddrinfo()/getnameinfo() roundtrip on Solaris although there is no evidence that the inovolved system calls behave differently for IPv4 and IPv6. Instead I think the IPv6 version is just a leftover of the very first implementation which hasn't been updated in the same way like its IPv4 counterpart. Notice the comment in the IPv6 version which says "Solaris doesn't want to give us a fully qualified domain name". But that holds true for the Linux version as well - gethostname() on Linux returns "uname -n" which is usually unqualified. The comment further notices that even the reverse lookup may not return a fully qualified name which is true because that's highly system and name service dependent. I think we can therefore safely use the same implementation for both, Inet4AddressImpl_getLocalHostName() and Inet6AddressImpl_getLocalHostName(). We should actually refactor this implementation into its own function to avoid differences in the future. There's also a funny punchline in this whole story: trough a bug introduced by the Mac OS port, the two implementations have been semanticall equal for a while. But then this has been changed back as a fix for "7166687: InetAddress.getLocalHost().getHostName() returns FQDN " (https://bugs.openjdk.java.net/browse/JDK-7166687 , http://hg.openjdk.java.net/jdk9/dev/jdk/rev/b26c04717735). But I'm pretty sure that change didn't really fixed the problem described in the bug report (maybe just incidentally worked around). Here's why: getLocalHostName() is used by InetAddress.getLocalHost(), but it's result (i.e. the host name) is immediately converted back into an address (i.e. InetAddress) on which subsequently getHostName() is called. The result of getHostName() only depends on the available name services and not on the fact if getLocalHostName() returned a simple or a fully qualified host name. However the resolution of a host name to an IP-address may be different depending on whether we have a simple (may resolve trough /etc/hosts) or fully qualified name (may resolve through name service like DNS). The hacky way to fix issue 7166687 would be to have the corresponding entries in your /etc/hosts (i.e. short names for both, IPv4 and IPv6 interfaces). The right way to handle it would be to actually expect both, simple and full qualified host names as return values from InetAddress.getHostName(). Notice the InetAddress.getLocalHost() isn't guaranteed to not return the loopback address. If you have configured your system such that /etc/hosts associates your host name with the loopback device and /etc/resolve.conf in such a way to first query /etc/hosts before doing a name service lookup (which is not unusual) than InetAddress.getLocalHost() will do just that - return the address of your loopback device! So to finally cut a long story short, I propose the following: - refactor the implementation of Inet6AddressImpl_getLocalHostName() and Inet4AddressImpl_getLocalHostName() into a single function which corresponds to the current Inet4AddressImpl_getLocalHostName() implementation. - it may be also possible to complete omit the call to getnameinfo() in that new implementation, because as far as I can see the 'ai_canonname' field of the first addrinfo structure returned by getaddrinfo() already contains the canonical name of the host if we pass AI_CANONNAME as 'hints' to getaddrinfo (which we already do). More information can be found in the following mail threads: http://mail.openjdk.java.net/pipermail/net-dev/2014-October/thread.html#8721 http://mail.openjdk.java.net/pipermail/net-dev/2013-June/thread.html#6543