This commit is contained in:
Daniel D. Daugherty 2017-08-03 09:10:56 -07:00
commit d1c91a64c6
2 changed files with 45 additions and 9 deletions

View File

@ -275,6 +275,12 @@ public class SocketTransportService extends TransportService {
sa = new InetSocketAddress(localaddress, port); sa = new InetSocketAddress(localaddress, port);
} }
ServerSocket ss = new ServerSocket(); ServerSocket ss = new ServerSocket();
if (port == 0) {
// Only need SO_REUSEADDR if we're using a fixed port. If we
// start seeing EADDRINUSE due to collisions in free ports
// then we should retry the bind() a few times.
ss.setReuseAddress(false);
}
ss.bind(sa); ss.bind(sa);
return new SocketListenKey(ss); return new SocketListenKey(ss);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -119,8 +119,26 @@ getLastError() {
return (char *)dbgsysTlsGet(tlsIndex); return (char *)dbgsysTlsGet(tlsIndex);
} }
/* Set options common to client and server sides */
static jdwpTransportError static jdwpTransportError
setOptions(int fd) setOptionsCommon(int fd)
{
jvalue dontcare;
int err;
dontcare.i = 0; /* keep compiler happy */
err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare);
if (err < 0) {
RETURN_IO_ERROR("setsockopt TCPNODELAY failed");
}
return JDWPTRANSPORT_ERROR_NONE;
}
/* Set the SO_REUSEADDR option */
static jdwpTransportError
setReuseAddrOption(int fd)
{ {
jvalue dontcare; jvalue dontcare;
int err; int err;
@ -132,11 +150,6 @@ setOptions(int fd)
RETURN_IO_ERROR("setsockopt SO_REUSEADDR failed"); RETURN_IO_ERROR("setsockopt SO_REUSEADDR failed");
} }
err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare);
if (err < 0) {
RETURN_IO_ERROR("setsockopt TCPNODELAY failed");
}
return JDWPTRANSPORT_ERROR_NONE; return JDWPTRANSPORT_ERROR_NONE;
} }
@ -350,10 +363,21 @@ socketTransport_startListening(jdwpTransportEnv* env, const char* address,
RETURN_IO_ERROR("socket creation failed"); RETURN_IO_ERROR("socket creation failed");
} }
err = setOptions(serverSocketFD); err = setOptionsCommon(serverSocketFD);
if (err) { if (err) {
return err; return err;
} }
if (sa.sin_port != 0) {
/*
* Only need SO_REUSEADDR if we're using a fixed port. If we
* start seeing EADDRINUSE due to collisions in free ports
* then we should retry the dbgsysBind() a few times.
*/
err = setReuseAddrOption(serverSocketFD);
if (err) {
return err;
}
}
err = dbgsysBind(serverSocketFD, (struct sockaddr *)&sa, sizeof(sa)); err = dbgsysBind(serverSocketFD, (struct sockaddr *)&sa, sizeof(sa));
if (err < 0) { if (err < 0) {
@ -510,11 +534,17 @@ socketTransport_attach(jdwpTransportEnv* env, const char* addressString, jlong a
RETURN_IO_ERROR("unable to create socket"); RETURN_IO_ERROR("unable to create socket");
} }
err = setOptions(socketFD); err = setOptionsCommon(socketFD);
if (err) { if (err) {
return err; return err;
} }
/*
* We don't call setReuseAddrOption() for the non-server socket
* case. If we start seeing EADDRINUSE due to collisions in free
* ports then we should retry the dbgsysConnect() a few times.
*/
/* /*
* To do a timed connect we make the socket non-blocking * To do a timed connect we make the socket non-blocking
* and poll with a timeout; * and poll with a timeout;