Deduplicate addresses from resolver.

In some cases this may contain duplicates, although its a misconfiguration,
lets not bind to multiple ports. Its no problem for us to dedup, this code
doesn't need to be huper-duper fast since its used only for logic around bind/publish
This commit is contained in:
Robert Muir 2015-08-19 12:06:54 -04:00
parent ca28acc373
commit ce120b9c71
1 changed files with 15 additions and 14 deletions

View File

@ -21,8 +21,6 @@ package org.elasticsearch.common.network;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Constants; import org.apache.lucene.util.Constants;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
@ -34,10 +32,12 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet;
import java.util.List; import java.util.List;
/** /**
* Utilities for network interfaces / addresses * Utilities for network interfaces / addresses binding and publishing.
* Its only intended for that purpose, not general purpose usage!!!!
*/ */
public abstract class NetworkUtils { public abstract class NetworkUtils {
@ -84,7 +84,7 @@ public abstract class NetworkUtils {
* @deprecated remove this when multihoming is really correct * @deprecated remove this when multihoming is really correct
*/ */
@Deprecated @Deprecated
private static void sortAddresses(List<InetAddress> list) { static void sortAddresses(List<InetAddress> list) {
Collections.sort(list, new Comparator<InetAddress>() { Collections.sort(list, new Comparator<InetAddress>() {
@Override @Override
public int compare(InetAddress left, InetAddress right) { public int compare(InetAddress left, InetAddress right) {
@ -97,8 +97,6 @@ public abstract class NetworkUtils {
}); });
} }
private final static ESLogger logger = Loggers.getLogger(NetworkUtils.class);
/** Return all interfaces (and subinterfaces) on the system */ /** Return all interfaces (and subinterfaces) on the system */
static List<NetworkInterface> getInterfaces() throws SocketException { static List<NetworkInterface> getInterfaces() throws SocketException {
List<NetworkInterface> all = new ArrayList<>(); List<NetworkInterface> all = new ArrayList<>();
@ -128,7 +126,7 @@ public abstract class NetworkUtils {
} }
/** Returns addresses for all loopback interfaces that are up. */ /** Returns addresses for all loopback interfaces that are up. */
public static InetAddress[] getLoopbackAddresses() throws SocketException { static InetAddress[] getLoopbackAddresses() throws SocketException {
List<InetAddress> list = new ArrayList<>(); List<InetAddress> list = new ArrayList<>();
for (NetworkInterface intf : getInterfaces()) { for (NetworkInterface intf : getInterfaces()) {
if (intf.isLoopback() && intf.isUp()) { if (intf.isLoopback() && intf.isUp()) {
@ -143,7 +141,7 @@ public abstract class NetworkUtils {
} }
/** Returns addresses for the first non-loopback interface that is up. */ /** Returns addresses for the first non-loopback interface that is up. */
public static InetAddress[] getFirstNonLoopbackAddresses() throws SocketException { static InetAddress[] getFirstNonLoopbackAddresses() throws SocketException {
List<InetAddress> list = new ArrayList<>(); List<InetAddress> list = new ArrayList<>();
for (NetworkInterface intf : getInterfaces()) { for (NetworkInterface intf : getInterfaces()) {
if (intf.isLoopback() == false && intf.isUp()) { if (intf.isLoopback() == false && intf.isUp()) {
@ -159,7 +157,7 @@ public abstract class NetworkUtils {
} }
/** Returns addresses for the given interface (it must be marked up) */ /** Returns addresses for the given interface (it must be marked up) */
public static InetAddress[] getAddressesForInterface(String name) throws SocketException { static InetAddress[] getAddressesForInterface(String name) throws SocketException {
NetworkInterface intf = NetworkInterface.getByName(name); NetworkInterface intf = NetworkInterface.getByName(name);
if (intf == null) { if (intf == null) {
throw new IllegalArgumentException("No interface named '" + name + "' found, got " + getInterfaces()); throw new IllegalArgumentException("No interface named '" + name + "' found, got " + getInterfaces());
@ -176,14 +174,17 @@ public abstract class NetworkUtils {
} }
/** Returns addresses for the given host, sorted by order of preference */ /** Returns addresses for the given host, sorted by order of preference */
public static InetAddress[] getAllByName(String host) throws UnknownHostException { static InetAddress[] getAllByName(String host) throws UnknownHostException {
InetAddress addresses[] = InetAddress.getAllByName(host); InetAddress addresses[] = InetAddress.getAllByName(host);
sortAddresses(Arrays.asList(addresses)); // deduplicate, in case of resolver misconfiguration
return addresses; // stuff like https://bugzilla.redhat.com/show_bug.cgi?id=496300
List<InetAddress> 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} */ /** Returns only the IPV4 addresses in {@code addresses} */
public static InetAddress[] filterIPV4(InetAddress addresses[]) { static InetAddress[] filterIPV4(InetAddress addresses[]) {
List<InetAddress> list = new ArrayList<>(); List<InetAddress> list = new ArrayList<>();
for (InetAddress address : addresses) { for (InetAddress address : addresses) {
if (address instanceof Inet4Address) { if (address instanceof Inet4Address) {
@ -197,7 +198,7 @@ public abstract class NetworkUtils {
} }
/** Returns only the IPV6 addresses in {@code addresses} */ /** Returns only the IPV6 addresses in {@code addresses} */
public static InetAddress[] filterIPV6(InetAddress addresses[]) { static InetAddress[] filterIPV6(InetAddress addresses[]) {
List<InetAddress> list = new ArrayList<>(); List<InetAddress> list = new ArrayList<>();
for (InetAddress address : addresses) { for (InetAddress address : addresses) {
if (address instanceof Inet6Address) { if (address instanceof Inet6Address) {