diff options
Diffstat (limited to 'external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java')
| -rw-r--r-- | external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java | 37 | 
1 files changed, 30 insertions, 7 deletions
| diff --git a/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java b/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java index 4f35a6c6f6..a3584d8632 100644 --- a/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java +++ b/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java @@ -34,15 +34,25 @@ import java.io.FileDescriptor;   * single file descriptor.   *   * @author Chris Hegarty - * @author Jeroen Frijters   */  class DualStackPlainSocketImpl extends AbstractPlainSocketImpl  { -    public DualStackPlainSocketImpl() {} -    public DualStackPlainSocketImpl(FileDescriptor fd) { + +    // true if this socket is exclusively bound +    private final boolean exclusiveBind; + +    // emulates SO_REUSEADDR when exclusiveBind is true +    private boolean isReuseAddress; + +    public DualStackPlainSocketImpl(boolean exclBind) { +        exclusiveBind = exclBind; +    } + +    public DualStackPlainSocketImpl(FileDescriptor fd, boolean exclBind) {          this.fd = fd; +        exclusiveBind = exclBind;      }      void socketCreate(boolean stream) throws IOException { @@ -90,7 +100,7 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl          if (address == null)              throw new NullPointerException("inet address argument is null."); -        bind0(nativefd, address, port); +        bind0(nativefd, address, port, exclusiveBind);          if (port == 0) {              localport = localPort0(nativefd);          } else { @@ -158,6 +168,8 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl          shutdown0(nativefd, howto);      } +    // Intentional fallthrough after SO_REUSEADDR +    @SuppressWarnings("fallthrough")      void socketSetOption(int opt, boolean on, Object value)          throws SocketException {          cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); @@ -169,10 +181,16 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl          int optionValue = 0;          switch(opt) { +            case SO_REUSEADDR : +                if (exclusiveBind) { +                    // SO_REUSEADDR emulated when using exclusive bind +                    isReuseAddress = on; +                    return; +                } +                // intentional fallthrough              case TCP_NODELAY :              case SO_OOBINLINE :              case SO_KEEPALIVE : -            case SO_REUSEADDR :                  optionValue = on ? 1 : 0;                  break;              case SO_SNDBUF : @@ -203,6 +221,10 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl              return 0;  // return value doesn't matter.          } +        // SO_REUSEADDR emulated when using exclusive bind +        if (opt == SO_REUSEADDR && exclusiveBind) +            return isReuseAddress? 1 : -1; +          int value = getIntOption(nativefd, opt);          switch (opt) { @@ -238,10 +260,11 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl          return ret;      } -    static void bind0(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport) +    static void bind0(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport, +                             boolean exclBind)          throws IOException {          ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); -        DualStackPlainSocketImpl_c.bind0(env, fd, localAddress, localport); +        DualStackPlainSocketImpl_c.bind0(env, fd, localAddress, localport, exclBind);          env.ThrowPendingException();      } | 
