summaryrefslogtreecommitdiff
path: root/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java')
-rw-r--r--external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java52
1 files changed, 46 insertions, 6 deletions
diff --git a/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java b/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
index a119c4b7fe..2b2bde1b41 100644
--- a/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
+++ b/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
@@ -38,7 +38,6 @@ import sun.net.ResourceManager;
* during socket creation.
*
* @author Chris Hegarty
- * @author Jeroen Frijters
*/
class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
@@ -63,6 +62,22 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
*/
cli.System.Net.Sockets.Socket lastfd=null;
+ // true if this socket is exclusively bound
+ private final boolean exclusiveBind;
+
+ /*
+ * Set to true if SO_REUSEADDR is set after the socket is bound to
+ * indicate SO_REUSEADDR is being emulated
+ */
+ private boolean reuseAddressEmulated;
+
+ // emulates SO_REUSEADDR when exclusiveBind is true and socket is bound
+ private boolean isReuseAddress;
+
+ TwoStacksPlainDatagramSocketImpl(boolean exclBind) {
+ exclusiveBind = exclBind;
+ }
+
protected synchronized void create() throws SocketException {
fd1 = new FileDescriptor();
try {
@@ -81,6 +96,14 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
}
}
+ @Override
+ protected synchronized void bind0(int lport, InetAddress laddr)
+ throws SocketException
+ {
+ bind0(lport, laddr, exclusiveBind);
+
+ }
+
protected synchronized void receive(DatagramPacket p)
throws IOException {
try {
@@ -100,8 +123,24 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
return anyLocalBoundAddr;
}
return socketGetOption(optID);
- } else
+ } else if (optID == SO_REUSEADDR && reuseAddressEmulated) {
+ return isReuseAddress;
+ } else {
return super.getOption(optID);
+ }
+ }
+
+ protected void socketSetOption(int opt, Object val)
+ throws SocketException
+ {
+ if (opt == SO_REUSEADDR && exclusiveBind && localPort != 0) {
+ // socket already bound, emulate
+ reuseAddressEmulated = true;
+ isReuseAddress = (Boolean)val;
+ } else {
+ socketNativeSetOption(opt, val);
+ }
+
}
protected boolean isClosed() {
@@ -119,9 +158,10 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
/* Native methods */
- protected synchronized void bind0(int lport, InetAddress laddr) throws SocketException {
+ protected synchronized void bind0(int lport, InetAddress laddr,
+ boolean exclBind) throws SocketException {
ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.bind0(env, this, lport, laddr);
+ TwoStacksPlainDatagramSocketImpl_c.bind0(env, this, lport, laddr, exclBind);
env.ThrowPendingException();
}
@@ -199,9 +239,9 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
TwoStacksPlainDatagramSocketImpl_c.datagramSocketClose(this);
}
- protected void socketSetOption(int opt, Object val) throws SocketException {
+ protected void socketNativeSetOption(int opt, Object val) throws SocketException {
ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.socketSetOption(env, this, opt, val);
+ TwoStacksPlainDatagramSocketImpl_c.socketNativeSetOption(env, this, opt, val);
env.ThrowPendingException();
}