jakarta-jcs-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dieter Laufkoetter <dieter.laufkoet...@siemens.com>
Subject Re: [jira] Created: (JCS-40) InetAddress.getLocalHost() ambiguous on Linux systems
Date Fri, 14 Mar 2008 10:27:13 GMT

HostNameUtil.getLocalHostAddress() is only used for debug issues and not to
bind at one of multiple network cards.
The socket to send data is created in
org.apache.jcs.auxiliary.lateral.socket.tcp.utils.SocketOpener by Socket(
String host, int port ) and not with Socket( String host, int port,
InetAddress localAddr, int localPort ), so the operating system decides the
network card.



JIRA jira@apache.org wrote:
> 
> InetAddress.getLocalHost() ambiguous on Linux systems
> -----------------------------------------------------
> 
>                  Key: JCS-40
>                  URL: https://issues.apache.org/jira/browse/JCS-40
>              Project: JCS
>           Issue Type: Bug
>     Affects Versions: jcs-1.3
>          Environment: Linux and other *nix systems
>             Reporter: Niall Gallagher
>             Assignee: Aaron Smuts
> 
> 
> Per JDK bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037
> 
> ...InetAddress.getLocalHost() is ambiguous on Linux systems. JCS uses this
> method. We have found that the issue breaks JCS networking on Linux/*nix
> systems (tested on Fedora, Red Hat and CentOS) configured with both static
> and DHCP-assigned IP addresses. The only workarounds we can find either do
> not 100% fix the problem, or require non-optimal configuration of the OS
> loopback connection.
> 
> Background:
> On Windows the address returned by InetAddress.getLocalHost() is fairly
> consistent; typically the server's LAN address. On Windows systems with
> multiple network cards (e.g. Internet, WAN, LAN, VPN, multi-homed), the
> address returned is ambiguous however.
> 
> On Linux, the address returned by InetAddress.getLocalHost() seems to
> depend on the order in which the OS lists network interfaces, which really
> should be irrelevant. Furthermore the behaviour can vary between Linux
> distributions. Linux always exposes the loopback address (127.0.0.1) as a
> virtual network card, as if it was a physical NIC. On servers using DHCP,
> the method usually returns the loopback address. On servers configured
> with static IP addresses, depending on OS ordering, the method sometimes
> returns the LAN address but sometimes returns the loopback (127.0.0.1)
> address.
> 
> InetAddress.getLocalHost() makes no attempt to prioritize LAN/non-loopback
> addresses in its selection.
> 
> Impact on JCS:
> This affects networking in JCS in general. e.g. remote cache and lateral
> cache. JCS can bind to the loopback interface (127.0.0.1) instead of the
> LAN address, or the RMI system can advertise the wrong (127.0.0.1) IP
> address to clients when sending events. We use the JCS remote cache
> server, and saw both of these issues on Fedora, Red Hat and CentOS
> machines configured with static and DHCP-assigned addresses.
> 
> We first tried various workarounds:
> -setting system property java.rmi.server.hostname=x.x.x.x
> --> JCS overrides this by supplying an invalid (127.0.0.1) IP address to
> the RMI subsystem explicitly
> -changing the IP address associated with localhost in /etc/hosts file from
> 127.0.0.1 to the machines LAN address
> -->reduces the performance of inter-process (loopback) communication on
> the server
> 
> In the end we modified the JCS source code, and we have been running it
> flawlessly for the past 8 months. The fix requires JDK 1.4. Can we
> therefore get it integrated into the next 1.4 release of JCS?
> 
> JCS uses InetAddress.getLocalHost() in the following classes:
> org/apache/jcs/auxiliary/lateral/socket/tcp/discovery/UDPDiscoveryService.java
> org/apache/jcs/auxiliary/remote/server/RemoteCacheStartupServlet.java
> org/apache/jcs/utils/net/HostNameUtil.java
> 
> We updated UDPDiscoveryService and RemoteCacheStartupServlet to not call
> InetAddress.getLocalHost() directly, but to call the getLocalHostAddress()
> method in HostNameUtil instead.
> 
> We then changed the implementation of HostNameUtil.getLocalHostAddress()
> as follows:
> 
>     public static String getLocalHostAddress() throws UnknownHostException
> {
> 
>         return getLocalHostLANAddress().getHostAddress();
> 
>     }
> 
>     /**
>      * Returns an <code>InetAddress</code> object encapsulating what is
> most likely the machine's LAN IP address.
>      * <p/>
>      * This method is intended for use as a replacement of JDK method
> <code>InetAddress.getLocalHost</code>, because
>      * that method is ambiguous on Linux systems. Linux systems enumerate
> the loopback network interface the same
>      * way as regular LAN network interfaces, but the JDK
> <code>InetAddress.getLocalHost</code> method does not
>      * specify the algorithm used to select the address returned under
> such circumstances, and will often return the
>      * loopback address, which is not valid for network communication.
> Details
>      *  http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037 here .
>      * <p/>
>      * This method will scan all IP addresses on all network interfaces on
> the host machine to determine the IP address
>      * most likely to be the machine's LAN address. If the machine has
> multiple IP addresses, this method will prefer
>      * a site-local IP address (e.g. 192.168.x.x or 10.10.x.x, usually
> IPv4) if the machine has one (and will return the
>      * first site-local address if the machine has more than one), but if
> the machine does not hold a site-local
>      * address, this method will return simply the first non-loopback
> address found (IPv4 or IPv6).
>      * <p/>
>      * If this method cannot find a non-loopback address using this
> selection algorithm, it will fall back to
>      * calling and returning the result of JDK method
> <code>InetAddress.getLocalHost</code>.
>      * <p/>
>      *
>      * @throws UnknownHostException If the LAN address of the machine
> cannot be found.
>      */
>     private static InetAddress getLocalHostLANAddress() throws
> UnknownHostException {
>         try {
>             InetAddress candidateAddress = null;
>             // Iterate all NICs (network interface cards)...
>             for (Enumeration ifaces =
> NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
>                 NetworkInterface iface = (NetworkInterface)
> ifaces.nextElement();
>                 // Iterate all IP addresses assigned to each card...
>                 for (Enumeration inetAddrs = iface.getInetAddresses();
> inetAddrs.hasMoreElements();) {
>                     InetAddress inetAddr = (InetAddress)
> inetAddrs.nextElement();
>                     if (!inetAddr.isLoopbackAddress()) {
> 
>                         if (inetAddr.isSiteLocalAddress()) {
>                             // Found non-loopback site-local address.
> Return it immediately...
>                             return inetAddr;
>                         }
>                         else if (candidateAddress == null) {
>                             // Found non-loopback address, but not
> necessarily site-local.
>                             // Store it as a candidate to be returned if
> site-local address is not subsequently found...
>                             candidateAddress = inetAddr;
>                             // Note that we don't repeatedly assign
> non-loopback non-site-local addresses as candidates,
>                             // only the first. For subsequent iterations,
> candidate will be non-null.
>                         }
>                     }
>                 }
>             }
>             if (candidateAddress != null) {
>                 // We did not find a site-local address, but we found some
> other non-loopback address.
>                 // Server might have a non-site-local address assigned to
> its NIC (or it might be running
>                 // IPv6 which deprecates the "site-local" concept).
>                 // Return this non-loopback candidate address...
>                 return candidateAddress;
>             }
>             // At this point, we did not find a non-loopback address.
>             // Fall back to returning whatever InetAddress.getLocalHost()
> returns...
>             InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
>             if (jdkSuppliedAddress == null) {
>                 throw new UnknownHostException("The JDK
> InetAddress.getLocalHost() method unexpectedly returned null.");
>             }
>             return jdkSuppliedAddress;
>         }
>         catch (Exception e) {
>             UnknownHostException unknownHostException = new
> UnknownHostException("Failed to determine LAN address: " + e);
>             unknownHostException.initCause(e);
>             throw unknownHostException;
>         }
>     }
> 
> 
> 
> -- 
> This message is automatically generated by JIRA.
> -
> You can reply to this email to add a comment to the issue online.
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jcs-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: jcs-dev-help@jakarta.apache.org
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/-jira--Created%3A-%28JCS-40%29-InetAddress.getLocalHost%28%29-ambiguous-on-Linux-systems-tp15827289p16047975.html
Sent from the JCS - Dev mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jcs-dev-help@jakarta.apache.org


Mime
View raw message