< prev index next >

src/solaris/native/sun/nio/ch/Net.c

Print this page
rev 8219 : 8024900: PPC64: Enable new build on AIX (jdk part)
8024854: PPC64: Basic changes and files to build the class library on AIX
Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan, art, erikj
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com

@@ -37,28 +37,52 @@
 #include "net_util.h"
 #include "net_util_md.h"
 #include "nio_util.h"
 #include "nio.h"
 
-#ifdef _ALLBSD_SOURCE
+#ifdef AIX
+#include <sys/utsname.h>
+#endif
+
+#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_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 */
+
+#define MCAST_BLOCK_SOURCE              64
+#define MCAST_UNBLOCK_SOURCE            65
+#define MCAST_JOIN_SOURCE_GROUP         66
+#define MCAST_LEAVE_SOURCE_GROUP        67
+
 #endif /* MCAST_BLOCK_SOURCE */
 
 #ifndef IPV6_ADD_MEMBERSHIP
 
 #define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP

@@ -87,10 +111,11 @@
 
 
 #define COPY_INET6_ADDRESS(env, source, target) \
     (*env)->GetByteArrayRegion(env, source, 0, 16, target)
 
+
 /*
  * Copy IPv6 group, interface index, and IPv6 source address
  * into group_source_req structure.
  */
 #ifdef AF_INET6

@@ -109,10 +134,44 @@
     sin6->sin6_family = AF_INET6;
     COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr));
 }
 #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, "OS400") == 0){// usupported on OS400 < 7.1
+            if (major < 7 || (major == 7 && minor < 1)) {
+                result = JNI_FALSE;
+            }
+         } else if (strcmp(uts.sysname, "AIX") == 0) {
+            if (major < 6 || (major == 6 && minor < 1)) {// usupported 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)
 {
     /* Here because Windows native code does need to init IDs */
 }

@@ -452,10 +511,19 @@
     } else {
 #ifdef MACOSX
         /* no IPv4 include-mode filtering for now */
         return IOS_UNAVAILABLE;
 #else
+
+#ifdef _AIX
+        /* check AIX and OS400 for support of source filtering */
+        if (isSourceFilterSupported() != JNI_TRUE){
+            JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
+            return -1;
+        }
+#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);
         opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
         optval = (void*)&mreq_source;

@@ -463,13 +531,21 @@
 #endif
     }
 
     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
     if (n < 0) {
-        if (join && (errno == ENOPROTOOPT))
+        /* catch genreric unsupported error for 'socket extension for multicast source filter'
+         * I did not put this inside function handleSocketError to prevent any changes in behaviour of other calls.
+         */
+        int last_err = errno;
+        if (join && source && (last_err == EOPNOTSUPP)){
+            JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
+            return -1;
+        }
+        if (join && (last_err == ENOPROTOOPT))
             return IOS_UNAVAILABLE;
-        handleSocketError(env, errno);
+        handleSocketError(env, last_err);
     }
     return 0;
 }
 
 JNIEXPORT jint JNICALL

@@ -482,20 +558,36 @@
 #else
     struct my_ip_mreq_source mreq_source;
     int n;
     int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
 
+#ifdef _AIX
+    /* check AIX and OS400 for support of source filtering */
+    if (isSourceFilterSupported() != JNI_TRUE){
+        JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
+        return -1;
+    }
+#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);
 
     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
                    (void*)&mreq_source, sizeof(mreq_source));
     if (n < 0) {
-        if (block && (errno == ENOPROTOOPT))
+        /* catch generic unsupported error for 'socket extension for multicast source filter'
+         * I did not put this inside function handleSocketError to prevent any changes in behaviour of other calls.
+         */
+        int last_err = errno;
+        if (block && source && (last_err == EOPNOTSUPP)){
+            JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
+            return -1;
+        }
+        if (block && (last_err == ENOPROTOOPT))
             return IOS_UNAVAILABLE;
-        handleSocketError(env, errno);
+        handleSocketError(env, last_err);
     }
     return 0;
 #endif
 }
 

@@ -527,13 +619,21 @@
 #endif
     }
 
     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
     if (n < 0) {
-        if (join && (errno == ENOPROTOOPT))
+        /* catch genreric unsupported error for 'socket extension for multicast source filter'
+         * I did not put this inside function handleSocketError to prevent any changes in behaviour of other calls.
+         */
+        int last_err = errno;
+        if (join && source && (last_err == EOPNOTSUPP)) {
+            JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
+            return -1;
+        }
+        if (join && (last_err == ENOPROTOOPT))
             return IOS_UNAVAILABLE;
-        handleSocketError(env, errno);
+        handleSocketError(env, last_err);
     }
     return 0;
 #else
     JNU_ThrowInternalError(env, "Should not get here");
     return IOS_THROWN;

@@ -556,13 +656,21 @@
     initGroupSourceReq(env, group, index, source, &req);
 
     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
         (void*)&req, sizeof(req));
     if (n < 0) {
-        if (block && (errno == ENOPROTOOPT))
+        /* catch genreric unsupported error for 'socket extension for multicast source filter'
+         * I did not put this inside function handleSocketError to prevent any changes in behaviour of other calls.
+         */
+        int last_err = errno;
+        if (block && source && (last_err == EOPNOTSUPP)) {
+            JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
+            return -1;
+        }
+        if (block && (last_err == ENOPROTOOPT))
             return IOS_UNAVAILABLE;
-        handleSocketError(env, errno);
+        handleSocketError(env, last_err);
     }
     return 0;
   #endif
 #else
     JNU_ThrowInternalError(env, "Should not get here");
< prev index next >