--- a/jdk/make/sun/net/FILES_java.gmk Thu Mar 17 17:16:35 2011 -0700
+++ b/jdk/make/sun/net/FILES_java.gmk Thu Mar 17 18:26:50 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
sun/net/ProgressListener.java \
sun/net/ProgressMeteringPolicy.java \
sun/net/SocksProxy.java \
+ sun/net/ResourceManager.java \
sun/net/TelnetInputStream.java \
sun/net/TelnetOutputStream.java \
sun/net/TelnetProtocolException.java \
--- a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Thu Mar 17 17:16:35 2011 -0700
+++ b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Thu Mar 17 18:26:50 2011 -0700
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.Enumeration;
+import sun.net.ResourceManager;
/**
* Abstract datagram and multicast socket implementation base class.
@@ -66,7 +67,14 @@
*/
protected synchronized void create() throws SocketException {
fd = new FileDescriptor();
- datagramSocketCreate();
+ ResourceManager.beforeUdpCreate();
+ try {
+ datagramSocketCreate();
+ } catch (SocketException ioe) {
+ ResourceManager.afterUdpClose();
+ fd = null;
+ throw ioe;
+ }
}
/**
@@ -211,6 +219,7 @@
protected void close() {
if (fd != null) {
datagramSocketClose();
+ ResourceManager.afterUdpClose();
fd = null;
}
}
--- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java Thu Mar 17 17:16:35 2011 -0700
+++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java Thu Mar 17 18:26:50 2011 -0700
@@ -32,6 +32,7 @@
import sun.net.ConnectionResetException;
import sun.net.NetHooks;
+import sun.net.ResourceManager;
/**
* Default Socket Implementation. This implementation does
@@ -68,6 +69,10 @@
private int resetState;
private final Object resetLock = new Object();
+ /* whether this Socket is a stream (TCP) socket or not (UDP)
+ */
+ private boolean stream;
+
/**
* Load net library into runtime.
*/
@@ -82,7 +87,19 @@
*/
protected synchronized void create(boolean stream) throws IOException {
fd = new FileDescriptor();
- socketCreate(stream);
+ this.stream = stream;
+ if (!stream) {
+ ResourceManager.beforeUdpCreate();
+ try {
+ socketCreate(false);
+ } catch (IOException ioe) {
+ ResourceManager.afterUdpClose();
+ fd = null;
+ throw ioe;
+ }
+ } else {
+ socketCreate(true);
+ }
if (socket != null)
socket.setCreated();
if (serverSocket != null)
@@ -479,6 +496,9 @@
protected void close() throws IOException {
synchronized(fdLock) {
if (fd != null) {
+ if (!stream) {
+ ResourceManager.afterUdpClose();
+ }
if (fdUseCount == 0) {
if (closePending) {
return;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/net/ResourceManager.java Thu Mar 17 18:26:50 2011 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.net;
+
+import java.net.SocketException;
+import java.util.concurrent.atomic.AtomicInteger;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Manages count of total number of UDP sockets and ensures
+ * that exception is thrown if we try to create more than the
+ * configured limit.
+ *
+ * This functionality could be put in NetHooks some time in future.
+ */
+
+public class ResourceManager {
+
+ /* default maximum number of udp sockets per VM
+ * when a security manager is enabled.
+ * The default is 1024 which is high enough to be useful
+ * but low enough to be well below the maximum number
+ * of port numbers actually available on all OSes for
+ * such sockets (5000 on some versions of windows)
+ */
+
+ private static final int DEFAULT_MAX_SOCKETS = 1024;
+ private static final int maxSockets;
+ private static final AtomicInteger numSockets;
+
+ static {
+ String prop = java.security.AccessController.doPrivileged(
+ new GetPropertyAction("sun.net.maxDatagramSockets")
+ );
+ int defmax = DEFAULT_MAX_SOCKETS;
+ try {
+ if (prop != null) {
+ defmax = Integer.parseInt(prop);
+ }
+ } catch (NumberFormatException e) {}
+ maxSockets = defmax;
+ numSockets = new AtomicInteger(0);
+ }
+
+ public static void beforeUdpCreate() throws SocketException {
+ if (System.getSecurityManager() != null) {
+ if (numSockets.incrementAndGet() > maxSockets) {
+ numSockets.decrementAndGet();
+ throw new SocketException("maximum number of DatagramSockets reached");
+ }
+ }
+ }
+
+ public static void afterUdpClose() {
+ if (System.getSecurityManager() != null) {
+ numSockets.decrementAndGet();
+ }
+ }
+}
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 17 17:16:35 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 17 18:26:50 2011 -0700
@@ -32,6 +32,7 @@
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
+import sun.net.ResourceManager;
/**
@@ -101,14 +102,22 @@
throws IOException
{
super(sp);
- this.family = Net.isIPv6Available() ?
- StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
- this.fd = Net.socket(family, false);
- this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_UNCONNECTED;
+ ResourceManager.beforeUdpCreate();
+ try {
+ this.family = Net.isIPv6Available() ?
+ StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
+ this.fd = Net.socket(family, false);
+ this.fdVal = IOUtil.fdVal(fd);
+ this.state = ST_UNCONNECTED;
+ } catch (IOException ioe) {
+ ResourceManager.afterUdpClose();
+ throw ioe;
+ }
}
- public DatagramChannelImpl(SelectorProvider sp, ProtocolFamily family) {
+ public DatagramChannelImpl(SelectorProvider sp, ProtocolFamily family)
+ throws IOException
+ {
super(sp);
if ((family != StandardProtocolFamily.INET) &&
(family != StandardProtocolFamily.INET6))
@@ -957,6 +966,7 @@
protected void implCloseSelectableChannel() throws IOException {
synchronized (stateLock) {
nd.preClose(fd);
+ ResourceManager.afterUdpClose();
// if member of mulitcast group then invalidate all keys
if (registry != null)
--- a/jdk/src/share/classes/sun/nio/ch/Net.java Thu Mar 17 17:16:35 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/Net.java Thu Mar 17 18:26:50 2011 -0700
@@ -312,11 +312,12 @@
private static native boolean canJoin6WithIPv4Group0();
- static FileDescriptor socket(boolean stream) {
+ static FileDescriptor socket(boolean stream) throws IOException {
return socket(UNSPEC, stream);
}
- static FileDescriptor socket(ProtocolFamily family, boolean stream) {
+ static FileDescriptor socket(ProtocolFamily family, boolean stream)
+ throws IOException {
boolean preferIPv6 = isIPv6Available() &&
(family != StandardProtocolFamily.INET);
return IOUtil.newFD(socket0(preferIPv6, stream, false));