prefer IPv4 addresses for localhost (this is what people seem to expect)
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/a738eb55 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/a738eb55 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/a738eb55 Branch: refs/heads/master Commit: a738eb55f3182d81241e070fcee2b418a145d9d2 Parents: 810ce62 Author: Alex Heneveld <[email protected]> Authored: Wed Jul 19 12:54:26 2017 +0100 Committer: Alex Heneveld <[email protected]> Committed: Sat Jul 22 03:10:09 2017 +0100 ---------------------------------------------------------------------- .../util/core/BrooklynNetworkUtils.java | 4 ++-- .../apache/brooklyn/util/net/Networking.java | 24 ++++++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a738eb55/core/src/main/java/org/apache/brooklyn/util/core/BrooklynNetworkUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/util/core/BrooklynNetworkUtils.java b/core/src/main/java/org/apache/brooklyn/util/core/BrooklynNetworkUtils.java index 190ad75..949f48f 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/BrooklynNetworkUtils.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/BrooklynNetworkUtils.java @@ -44,9 +44,9 @@ public class BrooklynNetworkUtils { * {@link BrooklynServiceAttributes#LOCALHOST_IP_ADDRESS} * if set to prevent default selection when needed, * otherwise finding the first bindable/reachable NIC from a system lookup which usually - * prefers non-loopback devices (but use the system property if if needed) */ + * prefers IPv4 then non-loopback devices (but use the system property if if needed) */ public static InetAddress getLocalhostInetAddress() { return TypeCoercions.coerce(JavaGroovyEquivalents.elvis(BrooklynServiceAttributes.LOCALHOST_IP_ADDRESS.getValue(), - Networking.getLocalHost(true, false, true, 500)), InetAddress.class); + Networking.getLocalHost(true, false, true, true, 500)), InetAddress.class); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a738eb55/utils/common/src/main/java/org/apache/brooklyn/util/net/Networking.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/net/Networking.java b/utils/common/src/main/java/org/apache/brooklyn/util/net/Networking.java index f0728dd..a02dea2 100644 --- a/utils/common/src/main/java/org/apache/brooklyn/util/net/Networking.java +++ b/utils/common/src/main/java/org/apache/brooklyn/util/net/Networking.java @@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkArgument; import java.io.IOException; import java.net.DatagramSocket; +import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; @@ -50,6 +51,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.base.Stopwatch; import com.google.common.base.Throwables; +import com.google.common.collect.Iterables; import com.google.common.collect.Range; import com.google.common.collect.RangeSet; import com.google.common.collect.TreeRangeSet; @@ -89,6 +91,9 @@ public class Networking { return isPortAvailable(ANY_NIC, port); } public static boolean isPortAvailable(InetAddress localAddress, int port) { + return isPortAvailable(localAddress, port, SET_REUSE_ADDRESS); + } + public static boolean isPortAvailable(InetAddress localAddress, int port, Boolean allowReuse) { if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) { throw new IllegalArgumentException("Invalid start port: " + port); } @@ -101,19 +106,21 @@ public class Networking { //Svet - SO_REUSEADDR (enabled below) will allow one socket to listen on 0.0.0.0:X and another on //192.168.0.1:X which explains the above comment (nginx sets SO_REUSEADDR as well). Moreover there //is no TIME_WAIT for listening sockets without any connections so why enable it at all. + //Alex - TIME_WAIT sticks around for a while (30s or so) if a java process dies while it has + //connections; if we want things to aggressively try to take a port, they should use reuse-addr ServerSocket ss = null; DatagramSocket ds = null; try { // Check TCP port ss = new ServerSocket(); ss.setSoTimeout(250); - if (SET_REUSE_ADDRESS!=null) { ss.setReuseAddress(SET_REUSE_ADDRESS); } + if (allowReuse!=null) { ss.setReuseAddress(allowReuse); } ss.bind(new InetSocketAddress(localAddress, port)); // Check UDP port ds = new DatagramSocket(null); ds.setSoTimeout(250); - if (SET_REUSE_ADDRESS!=null) { ss.setReuseAddress(SET_REUSE_ADDRESS); } + if (allowReuse!=null) { ss.setReuseAddress(allowReuse); } ds.bind(new InetSocketAddress(localAddress, port)); } catch (IOException e) { if (log.isTraceEnabled()) log.trace("Failed binding to " + localAddress + " : " + port, e); @@ -143,7 +150,7 @@ public class Networking { Enumeration<InetAddress> as = ni.getInetAddresses(); while (as.hasMoreElements()) { InetAddress a = as.nextElement(); - if (!isPortAvailable(a, port)) { + if (!isPortAvailable(a, port, allowReuse)) { if (isAddressValid(a)) { if (log.isTraceEnabled()) log.trace("Port {} : {} @ {} is taken and the address is valid", new Object[] {a, port, nis}); return false; @@ -433,12 +440,12 @@ public class Networking { * use {@link #getLocalHost(boolean, boolean, boolean, int)} for full control or * {@link #getReachableLocalHost()} for a method with better defaults and errors */ public static InetAddress getLocalHost() { - return getLocalHost(false, true, false, 0); + return getLocalHost(false, true, true, false, 0); } /** returns a validated local IP address, preferring 127.0.0.1 if it works, and failing if none found */ public static InetAddress getReachableLocalHost() { - return getLocalHost(true, true, true, 250); + return getLocalHost(true, true, true, true, 250); } /** @@ -450,12 +457,15 @@ public class Networking { * @param timeout how long to wait for each address (if doing checkReachable) * @return an {@link InetAddress} corresponding to localhost */ - public static InetAddress getLocalHost(boolean checkReachable, boolean prefer127, boolean failIfNone, int timeout) { + public static InetAddress getLocalHost(boolean checkReachable, boolean prefer127, boolean preferIpV4, boolean failIfNone, int timeout) { Map<String, InetAddress> addrs = getLocalAddresses(); MutableSet<InetAddress> candidates = new MutableSet<>(); if (prefer127) { candidates.addIfNotNull(addrs.get("127.0.0.1")); } + if (preferIpV4) { + candidates.addAll(Iterables.filter(addrs.values(), Inet4Address.class)); + } candidates.addAll(addrs.values()); if (checkReachable) { for (InetAddress a: candidates) { @@ -589,7 +599,7 @@ public class Networking { if (timeout>0) { s.setSoTimeout(timeout); } - s.connect(new InetSocketAddress(endpoint.getHostText(), endpoint.getPort())); + s.connect(new InetSocketAddress(endpoint.getHostText(), endpoint.getPort()), timeout); closeQuietly(s); return true; } catch (Exception e) {
