jdk/src/solaris/native/sun/nio/ch/Net.c
changeset 22607 ba232b417248
parent 22573 8f0344f13b7f
parent 22605 dba3d6b22818
child 23016 1805013d2034
equal deleted inserted replaced
22585:cb36782f6044 22607:ba232b417248
     1 /*
     1 /*
     2  * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
       
    26 #include <sys/poll.h>
    26 #include <sys/types.h>
    27 #include <sys/types.h>
    27 #include <sys/socket.h>
    28 #include <sys/socket.h>
    28 #include <string.h>
    29 #include <string.h>
    29 #include <netinet/in.h>
    30 #include <netinet/in.h>
    30 #include <netinet/tcp.h>
    31 #include <netinet/tcp.h>
    38 #include "net_util_md.h"
    39 #include "net_util_md.h"
    39 #include "nio_util.h"
    40 #include "nio_util.h"
    40 #include "nio.h"
    41 #include "nio.h"
    41 #include "sun_nio_ch_PollArrayWrapper.h"
    42 #include "sun_nio_ch_PollArrayWrapper.h"
    42 
    43 
       
    44 #ifdef _AIX
       
    45 #include <sys/utsname.h>
       
    46 #endif
    43 
    47 
    44 /**
    48 /**
    45  * IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
    49  * IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
    46  * build time.
    50  * build time.
    47  */
    51  */
    50     #define IP_MULTICAST_ALL    49
    54     #define IP_MULTICAST_ALL    49
    51   #endif
    55   #endif
    52 #endif
    56 #endif
    53 
    57 
    54 /**
    58 /**
    55  * IPV6_ADD_MEMBERSHIP/IPV6_DROP_MEMBERSHIP may not be defined on OSX
    59  * IPV6_ADD_MEMBERSHIP/IPV6_DROP_MEMBERSHIP may not be defined on OSX and AIX
    56  */
    60  */
    57 #ifdef __APPLE__
    61 #if defined(__APPLE__) || defined(_AIX)
    58   #ifndef IPV6_ADD_MEMBERSHIP
    62   #ifndef IPV6_ADD_MEMBERSHIP
    59     #define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP
    63     #define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP
    60     #define IPV6_DROP_MEMBERSHIP    IPV6_LEAVE_GROUP
    64     #define IPV6_DROP_MEMBERSHIP    IPV6_LEAVE_GROUP
    61   #endif
    65   #endif
    62 #endif
    66 #endif
       
    67 
       
    68 #if defined(_AIX)
       
    69   #ifndef IP_BLOCK_SOURCE
       
    70     #define IP_BLOCK_SOURCE                 58   /* Block data from a given source to a given group */
       
    71     #define IP_UNBLOCK_SOURCE               59   /* Unblock data from a given source to a given group */
       
    72     #define IP_ADD_SOURCE_MEMBERSHIP        60   /* Join a source-specific group */
       
    73     #define IP_DROP_SOURCE_MEMBERSHIP       61   /* Leave a source-specific group */
       
    74   #endif
       
    75 
       
    76   #ifndef MCAST_BLOCK_SOURCE
       
    77     #define MCAST_BLOCK_SOURCE              64
       
    78     #define MCAST_UNBLOCK_SOURCE            65
       
    79     #define MCAST_JOIN_SOURCE_GROUP         66
       
    80     #define MCAST_LEAVE_SOURCE_GROUP        67
       
    81   #endif
       
    82 #endif /* _AIX */
    63 
    83 
    64 #define COPY_INET6_ADDRESS(env, source, target) \
    84 #define COPY_INET6_ADDRESS(env, source, target) \
    65     (*env)->GetByteArrayRegion(env, source, 0, 16, target)
    85     (*env)->GetByteArrayRegion(env, source, 0, 16, target)
    66 
    86 
    67 /*
    87 /*
    84     sin6->sin6_family = AF_INET6;
   104     sin6->sin6_family = AF_INET6;
    85     COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr));
   105     COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr));
    86 }
   106 }
    87 #endif
   107 #endif
    88 
   108 
       
   109 #ifdef _AIX
       
   110 
       
   111 /*
       
   112  * Checks whether or not "socket extensions for multicast source filters" is supported.
       
   113  * Returns JNI_TRUE if it is supported, JNI_FALSE otherwise
       
   114  */
       
   115 static jboolean isSourceFilterSupported(){
       
   116     static jboolean alreadyChecked = JNI_FALSE;
       
   117     static jboolean result = JNI_TRUE;
       
   118     if (alreadyChecked != JNI_TRUE){
       
   119         struct utsname uts;
       
   120         memset(&uts, 0, sizeof(uts));
       
   121         strcpy(uts.sysname, "?");
       
   122         const int utsRes = uname(&uts);
       
   123         int major = -1;
       
   124         int minor = -1;
       
   125         major = atoi(uts.version);
       
   126         minor = atoi(uts.release);
       
   127         if (strcmp(uts.sysname, "AIX") == 0) {
       
   128             if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
       
   129                 result = JNI_FALSE;
       
   130             }
       
   131         }
       
   132         alreadyChecked = JNI_TRUE;
       
   133     }
       
   134     return result;
       
   135 }
       
   136 
       
   137 #endif  /* _AIX */
       
   138 
    89 JNIEXPORT void JNICALL
   139 JNIEXPORT void JNICALL
    90 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
   140 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
    91 {
   141 {
    92     /* Here because Windows native code does need to init IDs */
   142     /* Here because Windows native code does need to init IDs */
    93 }
   143 }
   104 }
   154 }
   105 
   155 
   106 JNIEXPORT jboolean JNICALL
   156 JNIEXPORT jboolean JNICALL
   107 Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
   157 Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
   108 {
   158 {
   109 #ifdef __APPLE__
   159 #if defined(__APPLE__) || defined(_AIX)
   110     /* for now IPv6 sockets cannot join IPv4 multicast groups */
   160     /* for now IPv6 sockets cannot join IPv4 multicast groups */
   111     return JNI_FALSE;
   161     return JNI_FALSE;
   112 #else
   162 #else
   113     return JNI_TRUE;
   163     return JNI_TRUE;
   114 #endif
   164 #endif
   432         mreq.imr_interface.s_addr = htonl(interf);
   482         mreq.imr_interface.s_addr = htonl(interf);
   433         opt = (join) ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
   483         opt = (join) ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
   434         optval = (void*)&mreq;
   484         optval = (void*)&mreq;
   435         optlen = sizeof(mreq);
   485         optlen = sizeof(mreq);
   436     } else {
   486     } else {
       
   487 
       
   488 #ifdef _AIX
       
   489         /* check AIX for support of source filtering */
       
   490         if (isSourceFilterSupported() != JNI_TRUE){
       
   491             return IOS_UNAVAILABLE;
       
   492         }
       
   493 #endif
       
   494 
   437         mreq_source.imr_multiaddr.s_addr = htonl(group);
   495         mreq_source.imr_multiaddr.s_addr = htonl(group);
   438         mreq_source.imr_sourceaddr.s_addr = htonl(source);
   496         mreq_source.imr_sourceaddr.s_addr = htonl(source);
   439         mreq_source.imr_interface.s_addr = htonl(interf);
   497         mreq_source.imr_interface.s_addr = htonl(interf);
   440         opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
   498         opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
   441         optval = (void*)&mreq_source;
   499         optval = (void*)&mreq_source;
   442         optlen = sizeof(mreq_source);
   500         optlen = sizeof(mreq_source);
   443     }
   501     }
   444 
   502 
   445     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
   503     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
   446     if (n < 0) {
   504     if (n < 0) {
   447         if (join && (errno == ENOPROTOOPT))
   505         if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
   448             return IOS_UNAVAILABLE;
   506             return IOS_UNAVAILABLE;
   449         handleSocketError(env, errno);
   507         handleSocketError(env, errno);
   450     }
   508     }
   451     return 0;
   509     return 0;
   452 }
   510 }
   461 #else
   519 #else
   462     struct ip_mreq_source mreq_source;
   520     struct ip_mreq_source mreq_source;
   463     int n;
   521     int n;
   464     int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
   522     int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
   465 
   523 
       
   524 #ifdef _AIX
       
   525     /* check AIX for support of source filtering */
       
   526     if (isSourceFilterSupported() != JNI_TRUE){
       
   527         return IOS_UNAVAILABLE;
       
   528     }
       
   529 #endif
       
   530 
   466     mreq_source.imr_multiaddr.s_addr = htonl(group);
   531     mreq_source.imr_multiaddr.s_addr = htonl(group);
   467     mreq_source.imr_sourceaddr.s_addr = htonl(source);
   532     mreq_source.imr_sourceaddr.s_addr = htonl(source);
   468     mreq_source.imr_interface.s_addr = htonl(interf);
   533     mreq_source.imr_interface.s_addr = htonl(interf);
   469 
   534 
   470     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
   535     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
   471                    (void*)&mreq_source, sizeof(mreq_source));
   536                    (void*)&mreq_source, sizeof(mreq_source));
   472     if (n < 0) {
   537     if (n < 0) {
   473         if (block && (errno == ENOPROTOOPT))
   538         if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
   474             return IOS_UNAVAILABLE;
   539             return IOS_UNAVAILABLE;
   475         handleSocketError(env, errno);
   540         handleSocketError(env, errno);
   476     }
   541     }
   477     return 0;
   542     return 0;
   478 #endif
   543 #endif
   506 #endif
   571 #endif
   507     }
   572     }
   508 
   573 
   509     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
   574     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
   510     if (n < 0) {
   575     if (n < 0) {
   511         if (join && (errno == ENOPROTOOPT))
   576         if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
   512             return IOS_UNAVAILABLE;
   577             return IOS_UNAVAILABLE;
   513         handleSocketError(env, errno);
   578         handleSocketError(env, errno);
   514     }
   579     }
   515     return 0;
   580     return 0;
   516 #else
   581 #else
   535     initGroupSourceReq(env, group, index, source, &req);
   600     initGroupSourceReq(env, group, index, source, &req);
   536 
   601 
   537     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
   602     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
   538         (void*)&req, sizeof(req));
   603         (void*)&req, sizeof(req));
   539     if (n < 0) {
   604     if (n < 0) {
   540         if (block && (errno == ENOPROTOOPT))
   605         if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
   541             return IOS_UNAVAILABLE;
   606             return IOS_UNAVAILABLE;
   542         handleSocketError(env, errno);
   607         handleSocketError(env, errno);
   543     }
   608     }
   544     return 0;
   609     return 0;
   545   #endif
   610   #endif
   633         return IOS_INTERRUPTED;
   698         return IOS_INTERRUPTED;
   634     } else {
   699     } else {
   635         handleSocketError(env, errno);
   700         handleSocketError(env, errno);
   636         return IOS_THROWN;
   701         return IOS_THROWN;
   637     }
   702     }
       
   703 }
       
   704 
       
   705 JNIEXPORT jshort JNICALL
       
   706 Java_sun_nio_ch_Net_pollinValue(JNIEnv *env, jclass this)
       
   707 {
       
   708     return (jshort)POLLIN;
       
   709 }
       
   710 
       
   711 JNIEXPORT jshort JNICALL
       
   712 Java_sun_nio_ch_Net_polloutValue(JNIEnv *env, jclass this)
       
   713 {
       
   714     return (jshort)POLLOUT;
       
   715 }
       
   716 
       
   717 JNIEXPORT jshort JNICALL
       
   718 Java_sun_nio_ch_Net_pollerrValue(JNIEnv *env, jclass this)
       
   719 {
       
   720     return (jshort)POLLERR;
       
   721 }
       
   722 
       
   723 JNIEXPORT jshort JNICALL
       
   724 Java_sun_nio_ch_Net_pollhupValue(JNIEnv *env, jclass this)
       
   725 {
       
   726     return (jshort)POLLHUP;
       
   727 }
       
   728 
       
   729 JNIEXPORT jshort JNICALL
       
   730 Java_sun_nio_ch_Net_pollnvalValue(JNIEnv *env, jclass this)
       
   731 {
       
   732     return (jshort)POLLNVAL;
       
   733 }
       
   734 
       
   735 JNIEXPORT jshort JNICALL
       
   736 Java_sun_nio_ch_Net_pollconnValue(JNIEnv *env, jclass this)
       
   737 {
       
   738     return (jshort)POLLOUT;
   638 }
   739 }
   639 
   740 
   640 
   741 
   641 /* Declared in nio_util.h */
   742 /* Declared in nio_util.h */
   642 
   743