8293842: IPv6-only systems throws UnsupportedOperationException for several socket/TCP options

Co-authored-by: Martin Buchholz <martin@openjdk.org>
Reviewed-by: djelinski, dfuchs
This commit is contained in:
Man Cao 2022-09-15 22:06:18 +00:00
parent bb9aa4eae6
commit 9a40b76ac5
5 changed files with 25 additions and 9 deletions

View file

@ -30,7 +30,7 @@
int IPv4_supported(); int IPv4_supported();
int IPv6_supported(); int IPv6_supported();
int reuseport_supported(); int reuseport_supported(int ipv6_available);
static int IPv4_available; static int IPv4_available;
static int IPv6_available; static int IPv6_available;
@ -80,7 +80,7 @@ DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
IPv6_available = IPv6_supported() & (!preferIPv4Stack); IPv6_available = IPv6_supported() & (!preferIPv4Stack);
/* check if SO_REUSEPORT is supported on this platform */ /* check if SO_REUSEPORT is supported on this platform */
REUSEPORT_available = reuseport_supported(); REUSEPORT_available = reuseport_supported(IPv6_available);
platformInit(); platformInit();
return JNI_VERSION_1_2; return JNI_VERSION_1_2;

View file

@ -187,12 +187,16 @@ jint IPv6_supported()
} }
#endif /* DONT_ENABLE_IPV6 */ #endif /* DONT_ENABLE_IPV6 */
jint reuseport_supported() jint reuseport_supported(int ipv6_available)
{ {
/* Do a simple dummy call, and try to figure out from that */ /* Do a simple dummy call, and try to figure out from that */
int one = 1; int one = 1;
int rv, s; int rv, s;
if (ipv6_available) {
s = socket(PF_INET6, SOCK_STREAM, 0);
} else {
s = socket(PF_INET, SOCK_STREAM, 0); s = socket(PF_INET, SOCK_STREAM, 0);
}
if (s < 0) { if (s < 0) {
return JNI_FALSE; return JNI_FALSE;
} }

View file

@ -235,7 +235,7 @@ jint IPv6_supported()
return JNI_TRUE; return JNI_TRUE;
} }
jint reuseport_supported() jint reuseport_supported(int ipv6_available)
{ {
/* SO_REUSEPORT is not supported on Windows */ /* SO_REUSEPORT is not supported on Windows */
return JNI_FALSE; return JNI_FALSE;

View file

@ -54,10 +54,16 @@ static jint socketOptionSupported(jint level, jint optname) {
jint one = 1; jint one = 1;
jint rv, s; jint rv, s;
socklen_t sz = sizeof (one); socklen_t sz = sizeof (one);
/* First try IPv6; fall back to IPv4. */
s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (s < 0) {
if (errno == EPFNOSUPPORT || errno == EAFNOSUPPORT) {
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
}
if (s < 0) { if (s < 0) {
return 0; return 0;
} }
}
rv = getsockopt(s, level, optname, (void *) &one, &sz); rv = getsockopt(s, level, optname, (void *) &one, &sz);
if (rv != 0 && errno == ENOPROTOOPT) { if (rv != 0 && errno == ENOPROTOOPT) {
rv = 0; rv = 0;

View file

@ -48,10 +48,16 @@ DEF_STATIC_JNI_OnLoad
static jint socketOptionSupported(jint sockopt) { static jint socketOptionSupported(jint sockopt) {
jint one = 1; jint one = 1;
jint rv, s; jint rv, s;
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); /* First try IPv6; fall back to IPv4. */
s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (s < 0) {
if (errno == EPFNOSUPPORT || errno == EAFNOSUPPORT) {
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
}
if (s < 0) { if (s < 0) {
return 0; return 0;
} }
}
rv = setsockopt(s, IPPROTO_TCP, sockopt, (void *) &one, sizeof (one)); rv = setsockopt(s, IPPROTO_TCP, sockopt, (void *) &one, sizeof (one));
if (rv != 0 && errno == ENOPROTOOPT) { if (rv != 0 && errno == ENOPROTOOPT) {
rv = 0; rv = 0;