We have an applet that connects to our game server. Since two days we get complaints from our users about not being able to connect. I tracked the issue down to the following code:
System.err.println("<PO> creating socket host=" + host + ", port=" + port);
try {
socket = new Socket(host, port);
} catch (Throwable t) {
System.err.println("<PO> OOPS: " + t.getMessage());
t.printStackTrace();
}
System.err.println("<PO> socket created");
The output is as follows:
<PO> creating socket host=<host deleted>, port=7754
And then the applet just hangs (no cpu usage). No exception, but also no 'socket created' print! Note that this code has been running successfully for many years (without the prints and try/catch of course). With java 1.7 it still runs fine but with java 1.8.0_25 the code hangs.
Under what conditions can a "new Socket" call hang?
Does anyone have any suggestions on how to debug this issue further?
I have found the relevant system calls with strace:
socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 53
setsockopt(53, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0
fcntl(53, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(53, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(53, {sa_family=AF_INET6, sin6_port=htons(7754), inet_pton(AF_INET6, "::ffff:<server ip in v4 format>", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=53, events=POLLOUT}], 1, 120000) = 1 ([{fd=53, revents=POLLOUT}])
getsockopt(53, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
fcntl(53, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(53, F_SETFL, O_RDWR) = 0
getsockname(53, {sa_family=AF_INET6, sin6_port=htons(52535), inet_pton(AF_INET6, "::ffff:<client ip in v4 format>", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
setsockopt(53, SOL_TCP, TCP_NODELAY, [1], 4) = 0
I suspect the 'setsocketopt(... IPV6_V6ONLY ...)' call: the server is definitely IPV4 only! Any idea how to force Java to use IPv4 (or at least stop Java from using IPV6_V6ONLY)?