Include source IP address in socket timeout exceptions
... to help debuggability.
Bug: 25488386
Test: CtsLibcoreTestCases
Change-Id: I2e9844ad9a3895f6c1463f32f1318146a8f8c468
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index 4568668..f5177fd 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -123,7 +123,8 @@
try {
connectErrno(fd, inetAddress, port, timeoutMs);
} catch (ErrnoException errnoException) {
- throw new ConnectException(connectDetail(inetAddress, port, timeoutMs, errnoException), errnoException);
+ throw new ConnectException(connectDetail(fd, inetAddress, port, timeoutMs,
+ errnoException), errnoException);
} catch (SocketException ex) {
throw ex; // We don't want to doubly wrap these.
} catch (SocketTimeoutException ex) {
@@ -169,21 +170,44 @@
remainingTimeoutMs =
(int) TimeUnit.NANOSECONDS.toMillis(finishTimeNanos - System.nanoTime());
if (remainingTimeoutMs <= 0) {
- throw new SocketTimeoutException(connectDetail(inetAddress, port, timeoutMs, null));
+ throw new SocketTimeoutException(connectDetail(fd, inetAddress, port, timeoutMs,
+ null));
}
} while (!IoBridge.isConnected(fd, inetAddress, port, timeoutMs, remainingTimeoutMs));
IoUtils.setBlocking(fd, true); // 4. set the socket back to blocking.
}
- private static String connectDetail(InetAddress inetAddress, int port, int timeoutMs, ErrnoException cause) {
- String detail = "failed to connect to " + inetAddress + " (port " + port + ")";
+ private static String connectDetail(FileDescriptor fd, InetAddress inetAddress, int port,
+ int timeoutMs, Exception cause) {
+ // Figure out source address from fd.
+ InetSocketAddress localAddress = null;
+ try {
+ localAddress = getLocalInetSocketAddress(fd);
+ } catch (SocketException ignored) { }
+
+ StringBuilder sb = new StringBuilder("failed to connect")
+ .append(" to ")
+ .append(inetAddress)
+ .append(" (port ")
+ .append(port)
+ .append(")");
+ if (localAddress != null) {
+ sb.append(" from ")
+ .append(localAddress.getAddress())
+ .append(" (port ")
+ .append(localAddress.getPort())
+ .append(")");
+ }
if (timeoutMs > 0) {
- detail += " after " + timeoutMs + "ms";
+ sb.append(" after ")
+ .append(timeoutMs)
+ .append("ms");
}
if (cause != null) {
- detail += ": " + cause.getMessage();
+ sb.append(": ")
+ .append(cause.getMessage());
}
- return detail;
+ return sb.toString();
}
/**
@@ -230,7 +254,7 @@
}
cause = errnoException;
}
- String detail = connectDetail(inetAddress, port, timeoutMs, cause);
+ String detail = connectDetail(fd, inetAddress, port, timeoutMs, cause);
if (cause.errno == ETIMEDOUT) {
throw new SocketTimeoutException(detail, cause);
}
@@ -621,21 +645,9 @@
}
}
- public static InetAddress getSocketLocalAddress(FileDescriptor fd) throws SocketException {
+ public static InetSocketAddress getLocalInetSocketAddress(FileDescriptor fd) throws SocketException {
try {
- SocketAddress sa = Libcore.os.getsockname(fd);
- InetSocketAddress isa = (InetSocketAddress) sa;
- return isa.getAddress();
- } catch (ErrnoException errnoException) {
- throw errnoException.rethrowAsSocketException();
- }
- }
-
- public static int getSocketLocalPort(FileDescriptor fd) throws SocketException {
- try {
- SocketAddress sa = Libcore.os.getsockname(fd);
- InetSocketAddress isa = (InetSocketAddress) sa;
- return isa.getPort();
+ return (InetSocketAddress) Libcore.os.getsockname(fd);
} catch (ErrnoException errnoException) {
throw errnoException.rethrowAsSocketException();
}
diff --git a/ojluni/src/main/java/java/net/Inet6AddressImpl.java b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
index 89da59a..0331ecf 100644
--- a/ojluni/src/main/java/java/net/Inet6AddressImpl.java
+++ b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
@@ -242,7 +242,7 @@
packet = StructIcmpHdr.IcmpEchoHdr(isIPv4, seq).getBytes();
IoBridge.sendto(fd, packet, 0, packet.length, 0, addr, 0);
- final int icmpId = IoBridge.getSocketLocalPort(fd);
+ final int icmpId = IoBridge.getLocalInetSocketAddress(fd).getPort();
byte[] received = new byte[packet.length];
DatagramPacket receivedPacket = new DatagramPacket(received, packet.length);