Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'openjdk/java/net/net_util_md.java')
-rw-r--r--openjdk/java/net/net_util_md.java59
1 files changed, 52 insertions, 7 deletions
diff --git a/openjdk/java/net/net_util_md.java b/openjdk/java/net/net_util_md.java
index d9132359..724ba4cc 100644
--- a/openjdk/java/net/net_util_md.java
+++ b/openjdk/java/net/net_util_md.java
@@ -271,6 +271,17 @@ final class net_util_md
optval = tos;
}
+ if (optname == SO_REUSEADDR) {
+ /*
+ * Do not set SO_REUSEADDE if SO_EXCLUSIVEADDUSE is already set
+ */
+ int[] parg = new int[1];
+ rv = NET_GetSockOpt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, parg);
+ if (rv == 0 && parg[0] == 1) {
+ return rv;
+ }
+ }
+
rv = setsockopt(s, level, optname, optval);
if (rv == SOCKET_ERROR) {
@@ -330,6 +341,18 @@ final class net_util_md
}
/*
+ * Sets SO_ECLUSIVEADDRUSE if SO_REUSEADDR is not already set.
+ */
+ static void setExclusiveBind(cli.System.Net.Sockets.Socket fd) {
+ int[] parg = new int[1];
+ int rv = 0;
+ rv = NET_GetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, parg);
+ if (rv == 0 && parg[0] == 0) {
+ rv = NET_SetSockOpt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
+ }
+ }
+
+ /*
* Wrapper for bind winsock call - transparent converts an
* error related to binding to a port that has exclusive access
* into an error indicating the port is in use (facilitates
@@ -337,7 +360,8 @@ final class net_util_md
*/
static int NET_Bind(cli.System.Net.Sockets.Socket s, SOCKETADDRESS him)
{
- int rv = bind(s, him);
+ int rv;
+ rv = bind(s, him);
if (rv == SOCKET_ERROR) {
/*
@@ -352,6 +376,17 @@ final class net_util_md
return rv;
}
+ /*
+ * Wrapper for NET_Bind call. Sets SO_EXCLUSIVEADDRUSE
+ * if required, and then calls NET_BIND
+ */
+ static int NET_WinBind(cli.System.Net.Sockets.Socket s, SOCKETADDRESS him, boolean exclBind)
+ {
+ if (exclBind == JNI_TRUE)
+ setExclusiveBind(s);
+ return NET_Bind(s, him);
+ }
+
static int NET_SocketClose(cli.System.Net.Sockets.Socket fd) {
linger l = new linger();
int ret;
@@ -470,7 +505,7 @@ final class net_util_md
return SOCKET_ERROR;
}
- static int NET_BindV6(ipv6bind b) {
+ static int NET_BindV6(ipv6bind b, boolean exclBind) {
cli.System.Net.Sockets.Socket fd = null;
cli.System.Net.Sockets.Socket ofd = null;
int rv;
@@ -487,7 +522,7 @@ final class net_util_md
if (family == AF_INET && (b.addr.him4.sin_addr.s_addr != INADDR_ANY)) {
/* bind to v4 only */
int ret;
- ret = NET_Bind (b.ipv4_fd, b.addr);
+ ret = NET_WinBind (b.ipv4_fd, b.addr, exclBind);
if (ret == SOCKET_ERROR) {
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
}
@@ -498,7 +533,7 @@ final class net_util_md
if (family == AF_INET6 && (!IN6ADDR_ISANY(b.addr))) {
/* bind to v6 only */
int ret;
- ret = NET_Bind (b.ipv6_fd, b.addr);
+ ret = NET_WinBind (b.ipv6_fd, b.addr, exclBind);
if (ret == SOCKET_ERROR) {
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
}
@@ -523,7 +558,7 @@ final class net_util_md
oaddr.set(new IPEndPoint(IPAddress.Any, htons(port)));
}
- rv = NET_Bind (fd, b.addr);
+ rv = NET_WinBind (fd, b.addr, exclBind);
if (rv == SOCKET_ERROR) {
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
}
@@ -568,7 +603,8 @@ final class net_util_md
/* bind random port on first socket */
oaddr.sin_port = 0;
- rv = NET_Bind (ofd, oaddr);
+ rv = NET_WinBind (ofd, oaddr,
+ exclBind);
if (rv == SOCKET_ERROR) {
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
}
@@ -583,7 +619,8 @@ final class net_util_md
}
bound_port = oaddr.sin_port;
b.addr.sin_port = bound_port;
- rv = NET_Bind (fd, b.addr);
+ rv = NET_WinBind (fd, b.addr,
+ exclBind);
if (rv != SOCKET_ERROR) {
if (family == AF_INET) {
@@ -836,4 +873,12 @@ final class net_util_md
}
return sock;
}
+
+ static int getInetAddress_addr(JNIEnv env, InetAddress iaObj) {
+ return iaObj.address;
+ }
+
+ static int getInetAddress_family(JNIEnv env, InetAddress iaObj) {
+ return iaObj.family;
+ }
}