diff options
Diffstat (limited to 'external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java')
-rw-r--r-- | external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java | 52 |
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(); } |