6432031: Add support for SO_REUSEPORT
Reviewed-by: alanb, simonis, chegar
This commit is contained in:
parent
19a07cb7db
commit
4dfed66526
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -87,6 +87,9 @@ SUNWprivate_1.1 {
|
|||||||
Java_java_net_PlainSocketImpl_socketConnect;
|
Java_java_net_PlainSocketImpl_socketConnect;
|
||||||
Java_java_net_PlainDatagramSocketImpl_getTimeToLive;
|
Java_java_net_PlainDatagramSocketImpl_getTimeToLive;
|
||||||
Java_java_net_PlainDatagramSocketImpl_setTimeToLive;
|
Java_java_net_PlainDatagramSocketImpl_setTimeToLive;
|
||||||
|
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0;
|
||||||
|
Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0;
|
||||||
|
Java_jdk_net_Sockets_isReusePortAvailable0;
|
||||||
Java_sun_net_PortConfig_getUpper0;
|
Java_sun_net_PortConfig_getUpper0;
|
||||||
Java_sun_net_PortConfig_getLower0;
|
Java_sun_net_PortConfig_getLower0;
|
||||||
Java_sun_net_dns_ResolverConfigurationImpl_localDomain0;
|
Java_sun_net_dns_ResolverConfigurationImpl_localDomain0;
|
||||||
@ -112,6 +115,7 @@ SUNWprivate_1.1 {
|
|||||||
NET_EnableFastTcpLoopback;
|
NET_EnableFastTcpLoopback;
|
||||||
NET_ThrowNew;
|
NET_ThrowNew;
|
||||||
ipv6_available;
|
ipv6_available;
|
||||||
|
reuseport_available;
|
||||||
initInetAddressIDs;
|
initInetAddressIDs;
|
||||||
|
|
||||||
local:
|
local:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -109,6 +109,7 @@ SUNWprivate_1.1 {
|
|||||||
Java_sun_nio_ch_Net_setIntOption0;
|
Java_sun_nio_ch_Net_setIntOption0;
|
||||||
Java_sun_nio_ch_Net_initIDs;
|
Java_sun_nio_ch_Net_initIDs;
|
||||||
Java_sun_nio_ch_Net_isIPv6Available0;
|
Java_sun_nio_ch_Net_isIPv6Available0;
|
||||||
|
Java_sun_nio_ch_Net_isReusePortAvailable0;
|
||||||
Java_sun_nio_ch_Net_joinOrDrop4;
|
Java_sun_nio_ch_Net_joinOrDrop4;
|
||||||
Java_sun_nio_ch_Net_blockOrUnblock4;
|
Java_sun_nio_ch_Net_blockOrUnblock4;
|
||||||
Java_sun_nio_ch_Net_joinOrDrop6;
|
Java_sun_nio_ch_Net_joinOrDrop6;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -102,6 +102,7 @@ SUNWprivate_1.1 {
|
|||||||
Java_sun_nio_ch_Net_setIntOption0;
|
Java_sun_nio_ch_Net_setIntOption0;
|
||||||
Java_sun_nio_ch_Net_initIDs;
|
Java_sun_nio_ch_Net_initIDs;
|
||||||
Java_sun_nio_ch_Net_isIPv6Available0;
|
Java_sun_nio_ch_Net_isIPv6Available0;
|
||||||
|
Java_sun_nio_ch_Net_isReusePortAvailable0;
|
||||||
Java_sun_nio_ch_Net_joinOrDrop4;
|
Java_sun_nio_ch_Net_joinOrDrop4;
|
||||||
Java_sun_nio_ch_Net_blockOrUnblock4;
|
Java_sun_nio_ch_Net_blockOrUnblock4;
|
||||||
Java_sun_nio_ch_Net_joinOrDrop6;
|
Java_sun_nio_ch_Net_joinOrDrop6;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -97,6 +97,7 @@ SUNWprivate_1.1 {
|
|||||||
Java_sun_nio_ch_Net_setIntOption0;
|
Java_sun_nio_ch_Net_setIntOption0;
|
||||||
Java_sun_nio_ch_Net_initIDs;
|
Java_sun_nio_ch_Net_initIDs;
|
||||||
Java_sun_nio_ch_Net_isIPv6Available0;
|
Java_sun_nio_ch_Net_isIPv6Available0;
|
||||||
|
Java_sun_nio_ch_Net_isReusePortAvailable0;
|
||||||
Java_sun_nio_ch_Net_joinOrDrop4;
|
Java_sun_nio_ch_Net_joinOrDrop4;
|
||||||
Java_sun_nio_ch_Net_blockOrUnblock4;
|
Java_sun_nio_ch_Net_blockOrUnblock4;
|
||||||
Java_sun_nio_ch_Net_joinOrDrop6;
|
Java_sun_nio_ch_Net_joinOrDrop6;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -34,6 +34,21 @@
|
|||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Defines SO_REUSEPORT */
|
||||||
|
#if !defined(SO_REUSEPORT)
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define SO_REUSEPORT 0
|
||||||
|
#elif __linux__
|
||||||
|
#define SO_REUSEPORT 15
|
||||||
|
#elif __solaris__
|
||||||
|
#define SO_REUSEPORT 0x100e
|
||||||
|
#elif defined(AIX) || defined(MACOSX)
|
||||||
|
#define SO_REUSEPORT 0x0200
|
||||||
|
#else
|
||||||
|
#define SO_REUSEPORT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates sun.nio.ch.SocketOptionRegistry, a class that maps Java-level
|
* Generates sun.nio.ch.SocketOptionRegistry, a class that maps Java-level
|
||||||
* socket options to the platform specific level and option.
|
* socket options to the platform specific level and option.
|
||||||
@ -102,6 +117,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
emit_unspec("StandardSocketOptions.SO_SNDBUF", SOL_SOCKET, SO_SNDBUF);
|
emit_unspec("StandardSocketOptions.SO_SNDBUF", SOL_SOCKET, SO_SNDBUF);
|
||||||
emit_unspec("StandardSocketOptions.SO_RCVBUF", SOL_SOCKET, SO_RCVBUF);
|
emit_unspec("StandardSocketOptions.SO_RCVBUF", SOL_SOCKET, SO_RCVBUF);
|
||||||
emit_unspec("StandardSocketOptions.SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR);
|
emit_unspec("StandardSocketOptions.SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR);
|
||||||
|
emit_unspec("StandardSocketOptions.SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT);
|
||||||
emit_unspec("StandardSocketOptions.TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY);
|
emit_unspec("StandardSocketOptions.TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY);
|
||||||
|
|
||||||
emit_inet("StandardSocketOptions.IP_TOS", IPPROTO_IP, IP_TOS);
|
emit_inet("StandardSocketOptions.IP_TOS", IPPROTO_IP, IP_TOS);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,6 +28,9 @@ import java.io.FileDescriptor;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import sun.net.ResourceManager;
|
import sun.net.ResourceManager;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract datagram and multicast socket implementation base class.
|
* Abstract datagram and multicast socket implementation base class.
|
||||||
@ -70,6 +73,45 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static volatile boolean checkedReusePort;
|
||||||
|
private static volatile boolean isReusePortAvailable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells whether SO_REUSEPORT is supported.
|
||||||
|
*/
|
||||||
|
static boolean isReusePortAvailable() {
|
||||||
|
if (!checkedReusePort) {
|
||||||
|
isReusePortAvailable = isReusePortAvailable0();
|
||||||
|
checkedReusePort = true;
|
||||||
|
}
|
||||||
|
return isReusePortAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static volatile Set<SocketOption<?>> socketOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a set of SocketOptions supported by this impl
|
||||||
|
* and by this impl's socket (Socket or ServerSocket)
|
||||||
|
*
|
||||||
|
* @return a Set of SocketOptions
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Set<SocketOption<?>> supportedOptions() {
|
||||||
|
Set<SocketOption<?>> options = socketOptions;
|
||||||
|
if (options == null) {
|
||||||
|
if (isReusePortAvailable()) {
|
||||||
|
options = new HashSet<>();
|
||||||
|
options.addAll(super.supportedOptions());
|
||||||
|
options.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
options = Collections.unmodifiableSet(options);
|
||||||
|
} else {
|
||||||
|
options = super.supportedOptions();
|
||||||
|
}
|
||||||
|
socketOptions = options;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a datagram socket
|
* Creates a datagram socket
|
||||||
*/
|
*/
|
||||||
@ -303,6 +345,14 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
|
|||||||
if (o == null || !(o instanceof Boolean))
|
if (o == null || !(o instanceof Boolean))
|
||||||
throw new SocketException("bad argument for IP_MULTICAST_LOOP");
|
throw new SocketException("bad argument for IP_MULTICAST_LOOP");
|
||||||
break;
|
break;
|
||||||
|
case SO_REUSEPORT:
|
||||||
|
if (o == null || !(o instanceof Boolean)) {
|
||||||
|
throw new SocketException("bad argument for SO_REUSEPORT");
|
||||||
|
}
|
||||||
|
if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new SocketException("invalid option: " + optID);
|
throw new SocketException("invalid option: " + optID);
|
||||||
}
|
}
|
||||||
@ -343,6 +393,13 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
|
|||||||
result = socketGetOption(optID);
|
result = socketGetOption(optID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SO_REUSEPORT:
|
||||||
|
if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
result = socketGetOption(optID);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new SocketException("invalid option: " + optID);
|
throw new SocketException("invalid option: " + optID);
|
||||||
}
|
}
|
||||||
@ -364,4 +421,5 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract int dataAvailable();
|
abstract int dataAvailable();
|
||||||
|
private static native boolean isReusePortAvailable0();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -33,6 +33,9 @@ import java.io.FileDescriptor;
|
|||||||
import sun.net.ConnectionResetException;
|
import sun.net.ConnectionResetException;
|
||||||
import sun.net.NetHooks;
|
import sun.net.NetHooks;
|
||||||
import sun.net.ResourceManager;
|
import sun.net.ResourceManager;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Socket Implementation. This implementation does
|
* Default Socket Implementation. This implementation does
|
||||||
@ -87,6 +90,45 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static volatile boolean checkedReusePort;
|
||||||
|
private static volatile boolean isReusePortAvailable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells whether SO_REUSEPORT is supported.
|
||||||
|
*/
|
||||||
|
static boolean isReusePortAvailable() {
|
||||||
|
if (!checkedReusePort) {
|
||||||
|
isReusePortAvailable = isReusePortAvailable0();
|
||||||
|
checkedReusePort = true;
|
||||||
|
}
|
||||||
|
return isReusePortAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static volatile Set<SocketOption<?>> socketOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a set of SocketOptions supported by this impl
|
||||||
|
* and by this impl's socket (Socket or ServerSocket)
|
||||||
|
*
|
||||||
|
* @return a Set of SocketOptions
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Set<SocketOption<?>> supportedOptions() {
|
||||||
|
Set<SocketOption<?>> options = socketOptions;
|
||||||
|
if (options == null) {
|
||||||
|
if (isReusePortAvailable()) {
|
||||||
|
options = new HashSet<>();
|
||||||
|
options.addAll(super.supportedOptions());
|
||||||
|
options.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
options = Collections.unmodifiableSet(options);
|
||||||
|
} else {
|
||||||
|
options = super.supportedOptions();
|
||||||
|
}
|
||||||
|
socketOptions = options;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a socket with a boolean that specifies whether this
|
* Creates a socket with a boolean that specifies whether this
|
||||||
* is a stream socket (true) or an unconnected UDP socket (false).
|
* is a stream socket (true) or an unconnected UDP socket (false).
|
||||||
@ -269,6 +311,13 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
|
|||||||
throw new SocketException("bad parameter for SO_REUSEADDR");
|
throw new SocketException("bad parameter for SO_REUSEADDR");
|
||||||
on = ((Boolean)val).booleanValue();
|
on = ((Boolean)val).booleanValue();
|
||||||
break;
|
break;
|
||||||
|
case SO_REUSEPORT:
|
||||||
|
if (val == null || !(val instanceof Boolean))
|
||||||
|
throw new SocketException("bad parameter for SO_REUSEPORT");
|
||||||
|
if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT))
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
on = ((Boolean)val).booleanValue();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new SocketException("unrecognized TCP option: " + opt);
|
throw new SocketException("unrecognized TCP option: " + opt);
|
||||||
}
|
}
|
||||||
@ -326,6 +375,12 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
|
|||||||
case SO_KEEPALIVE:
|
case SO_KEEPALIVE:
|
||||||
ret = socketGetOption(opt, null);
|
ret = socketGetOption(opt, null);
|
||||||
return Boolean.valueOf(ret != -1);
|
return Boolean.valueOf(ret != -1);
|
||||||
|
case SO_REUSEPORT:
|
||||||
|
if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
ret = socketGetOption(opt, null);
|
||||||
|
return Boolean.valueOf(ret != -1);
|
||||||
// should never get here
|
// should never get here
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
@ -723,4 +778,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
|
|||||||
|
|
||||||
public static final int SHUT_RD = 0;
|
public static final int SHUT_RD = 0;
|
||||||
public static final int SHUT_WR = 1;
|
public static final int SHUT_WR = 1;
|
||||||
|
|
||||||
|
private static native boolean isReusePortAvailable0();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -287,6 +287,9 @@ public abstract class DatagramSocketImpl implements SocketOptions {
|
|||||||
setOption(SocketOptions.SO_RCVBUF, value);
|
setOption(SocketOptions.SO_RCVBUF, value);
|
||||||
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
||||||
setOption(SocketOptions.SO_REUSEADDR, value);
|
setOption(SocketOptions.SO_REUSEADDR, value);
|
||||||
|
} else if (name == StandardSocketOptions.SO_REUSEPORT &&
|
||||||
|
supportedOptions().contains(name)) {
|
||||||
|
setOption(SocketOptions.SO_REUSEPORT, value);
|
||||||
} else if (name == StandardSocketOptions.IP_TOS) {
|
} else if (name == StandardSocketOptions.IP_TOS) {
|
||||||
setOption(SocketOptions.IP_TOS, value);
|
setOption(SocketOptions.IP_TOS, value);
|
||||||
} else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
|
} else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
|
||||||
@ -329,6 +332,9 @@ public abstract class DatagramSocketImpl implements SocketOptions {
|
|||||||
return (T) getOption(SocketOptions.SO_RCVBUF);
|
return (T) getOption(SocketOptions.SO_RCVBUF);
|
||||||
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
||||||
return (T) getOption(SocketOptions.SO_REUSEADDR);
|
return (T) getOption(SocketOptions.SO_REUSEADDR);
|
||||||
|
} else if (name == StandardSocketOptions.SO_REUSEPORT &&
|
||||||
|
supportedOptions().contains(name)) {
|
||||||
|
return (T) getOption(SocketOptions.SO_REUSEPORT);
|
||||||
} else if (name == StandardSocketOptions.IP_TOS) {
|
} else if (name == StandardSocketOptions.IP_TOS) {
|
||||||
return (T) getOption(SocketOptions.IP_TOS);
|
return (T) getOption(SocketOptions.IP_TOS);
|
||||||
} else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
|
} else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -98,7 +98,11 @@ class MulticastSocket extends DatagramSocket {
|
|||||||
* <p>
|
* <p>
|
||||||
* When the socket is created the
|
* When the socket is created the
|
||||||
* {@link DatagramSocket#setReuseAddress(boolean)} method is
|
* {@link DatagramSocket#setReuseAddress(boolean)} method is
|
||||||
* called to enable the SO_REUSEADDR socket option.
|
* called to enable the SO_REUSEADDR socket option. When
|
||||||
|
* {@link StandardSocketOptions#SO_REUSEPORT SO_REUSEPORT} is
|
||||||
|
* supported then
|
||||||
|
* {@link DatagramSocketImpl#setOption(SocketOption, Object)}
|
||||||
|
* is called to enable the socket option.
|
||||||
*
|
*
|
||||||
* @exception IOException if an I/O exception occurs
|
* @exception IOException if an I/O exception occurs
|
||||||
* while creating the MulticastSocket
|
* while creating the MulticastSocket
|
||||||
@ -106,6 +110,7 @@ class MulticastSocket extends DatagramSocket {
|
|||||||
* {@code checkListen} method doesn't allow the operation.
|
* {@code checkListen} method doesn't allow the operation.
|
||||||
* @see SecurityManager#checkListen
|
* @see SecurityManager#checkListen
|
||||||
* @see java.net.DatagramSocket#setReuseAddress(boolean)
|
* @see java.net.DatagramSocket#setReuseAddress(boolean)
|
||||||
|
* @see java.net.DatagramSocketImpl#setOption(SocketOption, Object)
|
||||||
*/
|
*/
|
||||||
public MulticastSocket() throws IOException {
|
public MulticastSocket() throws IOException {
|
||||||
this(new InetSocketAddress(0));
|
this(new InetSocketAddress(0));
|
||||||
@ -167,6 +172,11 @@ class MulticastSocket extends DatagramSocket {
|
|||||||
// Enable SO_REUSEADDR before binding
|
// Enable SO_REUSEADDR before binding
|
||||||
setReuseAddress(true);
|
setReuseAddress(true);
|
||||||
|
|
||||||
|
// Enable SO_REUSEPORT if supported before binding
|
||||||
|
if (supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
this.setOption(StandardSocketOptions.SO_REUSEPORT, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (bindaddr != null) {
|
if (bindaddr != null) {
|
||||||
try {
|
try {
|
||||||
bind(bindaddr);
|
bind(bindaddr);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -386,6 +386,9 @@ public abstract class SocketImpl implements SocketOptions {
|
|||||||
setOption(SocketOptions.SO_RCVBUF, value);
|
setOption(SocketOptions.SO_RCVBUF, value);
|
||||||
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
||||||
setOption(SocketOptions.SO_REUSEADDR, value);
|
setOption(SocketOptions.SO_REUSEADDR, value);
|
||||||
|
} else if (name == StandardSocketOptions.SO_REUSEPORT &&
|
||||||
|
supportedOptions().contains(name)) {
|
||||||
|
setOption(SocketOptions.SO_REUSEPORT, value);
|
||||||
} else if (name == StandardSocketOptions.SO_LINGER &&
|
} else if (name == StandardSocketOptions.SO_LINGER &&
|
||||||
(getSocket() != null)) {
|
(getSocket() != null)) {
|
||||||
setOption(SocketOptions.SO_LINGER, value);
|
setOption(SocketOptions.SO_LINGER, value);
|
||||||
@ -426,6 +429,9 @@ public abstract class SocketImpl implements SocketOptions {
|
|||||||
return (T)getOption(SocketOptions.SO_RCVBUF);
|
return (T)getOption(SocketOptions.SO_RCVBUF);
|
||||||
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
||||||
return (T)getOption(SocketOptions.SO_REUSEADDR);
|
return (T)getOption(SocketOptions.SO_REUSEADDR);
|
||||||
|
} else if (name == StandardSocketOptions.SO_REUSEPORT &&
|
||||||
|
supportedOptions().contains(name)) {
|
||||||
|
return (T)getOption(SocketOptions.SO_REUSEPORT);
|
||||||
} else if (name == StandardSocketOptions.SO_LINGER &&
|
} else if (name == StandardSocketOptions.SO_LINGER &&
|
||||||
(getSocket() != null)) {
|
(getSocket() != null)) {
|
||||||
return (T)getOption(SocketOptions.SO_LINGER);
|
return (T)getOption(SocketOptions.SO_LINGER);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -170,6 +170,17 @@ public interface SocketOptions {
|
|||||||
|
|
||||||
@Native public static final int SO_REUSEADDR = 0x04;
|
@Native public static final int SO_REUSEADDR = 0x04;
|
||||||
|
|
||||||
|
/** Sets SO_REUSEPORT for a socket. This option enables and disables
|
||||||
|
* the ability to have multiple sockets listen to the same address
|
||||||
|
* and port.
|
||||||
|
* <P>
|
||||||
|
* Valid for: SocketImpl, DatagramSocketImpl
|
||||||
|
*
|
||||||
|
* @since 9
|
||||||
|
* @see StandardSocketOptions#SO_REUSEPORT
|
||||||
|
*/
|
||||||
|
@Native public static final int SO_REUSEPORT = 0x0E;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets SO_BROADCAST for a socket. This option enables and disables
|
* Sets SO_BROADCAST for a socket. This option enables and disables
|
||||||
* the ability of the process to send broadcast messages. It is supported
|
* the ability of the process to send broadcast messages. It is supported
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -186,6 +186,29 @@ public final class StandardSocketOptions {
|
|||||||
public static final SocketOption<Boolean> SO_REUSEADDR =
|
public static final SocketOption<Boolean> SO_REUSEADDR =
|
||||||
new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
|
new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-use port.
|
||||||
|
*
|
||||||
|
* <p> The value of this socket option is a {@code Boolean} that represents
|
||||||
|
* whether the option is enabled or disabled. The exact semantics of this
|
||||||
|
* socket option are socket type and system dependent.
|
||||||
|
*
|
||||||
|
* <p> In the case of stream-oriented sockets, this socket option usually allows
|
||||||
|
* multiple listening sockets to be bound to both same address
|
||||||
|
* and same port.
|
||||||
|
*
|
||||||
|
* <p> For datagram-oriented sockets the socket option usually allows
|
||||||
|
* multiple UDP sockets to be bound to the same address and port.
|
||||||
|
*
|
||||||
|
* <p> An implementation allows this socket option to be set before the
|
||||||
|
* socket is bound or connected. Changing the value of this socket option
|
||||||
|
* after the socket is bound has no effect.
|
||||||
|
*
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
public static final SocketOption<Boolean> SO_REUSEPORT =
|
||||||
|
new StdSocketOption<Boolean>("SO_REUSEPORT", Boolean.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linger on close if data is present.
|
* Linger on close if data is present.
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -251,9 +251,23 @@ public class Sockets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static volatile boolean checkedReusePort;
|
||||||
|
private static volatile boolean isReusePortAvailable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells whether SO_REUSEPORT is supported.
|
||||||
|
*/
|
||||||
|
static boolean isReusePortAvailable() {
|
||||||
|
if (!checkedReusePort) {
|
||||||
|
isReusePortAvailable = isReusePortAvailable0();
|
||||||
|
checkedReusePort = true;
|
||||||
|
}
|
||||||
|
return isReusePortAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
private static void initOptionSets() {
|
private static void initOptionSets() {
|
||||||
boolean flowsupported = ExtendedOptionsImpl.flowSupported();
|
boolean flowsupported = ExtendedOptionsImpl.flowSupported();
|
||||||
|
boolean reuseportsupported = isReusePortAvailable();
|
||||||
// Socket
|
// Socket
|
||||||
|
|
||||||
Set<SocketOption<?>> set = new HashSet<>();
|
Set<SocketOption<?>> set = new HashSet<>();
|
||||||
@ -261,6 +275,9 @@ public class Sockets {
|
|||||||
set.add(StandardSocketOptions.SO_SNDBUF);
|
set.add(StandardSocketOptions.SO_SNDBUF);
|
||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (reuseportsupported) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
set.add(StandardSocketOptions.SO_LINGER);
|
set.add(StandardSocketOptions.SO_LINGER);
|
||||||
set.add(StandardSocketOptions.IP_TOS);
|
set.add(StandardSocketOptions.IP_TOS);
|
||||||
set.add(StandardSocketOptions.TCP_NODELAY);
|
set.add(StandardSocketOptions.TCP_NODELAY);
|
||||||
@ -275,6 +292,9 @@ public class Sockets {
|
|||||||
set = new HashSet<>();
|
set = new HashSet<>();
|
||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (reuseportsupported) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
set.add(StandardSocketOptions.IP_TOS);
|
set.add(StandardSocketOptions.IP_TOS);
|
||||||
set = Collections.unmodifiableSet(set);
|
set = Collections.unmodifiableSet(set);
|
||||||
options.put(ServerSocket.class, set);
|
options.put(ServerSocket.class, set);
|
||||||
@ -285,6 +305,9 @@ public class Sockets {
|
|||||||
set.add(StandardSocketOptions.SO_SNDBUF);
|
set.add(StandardSocketOptions.SO_SNDBUF);
|
||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (reuseportsupported) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
set.add(StandardSocketOptions.IP_TOS);
|
set.add(StandardSocketOptions.IP_TOS);
|
||||||
if (flowsupported) {
|
if (flowsupported) {
|
||||||
set.add(ExtendedSocketOptions.SO_FLOW_SLA);
|
set.add(ExtendedSocketOptions.SO_FLOW_SLA);
|
||||||
@ -298,6 +321,9 @@ public class Sockets {
|
|||||||
set.add(StandardSocketOptions.SO_SNDBUF);
|
set.add(StandardSocketOptions.SO_SNDBUF);
|
||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (reuseportsupported) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
set.add(StandardSocketOptions.IP_TOS);
|
set.add(StandardSocketOptions.IP_TOS);
|
||||||
set.add(StandardSocketOptions.IP_MULTICAST_IF);
|
set.add(StandardSocketOptions.IP_MULTICAST_IF);
|
||||||
set.add(StandardSocketOptions.IP_MULTICAST_TTL);
|
set.add(StandardSocketOptions.IP_MULTICAST_TTL);
|
||||||
@ -308,4 +334,6 @@ public class Sockets {
|
|||||||
set = Collections.unmodifiableSet(set);
|
set = Collections.unmodifiableSet(set);
|
||||||
options.put(MulticastSocket.class, set);
|
options.put(MulticastSocket.class, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static native boolean isReusePortAvailable0();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -231,6 +231,9 @@ abstract class AsynchronousServerSocketChannelImpl
|
|||||||
HashSet<SocketOption<?>> set = new HashSet<>(2);
|
HashSet<SocketOption<?>> set = new HashSet<>(2);
|
||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (Net.isReusePortAvailable()) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
return Collections.unmodifiableSet(set);
|
return Collections.unmodifiableSet(set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -508,6 +508,9 @@ abstract class AsynchronousSocketChannelImpl
|
|||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_KEEPALIVE);
|
set.add(StandardSocketOptions.SO_KEEPALIVE);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (Net.isReusePortAvailable()) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
set.add(StandardSocketOptions.TCP_NODELAY);
|
set.add(StandardSocketOptions.TCP_NODELAY);
|
||||||
if (ExtendedOptionsImpl.flowSupported()) {
|
if (ExtendedOptionsImpl.flowSupported()) {
|
||||||
set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
|
set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -298,6 +298,9 @@ class DatagramChannelImpl
|
|||||||
set.add(StandardSocketOptions.SO_SNDBUF);
|
set.add(StandardSocketOptions.SO_SNDBUF);
|
||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (Net.isReusePortAvailable()) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
set.add(StandardSocketOptions.SO_BROADCAST);
|
set.add(StandardSocketOptions.SO_BROADCAST);
|
||||||
set.add(StandardSocketOptions.IP_TOS);
|
set.add(StandardSocketOptions.IP_TOS);
|
||||||
set.add(StandardSocketOptions.IP_MULTICAST_IF);
|
set.add(StandardSocketOptions.IP_MULTICAST_IF);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -56,6 +56,8 @@ public class Net {
|
|||||||
|
|
||||||
private static volatile boolean checkedIPv6;
|
private static volatile boolean checkedIPv6;
|
||||||
private static volatile boolean isIPv6Available;
|
private static volatile boolean isIPv6Available;
|
||||||
|
private static volatile boolean checkedReusePort;
|
||||||
|
private static volatile boolean isReusePortAvailable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells whether dual-IPv4/IPv6 sockets should be used.
|
* Tells whether dual-IPv4/IPv6 sockets should be used.
|
||||||
@ -68,6 +70,17 @@ public class Net {
|
|||||||
return isIPv6Available;
|
return isIPv6Available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells whether SO_REUSEPORT is supported.
|
||||||
|
*/
|
||||||
|
static boolean isReusePortAvailable() {
|
||||||
|
if (!checkedReusePort) {
|
||||||
|
isReusePortAvailable = isReusePortAvailable0();
|
||||||
|
checkedReusePort = true;
|
||||||
|
}
|
||||||
|
return isReusePortAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if exclusive binding is on
|
* Returns true if exclusive binding is on
|
||||||
*/
|
*/
|
||||||
@ -389,6 +402,8 @@ public class Net {
|
|||||||
|
|
||||||
private static native boolean isIPv6Available0();
|
private static native boolean isIPv6Available0();
|
||||||
|
|
||||||
|
private static native boolean isReusePortAvailable0();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns 1 for Windows and -1 for Solaris/Linux/Mac OS
|
* Returns 1 for Windows and -1 for Solaris/Linux/Mac OS
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -33,7 +33,6 @@ import java.nio.channels.spi.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import sun.net.NetHooks;
|
import sun.net.NetHooks;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of ServerSocketChannels
|
* An implementation of ServerSocketChannels
|
||||||
*/
|
*/
|
||||||
@ -185,6 +184,9 @@ class ServerSocketChannelImpl
|
|||||||
HashSet<SocketOption<?>> set = new HashSet<>(2);
|
HashSet<SocketOption<?>> set = new HashSet<>(2);
|
||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (Net.isReusePortAvailable()) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
set.add(StandardSocketOptions.IP_TOS);
|
set.add(StandardSocketOptions.IP_TOS);
|
||||||
return Collections.unmodifiableSet(set);
|
return Collections.unmodifiableSet(set);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -234,6 +234,9 @@ class SocketChannelImpl
|
|||||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||||
set.add(StandardSocketOptions.SO_KEEPALIVE);
|
set.add(StandardSocketOptions.SO_KEEPALIVE);
|
||||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||||
|
if (Net.isReusePortAvailable()) {
|
||||||
|
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
}
|
||||||
set.add(StandardSocketOptions.SO_LINGER);
|
set.add(StandardSocketOptions.SO_LINGER);
|
||||||
set.add(StandardSocketOptions.TCP_NODELAY);
|
set.add(StandardSocketOptions.TCP_NODELAY);
|
||||||
// additional options required by socket adaptor
|
// additional options required by socket adaptor
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -29,14 +29,21 @@
|
|||||||
#include "net_util.h"
|
#include "net_util.h"
|
||||||
|
|
||||||
int IPv6_supported() ;
|
int IPv6_supported() ;
|
||||||
|
int reuseport_supported() ;
|
||||||
|
|
||||||
static int IPv6_available;
|
static int IPv6_available;
|
||||||
|
static int REUSEPORT_available;
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL ipv6_available()
|
JNIEXPORT jint JNICALL ipv6_available()
|
||||||
{
|
{
|
||||||
return IPv6_available ;
|
return IPv6_available ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL reuseport_available()
|
||||||
|
{
|
||||||
|
return REUSEPORT_available;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
|
DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||||
{
|
{
|
||||||
@ -45,7 +52,6 @@ DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
|
|||||||
jmethodID mid;
|
jmethodID mid;
|
||||||
jstring s;
|
jstring s;
|
||||||
jint preferIPv4Stack;
|
jint preferIPv4Stack;
|
||||||
|
|
||||||
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
|
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
|
||||||
return JNI_EVERSION; /* JNI version not supported */
|
return JNI_EVERSION; /* JNI version not supported */
|
||||||
}
|
}
|
||||||
@ -64,6 +70,9 @@ DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
|
|||||||
supporting socket APIs are available
|
supporting socket APIs are available
|
||||||
*/
|
*/
|
||||||
IPv6_available = IPv6_supported() & (!preferIPv4Stack);
|
IPv6_available = IPv6_supported() & (!preferIPv4Stack);
|
||||||
|
|
||||||
|
/* check if SO_REUSEPORT is supported on this platform */
|
||||||
|
REUSEPORT_available = reuseport_supported();
|
||||||
platformInit();
|
platformInit();
|
||||||
parseExclusiveBindProperty(env);
|
parseExclusiveBindProperty(env);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -131,6 +131,8 @@ jfieldID NET_GetFileDescriptorID(JNIEnv *env);
|
|||||||
|
|
||||||
JNIEXPORT jint JNICALL ipv6_available() ;
|
JNIEXPORT jint JNICALL ipv6_available() ;
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL reuseport_available() ;
|
||||||
|
|
||||||
void
|
void
|
||||||
NET_AllocSockaddr(struct sockaddr **him, int *len);
|
NET_AllocSockaddr(struct sockaddr **him, int *len);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -45,7 +45,15 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
|||||||
|
|
||||||
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
|
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
|
||||||
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
|
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
|
||||||
super.setOption(name, value);
|
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
super.setOption(name, value);
|
||||||
|
} else {
|
||||||
|
if (supportedOptions().contains(name)) {
|
||||||
|
super.setOption(name, value);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!flowSupported()) {
|
if (!flowSupported()) {
|
||||||
throw new UnsupportedOperationException("unsupported option");
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
@ -62,7 +70,15 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> T getOption(SocketOption<T> name) throws IOException {
|
protected <T> T getOption(SocketOption<T> name) throws IOException {
|
||||||
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
|
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
|
||||||
return super.getOption(name);
|
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
return super.getOption(name);
|
||||||
|
} else {
|
||||||
|
if (supportedOptions().contains(name)) {
|
||||||
|
return super.getOption(name);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!flowSupported()) {
|
if (!flowSupported()) {
|
||||||
throw new UnsupportedOperationException("unsupported option");
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
@ -87,6 +103,9 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void socketSetOption(int opt, Object val) throws SocketException {
|
protected void socketSetOption(int opt, Object val) throws SocketException {
|
||||||
|
if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
socketSetOption0(opt, val);
|
socketSetOption0(opt, val);
|
||||||
} catch (SocketException se) {
|
} catch (SocketException se) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -59,7 +59,15 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
|
|
||||||
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
|
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
|
||||||
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
|
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
|
||||||
super.setOption(name, value);
|
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
super.setOption(name, value);
|
||||||
|
} else {
|
||||||
|
if (supportedOptions().contains(name)) {
|
||||||
|
super.setOption(name, value);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (getSocket() == null || !flowSupported()) {
|
if (getSocket() == null || !flowSupported()) {
|
||||||
throw new UnsupportedOperationException("unsupported option");
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
@ -76,7 +84,15 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> T getOption(SocketOption<T> name) throws IOException {
|
protected <T> T getOption(SocketOption<T> name) throws IOException {
|
||||||
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
|
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
|
||||||
return super.getOption(name);
|
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
return super.getOption(name);
|
||||||
|
} else {
|
||||||
|
if (supportedOptions().contains(name)) {
|
||||||
|
return super.getOption(name);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (getSocket() == null || !flowSupported()) {
|
if (getSocket() == null || !flowSupported()) {
|
||||||
throw new UnsupportedOperationException("unsupported option");
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
@ -101,6 +117,9 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
|
protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
|
||||||
|
if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
socketSetOption0(opt, b, val);
|
socketSetOption0(opt, b, val);
|
||||||
} catch (SocketException se) {
|
} catch (SocketException se) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -1392,6 +1392,7 @@ Java_java_net_PlainDatagramSocketImpl_socketSetOption0(JNIEnv *env,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case java_net_SocketOptions_SO_REUSEADDR:
|
case java_net_SocketOptions_SO_REUSEADDR:
|
||||||
|
case java_net_SocketOptions_SO_REUSEPORT:
|
||||||
case java_net_SocketOptions_SO_BROADCAST:
|
case java_net_SocketOptions_SO_BROADCAST:
|
||||||
{
|
{
|
||||||
jclass cls;
|
jclass cls;
|
||||||
@ -1769,6 +1770,9 @@ Java_java_net_PlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobject this,
|
|||||||
case java_net_SocketOptions_SO_REUSEADDR:
|
case java_net_SocketOptions_SO_REUSEADDR:
|
||||||
return createBoolean(env, optval.i);
|
return createBoolean(env, optval.i);
|
||||||
|
|
||||||
|
case java_net_SocketOptions_SO_REUSEPORT:
|
||||||
|
return createBoolean(env, optval.i);
|
||||||
|
|
||||||
case java_net_SocketOptions_SO_SNDBUF:
|
case java_net_SocketOptions_SO_SNDBUF:
|
||||||
case java_net_SocketOptions_SO_RCVBUF:
|
case java_net_SocketOptions_SO_RCVBUF:
|
||||||
case java_net_SocketOptions_IP_TOS:
|
case java_net_SocketOptions_IP_TOS:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -108,6 +108,11 @@ Java_sun_net_sdp_SdpSupport_convert0(JNIEnv *env, jclass cls, int fd)
|
|||||||
len = sizeof(arg);
|
len = sizeof(arg);
|
||||||
if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, &len) == 0)
|
if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, &len) == 0)
|
||||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, len);
|
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, len);
|
||||||
|
#ifdef SO_REUSEPORT
|
||||||
|
len = sizeof(arg);
|
||||||
|
if (getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char*)&arg, &len) == 0)
|
||||||
|
setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char*)&arg, len);
|
||||||
|
#endif
|
||||||
len = sizeof(arg);
|
len = sizeof(arg);
|
||||||
if (getsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, &len) == 0)
|
if (getsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, &len) == 0)
|
||||||
setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, len);
|
setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, len);
|
||||||
|
47
jdk/src/java.base/unix/native/libnet/SocketImpl.c
Normal file
47
jdk/src/java.base/unix/native/libnet/SocketImpl.c
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "net_util.h"
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||||
|
{
|
||||||
|
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||||
|
{
|
||||||
|
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||||
|
{
|
||||||
|
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -439,6 +439,25 @@ jint IPv6_supported()
|
|||||||
}
|
}
|
||||||
#endif /* DONT_ENABLE_IPV6 */
|
#endif /* DONT_ENABLE_IPV6 */
|
||||||
|
|
||||||
|
jint reuseport_supported()
|
||||||
|
{
|
||||||
|
/* Do a simple dummy call, and try to figure out from that */
|
||||||
|
int one = 1;
|
||||||
|
int rv, s;
|
||||||
|
s = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
|
if (s < 0) {
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
rv = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void *)&one, sizeof(one));
|
||||||
|
if (rv != 0) {
|
||||||
|
rv = JNI_FALSE;
|
||||||
|
} else {
|
||||||
|
rv = JNI_TRUE;
|
||||||
|
}
|
||||||
|
close(s);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
|
void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
|
||||||
const char* hostname,
|
const char* hostname,
|
||||||
int gai_error)
|
int gai_error)
|
||||||
@ -1014,6 +1033,7 @@ NET_MapSocketOption(jint cmd, int *level, int *optname) {
|
|||||||
{ java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },
|
{ java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },
|
||||||
{ java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE },
|
{ java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE },
|
||||||
{ java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR },
|
{ java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR },
|
||||||
|
{ java_net_SocketOptions_SO_REUSEPORT, SOL_SOCKET, SO_REUSEPORT },
|
||||||
{ java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST },
|
{ java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST },
|
||||||
{ java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS },
|
{ java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS },
|
||||||
{ java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF },
|
{ java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF },
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -60,6 +60,19 @@ void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
|
|||||||
#define NET_WAIT_WRITE 0x02
|
#define NET_WAIT_WRITE 0x02
|
||||||
#define NET_WAIT_CONNECT 0x04
|
#define NET_WAIT_CONNECT 0x04
|
||||||
|
|
||||||
|
/* Defines SO_REUSEPORT */
|
||||||
|
#ifndef SO_REUSEPORT
|
||||||
|
#ifdef __linux__
|
||||||
|
#define SO_REUSEPORT 15
|
||||||
|
#elif __solaris__
|
||||||
|
#define SO_REUSEPORT 0x100e
|
||||||
|
#elif defined(AIX) || defined(MACOSX)
|
||||||
|
#define SO_REUSEPORT 0x0200
|
||||||
|
#else
|
||||||
|
#define SO_REUSEPORT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout);
|
jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -161,6 +161,12 @@ Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl)
|
|||||||
return (ipv6_available()) ? JNI_TRUE : JNI_FALSE;
|
return (ipv6_available()) ? JNI_TRUE : JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_sun_nio_ch_Net_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||||
|
{
|
||||||
|
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
|
Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -36,6 +36,18 @@
|
|||||||
} while((_result == -1) && (errno == EINTR)); \
|
} while((_result == -1) && (errno == EINTR)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* Defines SO_REUSEPORT */
|
||||||
|
#ifndef SO_REUSEPORT
|
||||||
|
#ifdef __linux__
|
||||||
|
#define SO_REUSEPORT 15
|
||||||
|
#elif __solaris__
|
||||||
|
#define SO_REUSEPORT 0x100e
|
||||||
|
#elif defined(AIX) || defined(MACOSX)
|
||||||
|
#define SO_REUSEPORT 0x0200
|
||||||
|
#else
|
||||||
|
#define SO_REUSEPORT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* NIO utility procedures */
|
/* NIO utility procedures */
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -167,6 +167,11 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
|||||||
|
|
||||||
int optionValue = 0;
|
int optionValue = 0;
|
||||||
|
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
if (opt == SO_REUSEPORT) {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
|
||||||
switch(opt) {
|
switch(opt) {
|
||||||
case IP_TOS :
|
case IP_TOS :
|
||||||
case SO_RCVBUF :
|
case SO_RCVBUF :
|
||||||
@ -200,6 +205,9 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
|||||||
}
|
}
|
||||||
if (opt == SO_REUSEADDR && reuseAddressEmulated)
|
if (opt == SO_REUSEADDR && reuseAddressEmulated)
|
||||||
return isReuseAddress;
|
return isReuseAddress;
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
if (opt == SO_REUSEPORT)
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
|
||||||
int value = socketGetIntOption(nativefd, opt);
|
int value = socketGetIntOption(nativefd, opt);
|
||||||
Object returnValue = null;
|
Object returnValue = null;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -181,6 +181,10 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
if (opt == SO_TIMEOUT) { // timeout implemented through select.
|
if (opt == SO_TIMEOUT) { // timeout implemented through select.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
if (opt == SO_REUSEPORT) {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
|
||||||
int optionValue = 0;
|
int optionValue = 0;
|
||||||
|
|
||||||
@ -224,6 +228,10 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
localAddress(nativefd, (InetAddressContainer)iaContainerObj);
|
localAddress(nativefd, (InetAddressContainer)iaContainerObj);
|
||||||
return 0; // return value doesn't matter.
|
return 0; // return value doesn't matter.
|
||||||
}
|
}
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
if (opt == SO_REUSEPORT) {
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
|
|
||||||
// SO_REUSEADDR emulated when using exclusive bind
|
// SO_REUSEADDR emulated when using exclusive bind
|
||||||
if (opt == SO_REUSEADDR && exclusiveBind)
|
if (opt == SO_REUSEADDR && exclusiveBind)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -173,10 +173,18 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setOption(int opt, Object val) throws SocketException {
|
public void setOption(int opt, Object val) throws SocketException {
|
||||||
|
if (opt == SocketOptions.SO_REUSEPORT) {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
impl.setOption(opt, val);
|
impl.setOption(opt, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getOption(int opt) throws SocketException {
|
public Object getOption(int opt) throws SocketException {
|
||||||
|
if (opt == SocketOptions.SO_REUSEPORT) {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
return impl.getOption(opt);
|
return impl.getOption(opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,14 +340,27 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
|
|
||||||
void socketSetOption(int cmd, boolean on, Object value)
|
void socketSetOption(int cmd, boolean on, Object value)
|
||||||
throws SocketException {
|
throws SocketException {
|
||||||
|
if (cmd == SocketOptions.SO_REUSEPORT) {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
impl.socketSetOption(cmd, on, value);
|
impl.socketSetOption(cmd, on, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
|
int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
|
||||||
|
if (opt == SocketOptions.SO_REUSEPORT) {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
return impl.socketGetOption(opt, iaContainerObj);
|
return impl.socketGetOption(opt, iaContainerObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void socketSendUrgentData(int data) throws IOException {
|
void socketSendUrgentData(int data) throws IOException {
|
||||||
impl.socketSendUrgentData(data);
|
impl.socketSendUrgentData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean isReusePortAvailable() {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -130,6 +130,9 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
|||||||
return socketLocalAddress(family);
|
return socketLocalAddress(family);
|
||||||
} else if (optID == SO_REUSEADDR && reuseAddressEmulated) {
|
} else if (optID == SO_REUSEADDR && reuseAddressEmulated) {
|
||||||
return isReuseAddress;
|
return isReuseAddress;
|
||||||
|
} else if (optID == SO_REUSEPORT) {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
} else {
|
} else {
|
||||||
return super.getOption(optID);
|
return super.getOption(optID);
|
||||||
}
|
}
|
||||||
@ -142,6 +145,9 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
|||||||
// socket already bound, emulate
|
// socket already bound, emulate
|
||||||
reuseAddressEmulated = true;
|
reuseAddressEmulated = true;
|
||||||
isReuseAddress = (Boolean)val;
|
isReuseAddress = (Boolean)val;
|
||||||
|
} else if (opt == SO_REUSEPORT) {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
} else {
|
} else {
|
||||||
socketNativeSetOption(opt, val);
|
socketNativeSetOption(opt, val);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -128,6 +128,9 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
} else if (opt == SO_REUSEADDR && exclusiveBind) {
|
} else if (opt == SO_REUSEADDR && exclusiveBind) {
|
||||||
// SO_REUSEADDR emulated when using exclusive bind
|
// SO_REUSEADDR emulated when using exclusive bind
|
||||||
return isReuseAddress;
|
return isReuseAddress;
|
||||||
|
} else if (opt == SO_REUSEPORT) {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
} else
|
} else
|
||||||
return super.getOption(opt);
|
return super.getOption(opt);
|
||||||
}
|
}
|
||||||
@ -144,6 +147,10 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
// SO_REUSEADDR emulated when using exclusive bind
|
// SO_REUSEADDR emulated when using exclusive bind
|
||||||
if (opt == SO_REUSEADDR && exclusiveBind)
|
if (opt == SO_REUSEADDR && exclusiveBind)
|
||||||
isReuseAddress = on;
|
isReuseAddress = on;
|
||||||
|
else if (opt == SO_REUSEPORT) {
|
||||||
|
// SO_REUSEPORT is not supported on Windows.
|
||||||
|
throw new UnsupportedOperationException("unsupported option");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
socketNativeSetOption(opt, on, value);
|
socketNativeSetOption(opt, on, value);
|
||||||
}
|
}
|
||||||
|
47
jdk/src/java.base/windows/native/libnet/SocketImpl.c
Normal file
47
jdk/src/java.base/windows/native/libnet/SocketImpl.c
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||||
|
{
|
||||||
|
// SO_REUSEPORT is not supported on Windows
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||||
|
{
|
||||||
|
// SO_REUSEPORT is not supported on Windows
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||||
|
{
|
||||||
|
// SO_REUSEPORT is not supported on Windows
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -242,6 +242,11 @@ jint IPv6_supported()
|
|||||||
return JNI_TRUE;
|
return JNI_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jint reuseport_supported()
|
||||||
|
{
|
||||||
|
/* SO_REUSEPORT is not supported onn Windows */
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Return the default TOS value
|
* Return the default TOS value
|
||||||
*/
|
*/
|
||||||
|
@ -54,6 +54,9 @@
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/*SO_REUSEPORT is not supported on Windows, define it to 0*/
|
||||||
|
#define SO_REUSEPORT 0
|
||||||
|
|
||||||
/* Retain this code a little longer to support building in
|
/* Retain this code a little longer to support building in
|
||||||
* old environments. _MSC_VER is defined as:
|
* old environments. _MSC_VER is defined as:
|
||||||
* 1200 for MSVC++ 6.0
|
* 1200 for MSVC++ 6.0
|
||||||
@ -353,3 +356,4 @@ JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0_XP
|
|||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
|
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
|
||||||
(JNIEnv *env, jclass cls, jstring name, jint index);
|
(JNIEnv *env, jclass cls, jstring name, jint index);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -93,6 +93,13 @@ Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl)
|
|||||||
return ipv6_available() ? JNI_TRUE : JNI_FALSE;
|
return ipv6_available() ? JNI_TRUE : JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_sun_nio_ch_Net_isReusePortAvailable0(JNIEnv* env, jclass c1)
|
||||||
|
{
|
||||||
|
// SO_REUSEPORT is not supported on Windows
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
|
Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -54,6 +54,7 @@ public class OptionsTest {
|
|||||||
Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
|
Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
|
||||||
Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
|
Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
|
||||||
Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
|
Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
|
||||||
|
Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
|
||||||
Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(80)),
|
Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(80)),
|
||||||
Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
|
Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
|
||||||
};
|
};
|
||||||
@ -61,6 +62,7 @@ public class OptionsTest {
|
|||||||
static Test[] serverSocketTests = new Test[] {
|
static Test[] serverSocketTests = new Test[] {
|
||||||
Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
|
Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
|
||||||
Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
|
Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
|
||||||
|
Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
|
||||||
Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
|
Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ public class OptionsTest {
|
|||||||
Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
|
Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
|
||||||
Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
|
Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
|
||||||
Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
|
Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
|
||||||
|
Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
|
||||||
Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
|
Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,15 +100,19 @@ public class OptionsTest {
|
|||||||
Socket c = new Socket("127.0.0.1", srv.getLocalPort());
|
Socket c = new Socket("127.0.0.1", srv.getLocalPort());
|
||||||
Socket s = srv.accept();
|
Socket s = srv.accept();
|
||||||
) {
|
) {
|
||||||
|
Set<SocketOption<?>> options = c.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
|
||||||
for (int i=0; i<socketTests.length; i++) {
|
for (int i=0; i<socketTests.length; i++) {
|
||||||
Test test = socketTests[i];
|
Test test = socketTests[i];
|
||||||
c.setOption((SocketOption)test.option, test.testValue);
|
if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
|
||||||
Object getval = c.getOption((SocketOption)test.option);
|
c.setOption((SocketOption)test.option, test.testValue);
|
||||||
Object legacyget = legacyGetOption(Socket.class, c,test.option);
|
Object getval = c.getOption((SocketOption)test.option);
|
||||||
if (!getval.equals(legacyget)) {
|
Object legacyget = legacyGetOption(Socket.class, c,test.option);
|
||||||
Formatter f = new Formatter();
|
if (!getval.equals(legacyget)) {
|
||||||
f.format("S Err %d: %s/%s", i, getval, legacyget);
|
Formatter f = new Formatter();
|
||||||
throw new RuntimeException(f.toString());
|
f.format("S Err %d: %s/%s", i, getval, legacyget);
|
||||||
|
throw new RuntimeException(f.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,15 +122,19 @@ public class OptionsTest {
|
|||||||
try (
|
try (
|
||||||
DatagramSocket c = new DatagramSocket(0);
|
DatagramSocket c = new DatagramSocket(0);
|
||||||
) {
|
) {
|
||||||
|
Set<SocketOption<?>> options = c.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
|
||||||
for (int i=0; i<dgSocketTests.length; i++) {
|
for (int i=0; i<dgSocketTests.length; i++) {
|
||||||
Test test = dgSocketTests[i];
|
Test test = dgSocketTests[i];
|
||||||
c.setOption((SocketOption)test.option, test.testValue);
|
if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
|
||||||
Object getval = c.getOption((SocketOption)test.option);
|
c.setOption((SocketOption)test.option, test.testValue);
|
||||||
Object legacyget = legacyGetOption(DatagramSocket.class, c,test.option);
|
Object getval = c.getOption((SocketOption)test.option);
|
||||||
if (!getval.equals(legacyget)) {
|
Object legacyget = legacyGetOption(DatagramSocket.class, c,test.option);
|
||||||
Formatter f = new Formatter();
|
if (!getval.equals(legacyget)) {
|
||||||
f.format("DG Err %d: %s/%s", i, getval, legacyget);
|
Formatter f = new Formatter();
|
||||||
throw new RuntimeException(f.toString());
|
f.format("DG Err %d: %s/%s", i, getval, legacyget);
|
||||||
|
throw new RuntimeException(f.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,17 +162,21 @@ public class OptionsTest {
|
|||||||
try (
|
try (
|
||||||
ServerSocket c = new ServerSocket(0);
|
ServerSocket c = new ServerSocket(0);
|
||||||
) {
|
) {
|
||||||
|
Set<SocketOption<?>> options = c.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
|
||||||
for (int i=0; i<serverSocketTests.length; i++) {
|
for (int i=0; i<serverSocketTests.length; i++) {
|
||||||
Test test = serverSocketTests[i];
|
Test test = serverSocketTests[i];
|
||||||
c.setOption((SocketOption)test.option, test.testValue);
|
if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
|
||||||
Object getval = c.getOption((SocketOption)test.option);
|
c.setOption((SocketOption)test.option, test.testValue);
|
||||||
Object legacyget = legacyGetOption(
|
Object getval = c.getOption((SocketOption)test.option);
|
||||||
ServerSocket.class, c, test.option
|
Object legacyget = legacyGetOption(
|
||||||
);
|
ServerSocket.class, c, test.option
|
||||||
if (!getval.equals(legacyget)) {
|
);
|
||||||
Formatter f = new Formatter();
|
if (!getval.equals(legacyget)) {
|
||||||
f.format("SS Err %d: %s/%s", i, getval, legacyget);
|
Formatter f = new Formatter();
|
||||||
throw new RuntimeException(f.toString());
|
f.format("SS Err %d: %s/%s", i, getval, legacyget);
|
||||||
|
throw new RuntimeException(f.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,6 +189,8 @@ public class OptionsTest {
|
|||||||
{
|
{
|
||||||
if (type.equals(Socket.class)) {
|
if (type.equals(Socket.class)) {
|
||||||
Socket socket = (Socket)s;
|
Socket socket = (Socket)s;
|
||||||
|
Set<SocketOption<?>> options = socket.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
|
||||||
if (option.equals(StandardSocketOptions.SO_KEEPALIVE)) {
|
if (option.equals(StandardSocketOptions.SO_KEEPALIVE)) {
|
||||||
return Boolean.valueOf(socket.getKeepAlive());
|
return Boolean.valueOf(socket.getKeepAlive());
|
||||||
@ -183,6 +200,8 @@ public class OptionsTest {
|
|||||||
return Integer.valueOf(socket.getReceiveBufferSize());
|
return Integer.valueOf(socket.getReceiveBufferSize());
|
||||||
} else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
|
} else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
|
||||||
return Boolean.valueOf(socket.getReuseAddress());
|
return Boolean.valueOf(socket.getReuseAddress());
|
||||||
|
} else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
|
||||||
|
return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
|
||||||
} else if (option.equals(StandardSocketOptions.SO_LINGER)) {
|
} else if (option.equals(StandardSocketOptions.SO_LINGER)) {
|
||||||
return Integer.valueOf(socket.getSoLinger());
|
return Integer.valueOf(socket.getSoLinger());
|
||||||
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
|
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
|
||||||
@ -194,10 +213,15 @@ public class OptionsTest {
|
|||||||
}
|
}
|
||||||
} else if (type.equals(ServerSocket.class)) {
|
} else if (type.equals(ServerSocket.class)) {
|
||||||
ServerSocket socket = (ServerSocket)s;
|
ServerSocket socket = (ServerSocket)s;
|
||||||
|
Set<SocketOption<?>> options = socket.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
|
||||||
if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
|
if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
|
||||||
return Integer.valueOf(socket.getReceiveBufferSize());
|
return Integer.valueOf(socket.getReceiveBufferSize());
|
||||||
} else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
|
} else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
|
||||||
return Boolean.valueOf(socket.getReuseAddress());
|
return Boolean.valueOf(socket.getReuseAddress());
|
||||||
|
} else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
|
||||||
|
return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
|
||||||
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
|
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
|
||||||
return Integer.valueOf(jdk.net.Sockets.getOption(
|
return Integer.valueOf(jdk.net.Sockets.getOption(
|
||||||
socket, StandardSocketOptions.IP_TOS));
|
socket, StandardSocketOptions.IP_TOS));
|
||||||
@ -206,6 +230,8 @@ public class OptionsTest {
|
|||||||
}
|
}
|
||||||
} else if (type.equals(DatagramSocket.class)) {
|
} else if (type.equals(DatagramSocket.class)) {
|
||||||
DatagramSocket socket = (DatagramSocket)s;
|
DatagramSocket socket = (DatagramSocket)s;
|
||||||
|
Set<SocketOption<?>> options = socket.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
|
||||||
if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
|
if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
|
||||||
return Integer.valueOf(socket.getSendBufferSize());
|
return Integer.valueOf(socket.getSendBufferSize());
|
||||||
@ -213,6 +239,8 @@ public class OptionsTest {
|
|||||||
return Integer.valueOf(socket.getReceiveBufferSize());
|
return Integer.valueOf(socket.getReceiveBufferSize());
|
||||||
} else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
|
} else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
|
||||||
return Boolean.valueOf(socket.getReuseAddress());
|
return Boolean.valueOf(socket.getReuseAddress());
|
||||||
|
} else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
|
||||||
|
return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
|
||||||
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
|
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
|
||||||
return Integer.valueOf(socket.getTrafficClass());
|
return Integer.valueOf(socket.getTrafficClass());
|
||||||
} else {
|
} else {
|
||||||
@ -221,6 +249,8 @@ public class OptionsTest {
|
|||||||
|
|
||||||
} else if (type.equals(MulticastSocket.class)) {
|
} else if (type.equals(MulticastSocket.class)) {
|
||||||
MulticastSocket socket = (MulticastSocket)s;
|
MulticastSocket socket = (MulticastSocket)s;
|
||||||
|
Set<SocketOption<?>> options = socket.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
|
||||||
|
|
||||||
if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
|
if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
|
||||||
return Integer.valueOf(socket.getSendBufferSize());
|
return Integer.valueOf(socket.getSendBufferSize());
|
||||||
@ -228,6 +258,8 @@ public class OptionsTest {
|
|||||||
return Integer.valueOf(socket.getReceiveBufferSize());
|
return Integer.valueOf(socket.getReceiveBufferSize());
|
||||||
} else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
|
} else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
|
||||||
return Boolean.valueOf(socket.getReuseAddress());
|
return Boolean.valueOf(socket.getReuseAddress());
|
||||||
|
} else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
|
||||||
|
return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
|
||||||
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
|
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
|
||||||
return Integer.valueOf(socket.getTrafficClass());
|
return Integer.valueOf(socket.getTrafficClass());
|
||||||
} else if (option.equals(StandardSocketOptions.IP_MULTICAST_IF)) {
|
} else if (option.equals(StandardSocketOptions.IP_MULTICAST_IF)) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -141,8 +141,11 @@ public class Basic {
|
|||||||
try {
|
try {
|
||||||
// check supported options
|
// check supported options
|
||||||
Set<SocketOption<?>> options = ch.supportedOptions();
|
Set<SocketOption<?>> options = ch.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(SO_REUSEPORT);
|
||||||
if (!options.contains(SO_REUSEADDR))
|
if (!options.contains(SO_REUSEADDR))
|
||||||
throw new RuntimeException("SO_REUSEADDR should be supported");
|
throw new RuntimeException("SO_REUSEADDR should be supported");
|
||||||
|
if (!options.contains(SO_REUSEPORT) && reuseport)
|
||||||
|
throw new RuntimeException("SO_REUSEPORT should be supported");
|
||||||
if (!options.contains(SO_RCVBUF))
|
if (!options.contains(SO_RCVBUF))
|
||||||
throw new RuntimeException("SO_RCVBUF should be supported");
|
throw new RuntimeException("SO_RCVBUF should be supported");
|
||||||
|
|
||||||
@ -156,6 +159,13 @@ public class Basic {
|
|||||||
checkOption(ch, SO_REUSEADDR, true);
|
checkOption(ch, SO_REUSEADDR, true);
|
||||||
ch.setOption(SO_REUSEADDR, false);
|
ch.setOption(SO_REUSEADDR, false);
|
||||||
checkOption(ch, SO_REUSEADDR, false);
|
checkOption(ch, SO_REUSEADDR, false);
|
||||||
|
|
||||||
|
if (reuseport) {
|
||||||
|
ch.setOption(SO_REUSEPORT, true);
|
||||||
|
checkOption(ch, SO_REUSEPORT, true);
|
||||||
|
ch.setOption(SO_REUSEPORT, false);
|
||||||
|
checkOption(ch, SO_REUSEPORT, false);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
ch.close();
|
ch.close();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -37,6 +37,7 @@ import java.util.concurrent.*;
|
|||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.*;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class Basic {
|
public class Basic {
|
||||||
static final Random rand = new Random();
|
static final Random rand = new Random();
|
||||||
@ -165,6 +166,15 @@ public class Basic {
|
|||||||
// read others (can't check as actual value is implementation dependent)
|
// read others (can't check as actual value is implementation dependent)
|
||||||
ch.getOption(SO_RCVBUF);
|
ch.getOption(SO_RCVBUF);
|
||||||
ch.getOption(SO_SNDBUF);
|
ch.getOption(SO_SNDBUF);
|
||||||
|
|
||||||
|
Set<SocketOption<?>> options = ch.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(SO_REUSEPORT);
|
||||||
|
if (reuseport) {
|
||||||
|
if (ch.getOption(SO_REUSEPORT))
|
||||||
|
throw new RuntimeException("Default of SO_REUSEPORT should be 'false'");
|
||||||
|
if (!ch.setOption(SO_REUSEPORT, true).getOption(SO_REUSEPORT))
|
||||||
|
throw new RuntimeException("SO_REUSEPORT did not change");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -50,9 +50,17 @@ public class SocketOptionTests {
|
|||||||
|
|
||||||
// check supported options
|
// check supported options
|
||||||
Set<SocketOption<?>> options = dc.supportedOptions();
|
Set<SocketOption<?>> options = dc.supportedOptions();
|
||||||
List<? extends SocketOption<?>> expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
|
boolean reuseport = options.contains(SO_REUSEPORT);
|
||||||
SO_REUSEADDR, SO_BROADCAST, IP_TOS, IP_MULTICAST_IF, IP_MULTICAST_TTL,
|
List<? extends SocketOption<?>> expected;
|
||||||
IP_MULTICAST_LOOP);
|
if (reuseport) {
|
||||||
|
expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
|
||||||
|
SO_REUSEADDR, SO_REUSEPORT, SO_BROADCAST, IP_TOS, IP_MULTICAST_IF,
|
||||||
|
IP_MULTICAST_TTL, IP_MULTICAST_LOOP);
|
||||||
|
} else {
|
||||||
|
expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
|
||||||
|
SO_REUSEADDR, SO_BROADCAST, IP_TOS, IP_MULTICAST_IF, IP_MULTICAST_TTL,
|
||||||
|
IP_MULTICAST_LOOP);
|
||||||
|
}
|
||||||
for (SocketOption opt: expected) {
|
for (SocketOption opt: expected) {
|
||||||
if (!options.contains(opt))
|
if (!options.contains(opt))
|
||||||
throw new RuntimeException(opt.name() + " should be supported");
|
throw new RuntimeException(opt.name() + " should be supported");
|
||||||
@ -83,7 +91,12 @@ public class SocketOptionTests {
|
|||||||
checkOption(dc, SO_REUSEADDR, true);
|
checkOption(dc, SO_REUSEADDR, true);
|
||||||
dc.setOption(SO_REUSEADDR, false);
|
dc.setOption(SO_REUSEADDR, false);
|
||||||
checkOption(dc, SO_REUSEADDR, false);
|
checkOption(dc, SO_REUSEADDR, false);
|
||||||
|
if (reuseport) {
|
||||||
|
dc.setOption(SO_REUSEPORT, true);
|
||||||
|
checkOption(dc, SO_REUSEPORT, true);
|
||||||
|
dc.setOption(SO_REUSEPORT, false);
|
||||||
|
checkOption(dc, SO_REUSEPORT, false);
|
||||||
|
}
|
||||||
// bind socket
|
// bind socket
|
||||||
dc.bind(new InetSocketAddress(0));
|
dc.bind(new InetSocketAddress(0));
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -49,8 +49,11 @@ public class SocketOptionTests {
|
|||||||
|
|
||||||
// check supported options
|
// check supported options
|
||||||
Set<SocketOption<?>> options = ssc.supportedOptions();
|
Set<SocketOption<?>> options = ssc.supportedOptions();
|
||||||
|
boolean reuseport = options.contains(SO_REUSEPORT);
|
||||||
if (!options.contains(SO_REUSEADDR))
|
if (!options.contains(SO_REUSEADDR))
|
||||||
throw new RuntimeException("SO_REUSEADDR should be supported");
|
throw new RuntimeException("SO_REUSEADDR should be supported");
|
||||||
|
if (!options.contains(SO_REUSEPORT) && reuseport)
|
||||||
|
throw new RuntimeException("SO_REUSEPORT should be supported");
|
||||||
if (!options.contains(SO_RCVBUF))
|
if (!options.contains(SO_RCVBUF))
|
||||||
throw new RuntimeException("SO_RCVBUF should be supported");
|
throw new RuntimeException("SO_RCVBUF should be supported");
|
||||||
|
|
||||||
@ -64,6 +67,12 @@ public class SocketOptionTests {
|
|||||||
checkOption(ssc, SO_REUSEADDR, true);
|
checkOption(ssc, SO_REUSEADDR, true);
|
||||||
ssc.setOption(SO_REUSEADDR, false);
|
ssc.setOption(SO_REUSEADDR, false);
|
||||||
checkOption(ssc, SO_REUSEADDR, false);
|
checkOption(ssc, SO_REUSEADDR, false);
|
||||||
|
if (reuseport) {
|
||||||
|
ssc.setOption(SO_REUSEPORT, true);
|
||||||
|
checkOption(ssc, SO_REUSEPORT, true);
|
||||||
|
ssc.setOption(SO_REUSEPORT, false);
|
||||||
|
checkOption(ssc, SO_REUSEPORT, false);
|
||||||
|
}
|
||||||
|
|
||||||
// NullPointerException
|
// NullPointerException
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user