More robust localhost resolution

Ensure the resolved localhost can be bound and connected actually
This commit is contained in:
Trustin Lee 2012-11-10 08:45:07 +09:00
parent b4f796c5e3
commit 0b30bf613d
2 changed files with 54 additions and 20 deletions

View File

@ -20,10 +20,13 @@ import io.netty.logging.InternalLoggerFactory;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
/**
@ -60,30 +63,26 @@ public final class NetworkConstants {
static {
//Start the process of discovering localhost
InetAddress localhost = null;
InetAddress localhost;
try {
//Let's start by getting localhost automatically
localhost = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
//No? That's okay.
validateHost(localhost);
} catch (IOException e) {
// The default local host names did not work. Try hard-coded IPv4 address.
try {
//Try to force an IPv4 localhost address
localhost = InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 });
} catch (UnknownHostException e1) {
//No? Okay. You must be using IPv6
validateHost(localhost);
} catch (IOException e1) {
// The hard-coded IPv4 address did not work. Try hard coded IPv6 address.
try {
//Try to force an IPv6 localhost address
localhost = InetAddress.getByAddress(
new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 });
} catch (UnknownHostException e2) {
//No? Okay.
logger.error("Failed to resolve localhost - Incorrect network configuration?", e2);
localhost = InetAddress.getByAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 });
validateHost(localhost);
} catch (IOException e2) {
throw new Error("Failed to resolve localhost - incorrect network configuration?", e2);
}
}
}
//Set the localhost constant
LOCALHOST = localhost;
//Prepare to get the local NetworkInterface
@ -143,6 +142,41 @@ public final class NetworkConstants {
SOMAXCONN = somaxconn;
}
private static void validateHost(InetAddress host) throws IOException {
ServerSocket ss = null;
Socket s1 = null;
Socket s2 = null;
try {
ss = new ServerSocket();
ss.setReuseAddress(false);
ss.bind(new InetSocketAddress(host, 0));
s1 = new Socket(host, ss.getLocalPort());
s2 = ss.accept();
} finally {
if (s2 != null) {
try {
s2.close();
} catch (IOException e) {
// Ignore
}
}
if (s1 != null) {
try {
s1.close();
} catch (IOException e) {
// Ignore
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
// Ignore
}
}
}
}
/**
* A constructor to stop this class being constructed.
*/

View File

@ -30,7 +30,7 @@ public final class TestUtils {
private static final int NUM_CANDIDATES = END_PORT - START_PORT;
private static final List<Integer> PORTS = new ArrayList<Integer>();
private static Iterator<Integer> PORTS_ITERATOR;
private static Iterator<Integer> portIterator;
static {
for (int i = START_PORT; i < END_PORT; i ++) {
@ -40,10 +40,10 @@ public final class TestUtils {
}
private static int nextCandidatePort() {
if (PORTS_ITERATOR == null || !PORTS_ITERATOR.hasNext()) {
PORTS_ITERATOR = PORTS.iterator();
if (portIterator == null || !portIterator.hasNext()) {
portIterator = PORTS.iterator();
}
return PORTS_ITERATOR.next();
return portIterator.next();
}
/**