jdk/src/solaris/native/sun/nio/ch/Net.c
changeset 22597 7515a991bb37
parent 18535 71b74ae0ab8a
child 22604 9b394795e216
equal deleted inserted replaced
22596:62542b8be764 22597:7515a991bb37
     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
    38 #include "net_util_md.h"
    38 #include "net_util_md.h"
    39 #include "nio_util.h"
    39 #include "nio_util.h"
    40 #include "nio.h"
    40 #include "nio.h"
    41 #include "sun_nio_ch_PollArrayWrapper.h"
    41 #include "sun_nio_ch_PollArrayWrapper.h"
    42 
    42 
       
    43 #ifdef _AIX
       
    44 #include <sys/utsname.h>
       
    45 #endif
    43 
    46 
    44 /**
    47 /**
    45  * IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
    48  * IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
    46  * build time.
    49  * build time.
    47  */
    50  */
    49   #ifndef IP_MULTICAST_ALL
    52   #ifndef IP_MULTICAST_ALL
    50   #define IP_MULTICAST_ALL    49
    53   #define IP_MULTICAST_ALL    49
    51   #endif
    54   #endif
    52 #endif
    55 #endif
    53 
    56 
    54 #ifdef _ALLBSD_SOURCE
    57 #if defined(_ALLBSD_SOURCE) || defined(_AIX)
    55 
    58 
    56 #ifndef IP_BLOCK_SOURCE
    59 #ifndef IP_BLOCK_SOURCE
       
    60 
       
    61 #if defined(_AIX)
       
    62 
       
    63 #define IP_BLOCK_SOURCE                 58   /* Block data from a given source to a given group */
       
    64 #define IP_UNBLOCK_SOURCE               59   /* Unblock data from a given source to a given group */
       
    65 #define IP_ADD_SOURCE_MEMBERSHIP        60   /* Join a source-specific group */
       
    66 #define IP_DROP_SOURCE_MEMBERSHIP       61   /* Leave a source-specific group */
       
    67 
       
    68 #else
    57 
    69 
    58 #define IP_ADD_SOURCE_MEMBERSHIP        70   /* join a source-specific group */
    70 #define IP_ADD_SOURCE_MEMBERSHIP        70   /* join a source-specific group */
    59 #define IP_DROP_SOURCE_MEMBERSHIP       71   /* drop a single source */
    71 #define IP_DROP_SOURCE_MEMBERSHIP       71   /* drop a single source */
    60 #define IP_BLOCK_SOURCE                 72   /* block a source */
    72 #define IP_BLOCK_SOURCE                 72   /* block a source */
    61 #define IP_UNBLOCK_SOURCE               73   /* unblock a source */
    73 #define IP_UNBLOCK_SOURCE               73   /* unblock a source */
    62 
    74 
       
    75 #endif /* _AIX */
       
    76 
    63 #endif  /* IP_BLOCK_SOURCE */
    77 #endif  /* IP_BLOCK_SOURCE */
    64 
    78 
    65 #ifndef MCAST_BLOCK_SOURCE
    79 #ifndef MCAST_BLOCK_SOURCE
       
    80 
       
    81 #if defined(_AIX)
       
    82 
       
    83 #define MCAST_BLOCK_SOURCE              64
       
    84 #define MCAST_UNBLOCK_SOURCE            65
       
    85 #define MCAST_JOIN_SOURCE_GROUP         66
       
    86 #define MCAST_LEAVE_SOURCE_GROUP        67
       
    87 
       
    88 #else
    66 
    89 
    67 #define MCAST_JOIN_SOURCE_GROUP         82   /* join a source-specific group */
    90 #define MCAST_JOIN_SOURCE_GROUP         82   /* join a source-specific group */
    68 #define MCAST_LEAVE_SOURCE_GROUP        83   /* leave a single source */
    91 #define MCAST_LEAVE_SOURCE_GROUP        83   /* leave a single source */
    69 #define MCAST_BLOCK_SOURCE              84   /* block a source */
    92 #define MCAST_BLOCK_SOURCE              84   /* block a source */
    70 #define MCAST_UNBLOCK_SOURCE            85   /* unblock a source */
    93 #define MCAST_UNBLOCK_SOURCE            85   /* unblock a source */
       
    94 
       
    95 #endif /* _AIX */
    71 
    96 
    72 #endif /* MCAST_BLOCK_SOURCE */
    97 #endif /* MCAST_BLOCK_SOURCE */
    73 
    98 
    74 #ifndef IPV6_ADD_MEMBERSHIP
    99 #ifndef IPV6_ADD_MEMBERSHIP
    75 
   100 
   120     sin6 = (struct sockaddr_in6*)&(req->gsr_source);
   145     sin6 = (struct sockaddr_in6*)&(req->gsr_source);
   121     sin6->sin6_family = AF_INET6;
   146     sin6->sin6_family = AF_INET6;
   122     COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr));
   147     COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr));
   123 }
   148 }
   124 #endif
   149 #endif
       
   150 
       
   151 #ifdef _AIX
       
   152 
       
   153 /*
       
   154  * Checks whether or not "socket extensions for multicast source filters" is supported.
       
   155  * Returns JNI_TRUE if it is supported, JNI_FALSE otherwise
       
   156  */
       
   157 static jboolean isSourceFilterSupported(){
       
   158     static jboolean alreadyChecked = JNI_FALSE;
       
   159     static jboolean result = JNI_TRUE;
       
   160     if (alreadyChecked != JNI_TRUE){
       
   161         struct utsname uts;
       
   162         memset(&uts, 0, sizeof(uts));
       
   163         strcpy(uts.sysname, "?");
       
   164         const int utsRes = uname(&uts);
       
   165         int major = -1;
       
   166         int minor = -1;
       
   167         major = atoi(uts.version);
       
   168         minor = atoi(uts.release);
       
   169         if (strcmp(uts.sysname, "AIX") == 0) {
       
   170             if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
       
   171                 result = JNI_FALSE;
       
   172             }
       
   173         }
       
   174         alreadyChecked = JNI_TRUE;
       
   175     }
       
   176     return result;
       
   177 }
       
   178 
       
   179 #endif  /* _AIX */
   125 
   180 
   126 JNIEXPORT void JNICALL
   181 JNIEXPORT void JNICALL
   127 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
   182 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
   128 {
   183 {
   129     /* Here because Windows native code does need to init IDs */
   184     /* Here because Windows native code does need to init IDs */
   473     } else {
   528     } else {
   474 #ifdef MACOSX
   529 #ifdef MACOSX
   475         /* no IPv4 include-mode filtering for now */
   530         /* no IPv4 include-mode filtering for now */
   476         return IOS_UNAVAILABLE;
   531         return IOS_UNAVAILABLE;
   477 #else
   532 #else
       
   533 
       
   534 #ifdef _AIX
       
   535         /* check AIX for support of source filtering */
       
   536         if (isSourceFilterSupported() != JNI_TRUE){
       
   537             return IOS_UNAVAILABLE;
       
   538         }
       
   539 #endif
       
   540 
   478         mreq_source.imr_multiaddr.s_addr = htonl(group);
   541         mreq_source.imr_multiaddr.s_addr = htonl(group);
   479         mreq_source.imr_sourceaddr.s_addr = htonl(source);
   542         mreq_source.imr_sourceaddr.s_addr = htonl(source);
   480         mreq_source.imr_interface.s_addr = htonl(interf);
   543         mreq_source.imr_interface.s_addr = htonl(interf);
   481         opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
   544         opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
   482         optval = (void*)&mreq_source;
   545         optval = (void*)&mreq_source;
   484 #endif
   547 #endif
   485     }
   548     }
   486 
   549 
   487     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
   550     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
   488     if (n < 0) {
   551     if (n < 0) {
   489         if (join && (errno == ENOPROTOOPT))
   552         if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
   490             return IOS_UNAVAILABLE;
   553             return IOS_UNAVAILABLE;
   491         handleSocketError(env, errno);
   554         handleSocketError(env, errno);
   492     }
   555     }
   493     return 0;
   556     return 0;
   494 }
   557 }
   503 #else
   566 #else
   504     struct my_ip_mreq_source mreq_source;
   567     struct my_ip_mreq_source mreq_source;
   505     int n;
   568     int n;
   506     int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
   569     int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
   507 
   570 
       
   571 #ifdef _AIX
       
   572     /* check AIX for support of source filtering */
       
   573     if (isSourceFilterSupported() != JNI_TRUE){
       
   574         return IOS_UNAVAILABLE;
       
   575     }
       
   576 #endif
       
   577 
   508     mreq_source.imr_multiaddr.s_addr = htonl(group);
   578     mreq_source.imr_multiaddr.s_addr = htonl(group);
   509     mreq_source.imr_sourceaddr.s_addr = htonl(source);
   579     mreq_source.imr_sourceaddr.s_addr = htonl(source);
   510     mreq_source.imr_interface.s_addr = htonl(interf);
   580     mreq_source.imr_interface.s_addr = htonl(interf);
   511 
   581 
   512     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
   582     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
   513                    (void*)&mreq_source, sizeof(mreq_source));
   583                    (void*)&mreq_source, sizeof(mreq_source));
   514     if (n < 0) {
   584     if (n < 0) {
   515         if (block && (errno == ENOPROTOOPT))
   585         if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
   516             return IOS_UNAVAILABLE;
   586             return IOS_UNAVAILABLE;
   517         handleSocketError(env, errno);
   587         handleSocketError(env, errno);
   518     }
   588     }
   519     return 0;
   589     return 0;
   520 #endif
   590 #endif
   548 #endif
   618 #endif
   549     }
   619     }
   550 
   620 
   551     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
   621     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
   552     if (n < 0) {
   622     if (n < 0) {
   553         if (join && (errno == ENOPROTOOPT))
   623         if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
   554             return IOS_UNAVAILABLE;
   624             return IOS_UNAVAILABLE;
   555         handleSocketError(env, errno);
   625         handleSocketError(env, errno);
   556     }
   626     }
   557     return 0;
   627     return 0;
   558 #else
   628 #else
   577     initGroupSourceReq(env, group, index, source, &req);
   647     initGroupSourceReq(env, group, index, source, &req);
   578 
   648 
   579     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
   649     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
   580         (void*)&req, sizeof(req));
   650         (void*)&req, sizeof(req));
   581     if (n < 0) {
   651     if (n < 0) {
   582         if (block && (errno == ENOPROTOOPT))
   652         if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
   583             return IOS_UNAVAILABLE;
   653             return IOS_UNAVAILABLE;
   584         handleSocketError(env, errno);
   654         handleSocketError(env, errno);
   585     }
   655     }
   586     return 0;
   656     return 0;
   587   #endif
   657   #endif