--- a/jdk/src/solaris/native/sun/nio/ch/Net.c Thu Nov 21 12:28:16 2013 -0800
+++ b/jdk/src/solaris/native/sun/nio/ch/Net.c Tue Nov 26 16:40:31 2013 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, 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
@@ -40,6 +40,9 @@
#include "nio.h"
#include "sun_nio_ch_PollArrayWrapper.h"
+#ifdef _AIX
+#include <sys/utsname.h>
+#endif
/**
* IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
@@ -51,24 +54,46 @@
#endif
#endif
-#ifdef _ALLBSD_SOURCE
+#if defined(_ALLBSD_SOURCE) || defined(_AIX)
#ifndef IP_BLOCK_SOURCE
+#if defined(_AIX)
+
+#define IP_BLOCK_SOURCE 58 /* Block data from a given source to a given group */
+#define IP_UNBLOCK_SOURCE 59 /* Unblock data from a given source to a given group */
+#define IP_ADD_SOURCE_MEMBERSHIP 60 /* Join a source-specific group */
+#define IP_DROP_SOURCE_MEMBERSHIP 61 /* Leave a source-specific group */
+
+#else
+
#define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */
#define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */
#define IP_BLOCK_SOURCE 72 /* block a source */
#define IP_UNBLOCK_SOURCE 73 /* unblock a source */
+#endif /* _AIX */
+
#endif /* IP_BLOCK_SOURCE */
#ifndef MCAST_BLOCK_SOURCE
+#if defined(_AIX)
+
+#define MCAST_BLOCK_SOURCE 64
+#define MCAST_UNBLOCK_SOURCE 65
+#define MCAST_JOIN_SOURCE_GROUP 66
+#define MCAST_LEAVE_SOURCE_GROUP 67
+
+#else
+
#define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */
#define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */
#define MCAST_BLOCK_SOURCE 84 /* block a source */
#define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */
+#endif /* _AIX */
+
#endif /* MCAST_BLOCK_SOURCE */
#ifndef IPV6_ADD_MEMBERSHIP
@@ -123,6 +148,36 @@
}
#endif
+#ifdef _AIX
+
+/*
+ * Checks whether or not "socket extensions for multicast source filters" is supported.
+ * Returns JNI_TRUE if it is supported, JNI_FALSE otherwise
+ */
+static jboolean isSourceFilterSupported(){
+ static jboolean alreadyChecked = JNI_FALSE;
+ static jboolean result = JNI_TRUE;
+ if (alreadyChecked != JNI_TRUE){
+ struct utsname uts;
+ memset(&uts, 0, sizeof(uts));
+ strcpy(uts.sysname, "?");
+ const int utsRes = uname(&uts);
+ int major = -1;
+ int minor = -1;
+ major = atoi(uts.version);
+ minor = atoi(uts.release);
+ if (strcmp(uts.sysname, "AIX") == 0) {
+ if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
+ result = JNI_FALSE;
+ }
+ }
+ alreadyChecked = JNI_TRUE;
+ }
+ return result;
+}
+
+#endif /* _AIX */
+
JNIEXPORT void JNICALL
Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
{
@@ -475,6 +530,14 @@
/* no IPv4 include-mode filtering for now */
return IOS_UNAVAILABLE;
#else
+
+#ifdef _AIX
+ /* check AIX for support of source filtering */
+ if (isSourceFilterSupported() != JNI_TRUE){
+ return IOS_UNAVAILABLE;
+ }
+#endif
+
mreq_source.imr_multiaddr.s_addr = htonl(group);
mreq_source.imr_sourceaddr.s_addr = htonl(source);
mreq_source.imr_interface.s_addr = htonl(interf);
@@ -486,7 +549,7 @@
n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
if (n < 0) {
- if (join && (errno == ENOPROTOOPT))
+ if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
return IOS_UNAVAILABLE;
handleSocketError(env, errno);
}
@@ -505,6 +568,13 @@
int n;
int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
+#ifdef _AIX
+ /* check AIX for support of source filtering */
+ if (isSourceFilterSupported() != JNI_TRUE){
+ return IOS_UNAVAILABLE;
+ }
+#endif
+
mreq_source.imr_multiaddr.s_addr = htonl(group);
mreq_source.imr_sourceaddr.s_addr = htonl(source);
mreq_source.imr_interface.s_addr = htonl(interf);
@@ -512,7 +582,7 @@
n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
(void*)&mreq_source, sizeof(mreq_source));
if (n < 0) {
- if (block && (errno == ENOPROTOOPT))
+ if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
return IOS_UNAVAILABLE;
handleSocketError(env, errno);
}
@@ -550,7 +620,7 @@
n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
if (n < 0) {
- if (join && (errno == ENOPROTOOPT))
+ if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
return IOS_UNAVAILABLE;
handleSocketError(env, errno);
}
@@ -579,7 +649,7 @@
n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
(void*)&req, sizeof(req));
if (n < 0) {
- if (block && (errno == ENOPROTOOPT))
+ if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
return IOS_UNAVAILABLE;
handleSocketError(env, errno);
}