Skip to content

Commit 0c03754

Browse files
committed
Simplify filtering addresses on interfaces (#41758)
This commit is a refactoring of how we filter addresses on interfaces. In particular, we refactor all of these methods into a common private method. We also change the order of logic to first check if an address matches our filter and then check if the interface is up. This is to possibly avoid problems we are seeing where devices are flapping up and down while we are checking for loopback addresses. We do not expect the loopback device to flap up and down so by reversing the logic here we avoid that problem on CI machines. Finally, we expand the error message when this does occur so that we know which device is flapping.
1 parent 8a28c8d commit 0c03754

File tree

3 files changed

+37
-60
lines changed

3 files changed

+37
-60
lines changed

server/src/main/java/org/elasticsearch/common/network/NetworkUtils.java

Lines changed: 34 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.apache.lucene.util.BytesRef;
2323
import org.apache.lucene.util.Constants;
2424

25+
import java.io.IOException;
2526
import java.net.Inet4Address;
2627
import java.net.Inet6Address;
2728
import java.net.InetAddress;
@@ -33,6 +34,7 @@
3334
import java.util.Comparator;
3435
import java.util.List;
3536
import java.util.Optional;
37+
import java.util.function.Predicate;
3638

3739
/**
3840
* Utilities for network interfaces / addresses binding and publishing.
@@ -150,77 +152,53 @@ public static boolean defaultReuseAddress() {
150152
return Constants.WINDOWS ? false : true;
151153
}
152154

153-
/** Returns all interface-local scope (loopback) addresses for interfaces that are up. */
154-
static InetAddress[] getLoopbackAddresses() throws SocketException {
155-
List<InetAddress> list = new ArrayList<>();
156-
for (NetworkInterface intf : getInterfaces()) {
157-
if (intf.isUp()) {
158-
for (InetAddress address : Collections.list(intf.getInetAddresses())) {
159-
if (address.isLoopbackAddress()) {
160-
list.add(address);
161-
}
155+
private static InetAddress[] filterAllAddresses(final Predicate<InetAddress> predicate, final String message) throws IOException {
156+
final List<NetworkInterface> interfaces = getInterfaces();
157+
final List<InetAddress> list = new ArrayList<>();
158+
for (final NetworkInterface intf : interfaces) {
159+
for (final InetAddress address : Collections.list(intf.getInetAddresses())) {
160+
if (predicate.test(address) && isUp(intf)) {
161+
list.add(address);
162162
}
163163
}
164164
}
165165
if (list.isEmpty()) {
166-
throw new IllegalArgumentException("No up-and-running loopback addresses found, got " + getInterfaces());
166+
throw new IllegalArgumentException(message + ", got " + interfaces);
167+
}
168+
return list.toArray(new InetAddress[0]);
169+
}
170+
171+
private static boolean isUp(final NetworkInterface intf) throws IOException {
172+
try {
173+
return intf.isUp();
174+
} catch (final SocketException e) {
175+
throw new IOException("failed to check if interface [" + intf.getName() + "] is up", e);
167176
}
168-
return list.toArray(new InetAddress[list.size()]);
177+
}
178+
179+
/** Returns all interface-local scope (loopback) addresses for interfaces that are up. */
180+
static InetAddress[] getLoopbackAddresses() throws IOException {
181+
return filterAllAddresses(InetAddress::isLoopbackAddress, "no up-and-running loopback addresses found");
169182
}
170183

171184
/** Returns all site-local scope (private) addresses for interfaces that are up. */
172-
static InetAddress[] getSiteLocalAddresses() throws SocketException {
173-
List<InetAddress> list = new ArrayList<>();
174-
for (NetworkInterface intf : getInterfaces()) {
175-
if (intf.isUp()) {
176-
for (InetAddress address : Collections.list(intf.getInetAddresses())) {
177-
if (address.isSiteLocalAddress()) {
178-
list.add(address);
179-
}
180-
}
181-
}
182-
}
183-
if (list.isEmpty()) {
184-
throw new IllegalArgumentException("No up-and-running site-local (private) addresses found, got " + getInterfaces());
185-
}
186-
return list.toArray(new InetAddress[list.size()]);
185+
static InetAddress[] getSiteLocalAddresses() throws IOException {
186+
return filterAllAddresses(InetAddress::isSiteLocalAddress, "No up-and-running site-local (private) addresses found");
187187
}
188188

189189
/** Returns all global scope addresses for interfaces that are up. */
190-
static InetAddress[] getGlobalAddresses() throws SocketException {
191-
List<InetAddress> list = new ArrayList<>();
192-
for (NetworkInterface intf : getInterfaces()) {
193-
if (intf.isUp()) {
194-
for (InetAddress address : Collections.list(intf.getInetAddresses())) {
195-
if (address.isLoopbackAddress() == false &&
196-
address.isSiteLocalAddress() == false &&
197-
address.isLinkLocalAddress() == false) {
198-
list.add(address);
199-
}
200-
}
201-
}
202-
}
203-
if (list.isEmpty()) {
204-
throw new IllegalArgumentException("No up-and-running global-scope (public) addresses found, got " + getInterfaces());
205-
}
206-
return list.toArray(new InetAddress[list.size()]);
190+
static InetAddress[] getGlobalAddresses() throws IOException {
191+
return filterAllAddresses(
192+
address -> address.isLoopbackAddress() == false
193+
&& address.isSiteLocalAddress() == false
194+
&& address.isLinkLocalAddress() == false,
195+
"no up-and-running global-scope (public) addresses found");
207196
}
208197

209198
/** Returns all addresses (any scope) for interfaces that are up.
210199
* This is only used to pick a publish address, when the user set network.host to a wildcard */
211-
static InetAddress[] getAllAddresses() throws SocketException {
212-
List<InetAddress> list = new ArrayList<>();
213-
for (NetworkInterface intf : getInterfaces()) {
214-
if (intf.isUp()) {
215-
for (InetAddress address : Collections.list(intf.getInetAddresses())) {
216-
list.add(address);
217-
}
218-
}
219-
}
220-
if (list.isEmpty()) {
221-
throw new IllegalArgumentException("No up-and-running addresses found, got " + getInterfaces());
222-
}
223-
return list.toArray(new InetAddress[list.size()]);
200+
static InetAddress[] getAllAddresses() throws IOException {
201+
return filterAllAddresses(address -> true, "no up-and-running addresses found");
224202
}
225203

226204
/** Returns addresses for the given interface (it must be marked up) */

x-pack/plugin/core/src/main/java/org/elasticsearch/common/network/InetAddressHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
*/
66
package org.elasticsearch.common.network;
77

8+
import java.io.IOException;
89
import java.net.InetAddress;
9-
import java.net.SocketException;
1010

1111
/**
1212
* We use this class to access the package private method in NetworkUtils to resolve anyLocalAddress InetAddresses for certificate
@@ -16,7 +16,7 @@ public class InetAddressHelper {
1616

1717
private InetAddressHelper() {}
1818

19-
public static InetAddress[] getAllAddresses() throws SocketException {
19+
public static InetAddress[] getAllAddresses() throws IOException {
2020
return NetworkUtils.getAllAddresses();
2121
}
2222

x-pack/plugin/security/cli/src/main/java/org/elasticsearch/xpack/security/cli/CertGenUtils.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import java.io.IOException;
4545
import java.math.BigInteger;
4646
import java.net.InetAddress;
47-
import java.net.SocketException;
4847
import java.security.KeyPair;
4948
import java.security.KeyPairGenerator;
5049
import java.security.KeyStore;
@@ -266,7 +265,7 @@ public static KeyPair generateKeyPair(int keysize) throws NoSuchAlgorithmExcepti
266265
/**
267266
* Converts the {@link InetAddress} objects into a {@link GeneralNames} object that is used to represent subject alternative names.
268267
*/
269-
public static GeneralNames getSubjectAlternativeNames(boolean resolveName, Set<InetAddress> addresses) throws SocketException {
268+
public static GeneralNames getSubjectAlternativeNames(boolean resolveName, Set<InetAddress> addresses) throws IOException {
270269
Set<GeneralName> generalNameList = new HashSet<>();
271270
for (InetAddress address : addresses) {
272271
if (address.isAnyLocalAddress()) {

0 commit comments

Comments
 (0)