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 [EMAIL PROTECTED] 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: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > -- 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
