diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java
index 8eff70e7bd8f5..c42e95f6bdb82 100644
--- a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java
+++ b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java
@@ -28,6 +28,9 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
@@ -91,13 +94,21 @@ public void addCustomNameResolver(CustomNameResolver customNameResolver) {
customNameResolvers.add(customNameResolver);
}
- public InetAddress[] resolveBindHostAddress(String bindHost) throws IOException {
+ /**
+ * Resolves {@code bindHosts} to a list of internet addresses. The list will
+ * not contain duplicate addresses.
+ * @param bindHosts list of hosts to bind to. this may contain special pseudo-hostnames
+ * such as _local_ (see the documentation). if it is null, it will be populated
+ * based on global default settings.
+ * @return unique set of internet addresses
+ */
+ public InetAddress[] resolveBindHostAddresses(String bindHosts[]) throws IOException {
// first check settings
- if (bindHost == null) {
- bindHost = settings.get(GLOBAL_NETWORK_BINDHOST_SETTING, settings.get(GLOBAL_NETWORK_HOST_SETTING));
+ if (bindHosts == null) {
+ bindHosts = settings.getAsArray(GLOBAL_NETWORK_BINDHOST_SETTING, settings.getAsArray(GLOBAL_NETWORK_HOST_SETTING, null));
}
// next check any registered custom resolvers
- if (bindHost == null) {
+ if (bindHosts == null) {
for (CustomNameResolver customNameResolver : customNameResolvers) {
InetAddress addresses[] = customNameResolver.resolveDefault();
if (addresses != null) {
@@ -106,31 +117,44 @@ public InetAddress[] resolveBindHostAddress(String bindHost) throws IOException
}
}
// finally, fill with our default
- if (bindHost == null) {
- bindHost = DEFAULT_NETWORK_HOST;
+ if (bindHosts == null) {
+ bindHosts = new String[] { DEFAULT_NETWORK_HOST };
}
- InetAddress addresses[] = resolveInetAddress(bindHost);
+ InetAddress addresses[] = resolveInetAddresses(bindHosts);
// try to deal with some (mis)configuration
- if (addresses != null) {
- for (InetAddress address : addresses) {
- // check if its multicast: flat out mistake
- if (address.isMulticastAddress()) {
- throw new IllegalArgumentException("bind address: {" + NetworkAddress.format(address) + "} is invalid: multicast address");
- }
+ for (InetAddress address : addresses) {
+ // check if its multicast: flat out mistake
+ if (address.isMulticastAddress()) {
+ throw new IllegalArgumentException("bind address: {" + NetworkAddress.format(address) + "} is invalid: multicast address");
+ }
+ // check if its a wildcard address: this is only ok if its the only address!
+ if (address.isAnyLocalAddress() && addresses.length > 1) {
+ throw new IllegalArgumentException("bind address: {" + NetworkAddress.format(address) + "} is wildcard, but multiple addresses specified: this makes no sense");
}
}
return addresses;
}
+ /**
+ * Resolves {@code publishHosts} to a single publish address. The fact that it returns
+ * only one address is just a current limitation.
+ *
+ * If {@code publishHosts} resolves to more than one address, then one is selected with magic,
+ * and the user is warned (they can always just be more specific).
+ * @param publishHosts list of hosts to publish as. this may contain special pseudo-hostnames
+ * such as _local_ (see the documentation). if it is null, it will be populated
+ * based on global default settings.
+ * @return single internet address
+ */
// TODO: needs to be InetAddress[]
- public InetAddress resolvePublishHostAddress(String publishHost) throws IOException {
+ public InetAddress resolvePublishHostAddresses(String publishHosts[]) throws IOException {
// first check settings
- if (publishHost == null) {
- publishHost = settings.get(GLOBAL_NETWORK_PUBLISHHOST_SETTING, settings.get(GLOBAL_NETWORK_HOST_SETTING));
+ if (publishHosts == null) {
+ publishHosts = settings.getAsArray(GLOBAL_NETWORK_PUBLISHHOST_SETTING, settings.getAsArray(GLOBAL_NETWORK_HOST_SETTING, null));
}
// next check any registered custom resolvers
- if (publishHost == null) {
+ if (publishHosts == null) {
for (CustomNameResolver customNameResolver : customNameResolvers) {
InetAddress addresses[] = customNameResolver.resolveDefault();
if (addresses != null) {
@@ -139,30 +163,61 @@ public InetAddress resolvePublishHostAddress(String publishHost) throws IOExcept
}
}
// finally, fill with our default
- if (publishHost == null) {
- publishHost = DEFAULT_NETWORK_HOST;
+ if (publishHosts == null) {
+ publishHosts = new String[] { DEFAULT_NETWORK_HOST };
}
+ InetAddress addresses[] = resolveInetAddresses(publishHosts);
// TODO: allow publishing multiple addresses
- InetAddress address = resolveInetAddress(publishHost)[0];
+ // for now... the hack begins
- // try to deal with some (mis)configuration
- if (address != null) {
+ // 1. single wildcard address, probably set by network.host
+ if (addresses.length == 1 && addresses[0].isAnyLocalAddress()) {
+ InetAddress old = addresses[0];
+ addresses = resolveInetAddresses(new String[] { "_non_loopback_" });
+ logger.warn("publish address: {{}} is a wildcard address, falling back to _non_loopback_",
+ NetworkAddress.format(old));
+ }
+
+ // 2. try to deal with some (mis)configuration
+ for (InetAddress address : addresses) {
// check if its multicast: flat out mistake
if (address.isMulticastAddress()) {
throw new IllegalArgumentException("publish address: {" + NetworkAddress.format(address) + "} is invalid: multicast address");
}
- // wildcard address, probably set by network.host
+ // check if its a wildcard address: this is only ok if its the only address!
+ // (if it was a single wildcard address, it was replaced by step 1 above)
if (address.isAnyLocalAddress()) {
- InetAddress old = address;
- address = NetworkUtils.getFirstNonLoopbackAddresses()[0];
- logger.warn("publish address: {{}} is a wildcard address, falling back to first non-loopback: {{}}",
- NetworkAddress.format(old), NetworkAddress.format(address));
+ throw new IllegalArgumentException("publish address: {" + NetworkAddress.format(address) + "} is wildcard, but multiple addresses specified: this makes no sense");
}
}
- return address;
+
+ // 3. warn user if we end out with multiple publish addresses
+ if (addresses.length > 1) {
+ List sorted = new ArrayList<>(Arrays.asList(addresses));
+ NetworkUtils.sortAddresses(sorted);
+ addresses = new InetAddress[] { sorted.get(0) };
+ logger.warn("publish host: {} resolves to multiple addresses, auto-selecting {{}} as single publish address",
+ Arrays.toString(publishHosts), NetworkAddress.format(addresses[0]));
+ }
+ return addresses[0];
+ }
+
+ /** resolves (and deduplicates) host specification */
+ private InetAddress[] resolveInetAddresses(String hosts[]) throws UnknownHostException, IOException {
+ if (hosts.length == 0) {
+ throw new IllegalArgumentException("empty host specification");
+ }
+ // deduplicate, in case of resolver misconfiguration
+ // stuff like https://bugzilla.redhat.com/show_bug.cgi?id=496300
+ HashSet set = new HashSet<>();
+ for (String host : hosts) {
+ set.addAll(Arrays.asList(resolveInternal(host)));
+ }
+ return set.toArray(new InetAddress[set.size()]);
}
- private InetAddress[] resolveInetAddress(String host) throws UnknownHostException, IOException {
+ /** resolves a single host specification */
+ private InetAddress[] resolveInternal(String host) throws UnknownHostException, IOException {
if ((host.startsWith("#") && host.endsWith("#")) || (host.startsWith("_") && host.endsWith("_"))) {
host = host.substring(1, host.length() - 1);
// allow custom resolvers to have special names
@@ -198,6 +253,6 @@ private InetAddress[] resolveInetAddress(String host) throws UnknownHostExceptio
}
}
}
- return NetworkUtils.getAllByName(host);
+ return InetAddress.getAllByName(host);
}
}
diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkUtils.java b/core/src/main/java/org/elasticsearch/common/network/NetworkUtils.java
index 62bc91cfb85dd..371469492b10d 100644
--- a/core/src/main/java/org/elasticsearch/common/network/NetworkUtils.java
+++ b/core/src/main/java/org/elasticsearch/common/network/NetworkUtils.java
@@ -27,12 +27,10 @@
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashSet;
import java.util.List;
/**
@@ -109,7 +107,8 @@ static int sortKey(InetAddress address, boolean prefer_v6) {
* @deprecated remove this when multihoming is really correct
*/
@Deprecated
- static void sortAddresses(List list) {
+ // only public because of silly multicast
+ public static void sortAddresses(List list) {
Collections.sort(list, new Comparator() {
@Override
public int compare(InetAddress left, InetAddress right) {
@@ -161,7 +160,6 @@ static InetAddress[] getLoopbackAddresses() throws SocketException {
if (list.isEmpty()) {
throw new IllegalArgumentException("No up-and-running loopback interfaces found, got " + getInterfaces());
}
- sortAddresses(list);
return list.toArray(new InetAddress[list.size()]);
}
@@ -177,7 +175,6 @@ static InetAddress[] getFirstNonLoopbackAddresses() throws SocketException {
if (list.isEmpty()) {
throw new IllegalArgumentException("No up-and-running non-loopback interfaces found, got " + getInterfaces());
}
- sortAddresses(list);
return list.toArray(new InetAddress[list.size()]);
}
@@ -194,20 +191,9 @@ static InetAddress[] getAddressesForInterface(String name) throws SocketExceptio
if (list.isEmpty()) {
throw new IllegalArgumentException("Interface '" + name + "' has no internet addresses");
}
- sortAddresses(list);
return list.toArray(new InetAddress[list.size()]);
}
- /** Returns addresses for the given host, sorted by order of preference */
- static InetAddress[] getAllByName(String host) throws UnknownHostException {
- InetAddress addresses[] = InetAddress.getAllByName(host);
- // deduplicate, in case of resolver misconfiguration
- // stuff like https://bugzilla.redhat.com/show_bug.cgi?id=496300
- List unique = new ArrayList<>(new HashSet<>(Arrays.asList(addresses)));
- sortAddresses(unique);
- return unique.toArray(new InetAddress[unique.size()]);
- }
-
/** Returns only the IPV4 addresses in {@code addresses} */
static InetAddress[] filterIPV4(InetAddress addresses[]) {
List list = new ArrayList<>();
diff --git a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java
index a794f52dfaffe..3dbe3bf0df69a 100644
--- a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java
+++ b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java
@@ -50,6 +50,7 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
@@ -105,9 +106,9 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent boundAddresses = new ArrayList<>(hostAddresses.length);
@@ -262,7 +263,7 @@ protected void doStart() {
publishPort = boundAddress.getPort();
}
try {
- publishAddress = new InetSocketAddress(networkService.resolvePublishHostAddress(publishHost), publishPort);
+ publishAddress = new InetSocketAddress(networkService.resolvePublishHostAddresses(publishHosts), publishPort);
} catch (Exception e) {
throw new BindTransportException("Failed to resolve publish address", e);
}
diff --git a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java
index 5cf9ed31d32f4..f4319bb2cfd9a 100644
--- a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java
+++ b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java
@@ -343,9 +343,9 @@ public Map profileBoundAddresses() {
return ImmutableMap.copyOf(profileBoundAddresses);
}
- private InetSocketAddress createPublishAddress(String publishHost, int publishPort) {
+ private InetSocketAddress createPublishAddress(String publishHosts[], int publishPort) {
try {
- return new InetSocketAddress(networkService.resolvePublishHostAddress(publishHost), publishPort);
+ return new InetSocketAddress(networkService.resolvePublishHostAddresses(publishHosts), publishPort);
} catch (Exception e) {
throw new BindTransportException("Failed to resolve publish address", e);
}
@@ -436,11 +436,11 @@ private Settings createFallbackSettings() {
private void bindServerBootstrap(final String name, final Settings settings) {
// Bind and start to accept incoming connections.
InetAddress hostAddresses[];
- String bindHost = settings.get("bind_host");
+ String bindHosts[] = settings.getAsArray("bind_host", null);
try {
- hostAddresses = networkService.resolveBindHostAddress(bindHost);
+ hostAddresses = networkService.resolveBindHostAddresses(bindHosts);
} catch (IOException e) {
- throw new BindTransportException("Failed to resolve host [" + bindHost + "]", e);
+ throw new BindTransportException("Failed to resolve host " + Arrays.toString(bindHosts) + "", e);
}
if (logger.isDebugEnabled()) {
String[] addresses = new String[hostAddresses.length];
@@ -493,8 +493,8 @@ public boolean onPortNumber(int portNumber) {
if (boundTransportAddress == null) {
// no address is bound, so lets create one with the publish address information from the settings or the bound address as a fallback
int publishPort = profileSettings.getAsInt("publish_port", boundAddress.getPort());
- String publishHost = profileSettings.get("publish_host", boundAddress.getHostString());
- InetSocketAddress publishAddress = createPublishAddress(publishHost, publishPort);
+ String publishHosts[] = profileSettings.getAsArray("publish_host", new String[] { boundAddress.getHostString() });
+ InetSocketAddress publishAddress = createPublishAddress(publishHosts, publishPort);
profileBoundAddresses.put(name, new BoundTransportAddress(new TransportAddress[]{new InetSocketTransportAddress(boundAddress)}, new InetSocketTransportAddress(publishAddress)));
} else {
// TODO: support real multihoming with publishing. Today we update the bound addresses so only the prioritized address is published
@@ -511,8 +511,8 @@ public boolean onPortNumber(int portNumber) {
// these calls are different from the profile ones due to the way the settings for a profile are created. If we want to merge the code for the default profile and
// other profiles together, we need to change how the profileSettings are built for the default profile...
int publishPort = settings.getAsInt("transport.netty.publish_port", settings.getAsInt("transport.publish_port", boundAddress.getPort()));
- String publishHost = settings.get("transport.netty.publish_host", settings.get("transport.publish_host", settings.get("transport.host")));
- InetSocketAddress publishAddress = createPublishAddress(publishHost, publishPort);
+ String publishHosts[] = settings.getAsArray("transport.netty.publish_host", settings.getAsArray("transport.publish_host", settings.getAsArray("transport.host", null)));
+ InetSocketAddress publishAddress = createPublishAddress(publishHosts, publishPort);
this.boundAddress = new BoundTransportAddress(new TransportAddress[]{new InetSocketTransportAddress(boundAddress)}, new InetSocketTransportAddress(publishAddress));
} else {
// the default profile is already bound to one address and has the publish address, copy the existing bound addresses as is and append the new address.
diff --git a/core/src/test/java/org/elasticsearch/common/network/NetworkServiceTests.java b/core/src/test/java/org/elasticsearch/common/network/NetworkServiceTests.java
index 0a772907a8ca9..7be9547827b2d 100644
--- a/core/src/test/java/org/elasticsearch/common/network/NetworkServiceTests.java
+++ b/core/src/test/java/org/elasticsearch/common/network/NetworkServiceTests.java
@@ -23,6 +23,7 @@
import org.elasticsearch.test.ESTestCase;
import java.net.InetAddress;
+import java.util.Arrays;
/**
* Tests for network service... try to keep them safe depending upon configuration
@@ -36,7 +37,7 @@ public class NetworkServiceTests extends ESTestCase {
public void testBindMulticastV4() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
try {
- service.resolveBindHostAddress("239.1.1.1");
+ service.resolveBindHostAddresses(new String[] { "239.1.1.1" });
fail("should have hit exception");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("invalid: multicast"));
@@ -49,7 +50,7 @@ public void testBindMulticastV4() throws Exception {
public void testBindMulticastV6() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
try {
- service.resolveBindHostAddress("FF08::108");
+ service.resolveBindHostAddresses(new String[] { "FF08::108" });
fail("should have hit exception");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("invalid: multicast"));
@@ -62,7 +63,7 @@ public void testBindMulticastV6() throws Exception {
public void testPublishMulticastV4() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
try {
- service.resolvePublishHostAddress("239.1.1.1");
+ service.resolvePublishHostAddresses(new String[] { "239.1.1.1" });
fail("should have hit exception");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("invalid: multicast"));
@@ -75,7 +76,7 @@ public void testPublishMulticastV4() throws Exception {
public void testPublishMulticastV6() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
try {
- service.resolvePublishHostAddress("FF08::108");
+ service.resolvePublishHostAddresses(new String[] { "FF08::108" });
fail("should have hit exception");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("invalid: multicast"));
@@ -87,7 +88,7 @@ public void testPublishMulticastV6() throws Exception {
*/
public void testBindAnyLocalV4() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
- assertEquals(InetAddress.getByName("0.0.0.0"), service.resolveBindHostAddress("0.0.0.0")[0]);
+ assertEquals(InetAddress.getByName("0.0.0.0"), service.resolveBindHostAddresses(new String[] { "0.0.0.0" })[0]);
}
/**
@@ -95,36 +96,38 @@ public void testBindAnyLocalV4() throws Exception {
*/
public void testBindAnyLocalV6() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
- assertEquals(InetAddress.getByName("::"), service.resolveBindHostAddress("::")[0]);
+ assertEquals(InetAddress.getByName("::"), service.resolveBindHostAddresses(new String[] { "::" })[0]);
}
/**
* ensure specifying wildcard ipv4 address selects reasonable publish address
*/
public void testPublishAnyLocalV4() throws Exception {
- InetAddress expected = null;
+ InetAddress expected[] = null;
try {
- expected = NetworkUtils.getFirstNonLoopbackAddresses()[0];
+ expected = NetworkUtils.getFirstNonLoopbackAddresses();
} catch (Exception e) {
assumeNoException("test requires up-and-running non-loopback address", e);
}
+ NetworkUtils.sortAddresses(Arrays.asList(expected));
NetworkService service = new NetworkService(Settings.EMPTY);
- assertEquals(expected, service.resolvePublishHostAddress("0.0.0.0"));
+ assertEquals(expected[0], service.resolvePublishHostAddresses(new String[] { "0.0.0.0" }));
}
/**
* ensure specifying wildcard ipv6 address selects reasonable publish address
*/
public void testPublishAnyLocalV6() throws Exception {
- InetAddress expected = null;
+ InetAddress expected[] = null;
try {
- expected = NetworkUtils.getFirstNonLoopbackAddresses()[0];
+ expected = NetworkUtils.getFirstNonLoopbackAddresses();
} catch (Exception e) {
assumeNoException("test requires up-and-running non-loopback address", e);
}
+ NetworkUtils.sortAddresses(Arrays.asList(expected));
NetworkService service = new NetworkService(Settings.EMPTY);
- assertEquals(expected, service.resolvePublishHostAddress("::"));
+ assertEquals(expected[0], service.resolvePublishHostAddresses(new String[] { "::" }));
}
}
diff --git a/docs/reference/modules/network.asciidoc b/docs/reference/modules/network.asciidoc
index dc6aca718cdcb..a44b895ac4474 100644
--- a/docs/reference/modules/network.asciidoc
+++ b/docs/reference/modules/network.asciidoc
@@ -22,8 +22,8 @@ ordinary addresses are preferred to site-local or link-local addresses.
The `network.host` setting is a simple setting to automatically set both
`network.bind_host` and `network.publish_host` to the same host value.
-Both settings allows to be configured with either explicit host address
-or host name. The settings also accept logical setting values explained
+Both settings allows to be configured with either explicit host address(es)
+or host name(s). The settings also accept logical setting value(s) explained
in the following table:
[cols="<,<",options="header",]
diff --git a/plugins/cloud-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java b/plugins/cloud-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java
index 8feb9b8697cc7..476773dcc7316 100644
--- a/plugins/cloud-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java
+++ b/plugins/cloud-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java
@@ -110,7 +110,7 @@ public List buildDynamicNodes() {
cachedDiscoNodes = new ArrayList<>();
String ipAddress = null;
try {
- InetAddress inetAddress = networkService.resolvePublishHostAddress(null);
+ InetAddress inetAddress = networkService.resolvePublishHostAddresses(null);
if (inetAddress != null) {
ipAddress = NetworkAddress.formatAddress(inetAddress);
}
diff --git a/plugins/discovery-azure/src/main/java/org/elasticsearch/discovery/azure/AzureUnicastHostsProvider.java b/plugins/discovery-azure/src/main/java/org/elasticsearch/discovery/azure/AzureUnicastHostsProvider.java
index b2e6821e30d27..9f58b0bbb18d7 100644
--- a/plugins/discovery-azure/src/main/java/org/elasticsearch/discovery/azure/AzureUnicastHostsProvider.java
+++ b/plugins/discovery-azure/src/main/java/org/elasticsearch/discovery/azure/AzureUnicastHostsProvider.java
@@ -177,7 +177,7 @@ public List buildDynamicNodes() {
InetAddress ipAddress = null;
try {
- ipAddress = networkService.resolvePublishHostAddress(null);
+ ipAddress = networkService.resolvePublishHostAddresses(null);
logger.trace("ip of current node: [{}]", ipAddress);
} catch (IOException e) {
// We can't find the publish host address... Hmmm. Too bad :-(
diff --git a/plugins/discovery-multicast/pom.xml b/plugins/discovery-multicast/pom.xml
index eaa1e112f3413..5ffa5d0c5d6d5 100644
--- a/plugins/discovery-multicast/pom.xml
+++ b/plugins/discovery-multicast/pom.xml
@@ -19,6 +19,7 @@
1
discovery_multicast
false
+ -Xlint:-deprecation
diff --git a/plugins/discovery-multicast/src/main/java/org/elasticsearch/plugin/discovery/multicast/MulticastZenPing.java b/plugins/discovery-multicast/src/main/java/org/elasticsearch/plugin/discovery/multicast/MulticastZenPing.java
index 5b61787cdebd0..d21750fb6f5ae 100644
--- a/plugins/discovery-multicast/src/main/java/org/elasticsearch/plugin/discovery/multicast/MulticastZenPing.java
+++ b/plugins/discovery-multicast/src/main/java/org/elasticsearch/plugin/discovery/multicast/MulticastZenPing.java
@@ -33,6 +33,7 @@
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.network.NetworkService;
+import org.elasticsearch.common.network.NetworkUtils;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
@@ -47,7 +48,10 @@
import org.elasticsearch.transport.*;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.SocketAddress;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
@@ -130,11 +134,14 @@ protected void doStart() {
boolean shared = settings.getAsBoolean("discovery.zen.ping.multicast.shared", Constants.MAC_OS_X);
// OSX does not correctly send multicasts FROM the right interface
boolean deferToInterface = settings.getAsBoolean("discovery.zen.ping.multicast.defer_group_to_set_interface", Constants.MAC_OS_X);
+ // don't use publish address, the use case for that is e.g. a firewall or proxy and
+ // may not even be bound to an interface on this machine! use the first bound address.
+ List addresses = Arrays.asList(networkService.resolveBindHostAddresses(address == null ? null : new String[] { address }));
+ NetworkUtils.sortAddresses(addresses);
+
multicastChannel = MulticastChannel.getChannel(nodeName(), shared,
new MulticastChannel.Config(port, group, bufferSize, ttl,
- // don't use publish address, the use case for that is e.g. a firewall or proxy and
- // may not even be bound to an interface on this machine! use the first bound address.
- networkService.resolveBindHostAddress(address)[0],
+ addresses.get(0),
deferToInterface),
new Receiver());
} catch (Throwable t) {