diff options
Diffstat (limited to 'openjdk/java/net/net_util_md.java')
-rw-r--r-- | openjdk/java/net/net_util_md.java | 59 |
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; + } } |