< prev index next >

src/java.base/unix/native/libnio/ch/Net.c

Print this page
rev 57536 : [mq]: Cleanup
   1 /*
   2  * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  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


  24  */
  25 
  26 #include <poll.h>
  27 #include <sys/types.h>
  28 #include <sys/socket.h>
  29 #include <string.h>
  30 #include <netinet/in.h>
  31 #include <netinet/tcp.h>
  32 #include <limits.h>
  33 
  34 #include "jni.h"
  35 #include "jni_util.h"
  36 #include "jvm.h"
  37 #include "jlong.h"
  38 #include "sun_nio_ch_Net.h"
  39 #include "net_util.h"
  40 #include "net_util_md.h"
  41 #include "nio_util.h"
  42 #include "nio.h"
  43 
  44 #ifdef _AIX
  45 #include <stdlib.h>
  46 #include <sys/utsname.h>



  47 #endif
  48 
  49 /**
  50  * IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
  51  * build time.
  52  */
  53 #ifdef __linux__
  54   #ifndef IP_MULTICAST_ALL
  55     #define IP_MULTICAST_ALL    49
  56   #endif
  57 #endif
  58 
  59 /**
  60  * IPV6_ADD_MEMBERSHIP/IPV6_DROP_MEMBERSHIP may not be defined on OSX and AIX
  61  */
  62 #if defined(__APPLE__) || defined(_AIX)
  63   #ifndef IPV6_ADD_MEMBERSHIP
  64     #define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP
  65     #define IPV6_DROP_MEMBERSHIP    IPV6_LEAVE_GROUP
  66   #endif
  67 #endif
  68 
  69 #define COPY_INET6_ADDRESS(env, source, target) \
  70     (*env)->GetByteArrayRegion(env, source, 0, 16, target)
  71 
  72 /*
  73  * Copy IPv6 group, interface index, and IPv6 source address
  74  * into group_source_req structure.
  75  */
  76 static void initGroupSourceReq(JNIEnv* env, jbyteArray group, jint index,
  77                                jbyteArray source, struct group_source_req *req)
  78 {
  79     struct sockaddr_in6* sin6;
  80 
  81     req->gsr_interface = (uint32_t)index;
  82 
  83     sin6 = (struct sockaddr_in6 *)&(req->gsr_group);
  84     sin6->sin6_family = AF_INET6;
  85     COPY_INET6_ADDRESS(env, group, (jbyte *)&(sin6->sin6_addr));
  86 
  87     sin6 = (struct sockaddr_in6 *)&(req->gsr_source);
  88     sin6->sin6_family = AF_INET6;
  89     COPY_INET6_ADDRESS(env, source, (jbyte *)&(sin6->sin6_addr));
  90 }
  91 
  92 #ifdef _AIX
  93 
  94 /*
  95  * Checks whether or not "socket extensions for multicast source filters" is supported.
  96  * Returns JNI_TRUE if it is supported, JNI_FALSE otherwise
  97  */
  98 static jboolean isSourceFilterSupported(){
  99     static jboolean alreadyChecked = JNI_FALSE;
 100     static jboolean result = JNI_TRUE;
 101     if (alreadyChecked != JNI_TRUE){
 102         struct utsname uts;
 103         memset(&uts, 0, sizeof(uts));
 104         strcpy(uts.sysname, "?");
 105         const int utsRes = uname(&uts);
 106         int major = -1;
 107         int minor = -1;
 108         major = atoi(uts.version);
 109         minor = atoi(uts.release);
 110         if (strcmp(uts.sysname, "AIX") == 0) {
 111             if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
 112                 result = JNI_FALSE;
 113             }
 114         }
 115         alreadyChecked = JNI_TRUE;
 116     }
 117     return result;
 118 }
 119 
 120 #endif  /* _AIX */
 121 
 122 static jclass isa_class;        /* java.net.InetSocketAddress */
 123 static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
 124 
 125 JNIEXPORT void JNICALL
 126 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
 127 {
 128      jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
 129      CHECK_NULL(cls);
 130      isa_class = (*env)->NewGlobalRef(env, cls);
 131      if (isa_class == NULL) {
 132          JNU_ThrowOutOfMemoryError(env, NULL);
 133          return;
 134      }
 135      isa_ctorID = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/net/InetAddress;I)V");
 136      CHECK_NULL(isa_ctorID);
 137 
 138      initInetAddressIDs(env);
 139 }
 140 
 141 JNIEXPORT jboolean JNICALL


 166     return JNI_FALSE;
 167 #endif
 168 }
 169 
 170 JNIEXPORT jboolean JNICALL
 171 Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
 172 {
 173 #if defined(__linux__) || defined(__APPLE__) || defined(__solaris__)
 174     /* IPv6 sockets can join IPv4 multicast groups */
 175     return JNI_TRUE;
 176 #else
 177     /* IPv6 sockets cannot join IPv4 multicast groups */
 178     return JNI_FALSE;
 179 #endif
 180 }
 181 
 182 JNIEXPORT jboolean JNICALL
 183 Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
 184 {
 185 #if defined(__APPLE__) || defined(__solaris__)
 186     /* IPV6_ADD_MEMBERSHIP can be used to join IPv4 multicast groups */
 187     return JNI_TRUE;
 188 #else
 189     /* IPV6_ADD_MEMBERSHIP cannot be used to join IPv4 multicast groups */
 190     return JNI_FALSE;
 191 #endif
 192 }
 193 
 194 JNIEXPORT jboolean JNICALL
 195 Java_sun_nio_ch_Net_canUseIPv6OptionsWithIPv4LocalAddress0(JNIEnv* env, jclass cl)
 196 {
 197     /* IPV6_XXX socket options can be used on IPv6 sockets bound to IPv4 address */
 198     return JNI_TRUE;
 199 }
 200 
 201 JNIEXPORT jint JNICALL
 202 Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
 203                             jboolean stream, jboolean reuse, jboolean ignored)
 204 {
 205     int fd;
 206     int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
 207     int domain = (ipv6_available() && preferIPv6) ? AF_INET6 : AF_INET;
 208 
 209     fd = socket(domain, type, 0);


 539         } else {
 540             linger.l_onoff = 0;
 541             linger.l_linger = 0;
 542         }
 543     }
 544 
 545     if (mayNeedConversion) {
 546         n = NET_SetSockOpt(fdval(env, fdo), level, opt, parg, arglen);
 547     } else {
 548         n = setsockopt(fdval(env, fdo), level, opt, parg, arglen);
 549     }
 550     if (n < 0) {
 551         JNU_ThrowByNameWithLastError(env,
 552                                      JNU_JAVANETPKG "SocketException",
 553                                      "sun.nio.ch.Net.setIntOption");
 554     }
 555 }
 556 
 557 JNIEXPORT jint JNICALL
 558 Java_sun_nio_ch_Net_joinOrDrop4(JNIEnv *env, jobject this, jboolean join, jobject fdo,
 559                                 jint group, jint interf, jint source)
 560 {
 561     struct ip_mreq mreq;
 562     struct ip_mreq_source mreq_source;
 563     int opt, n, optlen;
 564     void* optval;
 565 
 566     if (source == 0) {
 567         mreq.imr_multiaddr.s_addr = htonl(group);
 568         mreq.imr_interface.s_addr = htonl(interf);
 569         opt = (join) ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
 570         optval = (void*)&mreq;
 571         optlen = sizeof(mreq);
 572     } else {
 573 
 574 #ifdef _AIX
 575         /* check AIX for support of source filtering */
 576         if (isSourceFilterSupported() != JNI_TRUE){
 577             return IOS_UNAVAILABLE;
 578         }
 579 #endif
 580 








 581         mreq_source.imr_multiaddr.s_addr = htonl(group);

 582         mreq_source.imr_sourceaddr.s_addr = htonl(source);
 583         mreq_source.imr_interface.s_addr = htonl(interf);
 584         opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
 585         optval = (void*)&mreq_source;
 586         optlen = sizeof(mreq_source);
 587     }
 588 
 589     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
 590     if (n < 0) {
 591         if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
 592             return IOS_UNAVAILABLE;
 593         handleSocketError(env, errno);
 594     }
 595     return 0;
 596 }
 597 
 598 JNIEXPORT jint JNICALL
 599 Java_sun_nio_ch_Net_blockOrUnblock4(JNIEnv *env, jobject this, jboolean block, jobject fdo,
 600                                     jint group, jint interf, jint source)
 601 {
 602 #ifdef __APPLE__
 603     /* no IPv4 exclude-mode filtering for now */
 604     return IOS_UNAVAILABLE;
 605 #else
 606     struct ip_mreq_source mreq_source;
 607     int n;







 608     int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
 609 
 610 #ifdef _AIX
 611     /* check AIX for support of source filtering */
 612     if (isSourceFilterSupported() != JNI_TRUE){
 613         return IOS_UNAVAILABLE;
 614     }
 615 #endif
 616 
 617     mreq_source.imr_multiaddr.s_addr = htonl(group);

 618     mreq_source.imr_sourceaddr.s_addr = htonl(source);
 619     mreq_source.imr_interface.s_addr = htonl(interf);
 620 
 621     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
 622                    (void*)&mreq_source, sizeof(mreq_source));
 623     if (n < 0) {
 624         if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
 625             return IOS_UNAVAILABLE;
 626         handleSocketError(env, errno);
 627     }
 628     return 0;
 629 #endif
 630 }
 631 
 632 JNIEXPORT jint JNICALL
 633 Java_sun_nio_ch_Net_joinOrDrop6(JNIEnv *env, jobject this, jboolean join, jobject fdo,
 634                                 jbyteArray group, jint index, jbyteArray source)
 635 {
 636     struct ipv6_mreq mreq6;









 637     struct group_source_req req;
 638     int opt, n, optlen;
 639     void* optval;
 640 





 641     if (source == NULL) {
 642         COPY_INET6_ADDRESS(env, group, (jbyte*)&(mreq6.ipv6mr_multiaddr));

 643         mreq6.ipv6mr_interface = (int)index;
 644         opt = (join) ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP;
 645         optval = (void*)&mreq6;
 646         optlen = sizeof(mreq6);
 647     } else {
 648 #ifdef __APPLE__
 649         /* no IPv6 include-mode filtering for now */
 650         return IOS_UNAVAILABLE;
 651 #else
 652         initGroupSourceReq(env, group, index, source, &req);
 653         opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP;
 654         optval = (void*)&req;
 655         optlen = sizeof(req);
 656 #endif
 657     }
 658 
 659     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
 660     if (n < 0) {
 661         if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
 662             return IOS_UNAVAILABLE;
 663         handleSocketError(env, errno);
 664     }
 665     return 0;
 666 }
 667 
 668 JNIEXPORT jint JNICALL
 669 Java_sun_nio_ch_Net_blockOrUnblock6(JNIEnv *env, jobject this, jboolean block, jobject fdo,
 670                                     jbyteArray group, jint index, jbyteArray source)
 671 {
 672 #ifdef __APPLE__
 673     /* no IPv6 exclude-mode filtering for now */
 674     return IOS_UNAVAILABLE;
 675 #else
 676     struct group_source_req req;
 677     int n;
 678     int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE;
 679 
 680     initGroupSourceReq(env, group, index, source, &req);
 681 
 682     n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
 683         (void*)&req, sizeof(req));
 684     if (n < 0) {
 685         if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
 686             return IOS_UNAVAILABLE;
 687         handleSocketError(env, errno);
 688     }
 689     return 0;
 690 #endif



 691 }
 692 
 693 JNIEXPORT void JNICALL
 694 Java_sun_nio_ch_Net_setInterface4(JNIEnv* env, jobject this, jobject fdo, jint interf)
 695 {
 696     struct in_addr in;
 697     socklen_t arglen = sizeof(struct in_addr);
 698     int n;
 699 
 700     in.s_addr = htonl(interf);
 701 
 702     n = setsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF,
 703                    (void*)&(in.s_addr), arglen);
 704     if (n < 0) {
 705         handleSocketError(env, errno);
 706     }
 707 }
 708 
 709 JNIEXPORT jint JNICALL
 710 Java_sun_nio_ch_Net_getInterface4(JNIEnv* env, jobject this, jobject fdo)
 711 {
 712     struct in_addr in;
 713     socklen_t arglen = sizeof(struct in_addr);
 714     int n;
 715 
 716     n = getsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF, (void*)&in, &arglen);
 717     if (n < 0) {
 718         handleSocketError(env, errno);
 719         return -1;
 720     }
 721     return ntohl(in.s_addr);


   1 /*
   2  * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  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


  24  */
  25 
  26 #include <poll.h>
  27 #include <sys/types.h>
  28 #include <sys/socket.h>
  29 #include <string.h>
  30 #include <netinet/in.h>
  31 #include <netinet/tcp.h>
  32 #include <limits.h>
  33 
  34 #include "jni.h"
  35 #include "jni_util.h"
  36 #include "jvm.h"
  37 #include "jlong.h"
  38 #include "sun_nio_ch_Net.h"
  39 #include "net_util.h"
  40 #include "net_util_md.h"
  41 #include "nio_util.h"
  42 #include "nio.h"
  43 
  44 /**
  45  * Use MCAST_JOIN_GROUP/MCAST_BLOCK_SOURCE on platforms that support it.
  46  */
  47 #if defined(__linux__) || defined(__solaris__)
  48   #include "nio_multicast.h"
  49   #define USE_MCAST_XXX  1
  50 #endif
  51 
  52 /**
  53  * IP_MULTICAST_ALL supported since 2.6.31 (and glibc 2.15) but may not be
  54  * available at build time.
  55  */
  56 #ifdef __linux__
  57   #ifndef IP_MULTICAST_ALL
  58     #define IP_MULTICAST_ALL    49
  59   #endif
  60 #endif
  61 































































  62 static jclass isa_class;        /* java.net.InetSocketAddress */
  63 static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
  64 
  65 JNIEXPORT void JNICALL
  66 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
  67 {
  68      jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
  69      CHECK_NULL(cls);
  70      isa_class = (*env)->NewGlobalRef(env, cls);
  71      if (isa_class == NULL) {
  72          JNU_ThrowOutOfMemoryError(env, NULL);
  73          return;
  74      }
  75      isa_ctorID = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/net/InetAddress;I)V");
  76      CHECK_NULL(isa_ctorID);
  77 
  78      initInetAddressIDs(env);
  79 }
  80 
  81 JNIEXPORT jboolean JNICALL


 106     return JNI_FALSE;
 107 #endif
 108 }
 109 
 110 JNIEXPORT jboolean JNICALL
 111 Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
 112 {
 113 #if defined(__linux__) || defined(__APPLE__) || defined(__solaris__)
 114     /* IPv6 sockets can join IPv4 multicast groups */
 115     return JNI_TRUE;
 116 #else
 117     /* IPv6 sockets cannot join IPv4 multicast groups */
 118     return JNI_FALSE;
 119 #endif
 120 }
 121 
 122 JNIEXPORT jboolean JNICALL
 123 Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
 124 {
 125 #if defined(__APPLE__) || defined(__solaris__)
 126     /* IPv6 sockets use IPPROTO_IPV6 level options to join IPv4 multicast groups */
 127     return JNI_TRUE;
 128 #else
 129     /* IPv6 sockets use IPPROTO_IP level options to join IPv4 multicast groups */
 130     return JNI_FALSE;
 131 #endif
 132 }
 133 
 134 JNIEXPORT jboolean JNICALL
 135 Java_sun_nio_ch_Net_canUseIPv6OptionsWithIPv4LocalAddress0(JNIEnv* env, jclass cl)
 136 {
 137     /* IPV6_XXX socket options can be used on IPv6 sockets bound to IPv4 address */
 138     return JNI_TRUE;
 139 }
 140 
 141 JNIEXPORT jint JNICALL
 142 Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
 143                             jboolean stream, jboolean reuse, jboolean ignored)
 144 {
 145     int fd;
 146     int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
 147     int domain = (ipv6_available() && preferIPv6) ? AF_INET6 : AF_INET;
 148 
 149     fd = socket(domain, type, 0);


 479         } else {
 480             linger.l_onoff = 0;
 481             linger.l_linger = 0;
 482         }
 483     }
 484 
 485     if (mayNeedConversion) {
 486         n = NET_SetSockOpt(fdval(env, fdo), level, opt, parg, arglen);
 487     } else {
 488         n = setsockopt(fdval(env, fdo), level, opt, parg, arglen);
 489     }
 490     if (n < 0) {
 491         JNU_ThrowByNameWithLastError(env,
 492                                      JNU_JAVANETPKG "SocketException",
 493                                      "sun.nio.ch.Net.setIntOption");
 494     }
 495 }
 496 
 497 JNIEXPORT jint JNICALL
 498 Java_sun_nio_ch_Net_joinOrDrop4(JNIEnv *env, jobject this, jboolean join, jobject fdo,
 499                                 jint group, jint index, jint infAddress, jint source)
 500 {
 501     int n;
 502     int fd = fdval(env, fdo);
 503     #ifdef USE_MCAST_XXX


 504         if (source == 0) {
 505             int opt = (join) ? MCAST_JOIN_GROUP  : MCAST_LEAVE_GROUP;
 506             struct group_req req;
 507             initGroupReq4(env, &req, index, group);
 508             n = setsockopt(fd, IPPROTO_IP, opt, (const void*)&req, sizeof(req));

 509         } else {
 510             int opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP;
 511             struct group_source_req req;
 512             initGroupSourceReq4(env, &req, index, group, source);
 513             n = setsockopt(fd, IPPROTO_IP, opt, (const void*)&req, sizeof(req));

 514         }
 515     #else
 516         if (source == 0) {
 517             int opt = (join) ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
 518             struct ip_mreq mreq;
 519             mreq.imr_multiaddr.s_addr = htonl(group);
 520             mreq.imr_interface.s_addr = htonl(infAddress);
 521             n = setsockopt(fd, IPPROTO_IP, opt, (const void*)&mreq, sizeof(mreq));
 522         } else {
 523             int opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
 524             struct ip_mreq_source mreq_source;
 525             mreq_source.imr_multiaddr.s_addr = htonl(group);
 526             mreq_source.imr_interface.s_addr = htonl(infAddress);
 527             mreq_source.imr_sourceaddr.s_addr = htonl(source);
 528             n = setsockopt(fd, IPPROTO_IP, opt, (const void*)&mreq_source, sizeof(mreq_source));



 529         }
 530     #endif
 531     if (n == -1) {



 532         handleSocketError(env, errno);
 533     }
 534     return 0;
 535 }
 536 
 537 JNIEXPORT jint JNICALL
 538 Java_sun_nio_ch_Net_blockOrUnblock4(JNIEnv *env, jobject this, jboolean block, jobject fdo,
 539                                     jint group, jint index, jint infAddress, jint source)
 540 {
 541     #if defined(__APPLE__)
 542         /* no IPv4 exclude-mode filtering on this platform */
 543         return IOS_UNAVAILABLE;
 544     #else

 545         int n;
 546         int fd = fdval(env, fdo);
 547         #if USE_MCAST_XXX
 548             int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE;
 549             struct group_source_req req;
 550             initGroupSourceReq4(env, &req, index, group, source);
 551             n = setsockopt(fd, IPPROTO_IP, opt, (const char*)&req, sizeof(req));
 552         #else
 553             int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
 554             struct ip_mreq_source mreq_source;







 555             mreq_source.imr_multiaddr.s_addr = htonl(group);
 556             mreq_source.imr_interface.s_addr = htonl(infAddress);
 557             mreq_source.imr_sourceaddr.s_addr = htonl(source);
 558             n = setsockopt(fd, IPPROTO_IP, opt, (void*)&mreq_source, sizeof(mreq_source));
 559         #endif
 560         if (n == -1) {




 561             handleSocketError(env, errno);
 562         }
 563         return 0;
 564     #endif
 565 }
 566 
 567 JNIEXPORT jint JNICALL
 568 Java_sun_nio_ch_Net_joinOrDrop6(JNIEnv *env, jobject this, jboolean join, jobject fdo,
 569                                 jbyteArray group, jint index, jbyteArray source)
 570 {
 571     int n;
 572     int fd = fdval(env, fdo);
 573     #ifdef USE_MCAST_XXX
 574         if (source == NULL) {
 575             int opt = (join) ? MCAST_JOIN_GROUP  : MCAST_LEAVE_GROUP;
 576             struct group_req req;
 577             initGroupReq6(env, &req, index, group);
 578             n = setsockopt(fd, IPPROTO_IPV6, opt, (const void*)&req, sizeof(req));
 579         } else {
 580             int opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP;
 581             struct group_source_req req;
 582             initGroupSourceReq6(env, &req, index, group, source);
 583             n = setsockopt(fd, IPPROTO_IPV6, opt, (const void*)&req, sizeof(req));
 584         }
 585     #else
 586         #ifndef IPV6_ADD_MEMBERSHIP
 587             #define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP
 588             #define IPV6_DROP_MEMBERSHIP    IPV6_LEAVE_GROUP
 589         #endif
 590         if (source == NULL) {
 591             int opt = (join) ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP;
 592             struct ipv6_mreq mreq6;
 593             mreq6.ipv6mr_interface = (int)index;
 594             (*env)->GetByteArrayRegion(env, group, 0, 16, (jbyte*)&(mreq6.ipv6mr_multiaddr));
 595             n = setsockopt(fd, IPPROTO_IPV6, opt, (const void*)&mreq6, sizeof(mreq6));

 596         } else {
 597             /* no IPv6 include-mode filtering */

 598             return IOS_UNAVAILABLE;






 599         }
 600     #endif
 601     if (n == -1) {



 602         handleSocketError(env, errno);
 603     }
 604     return 0;
 605 }
 606 
 607 JNIEXPORT jint JNICALL
 608 Java_sun_nio_ch_Net_blockOrUnblock6(JNIEnv *env, jobject this, jboolean block, jobject fdo,
 609                                     jbyteArray group, jint index, jbyteArray source)
 610 {
 611     #ifdef USE_MCAST_XXX




 612         int n;
 613         int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE;
 614         struct group_source_req req;
 615         initGroupSourceReq6(env, &req, index, group, source);
 616         n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, (void*)&req, sizeof(req));
 617         if (n == -1) {




 618             handleSocketError(env, errno);
 619         }
 620         return 0;
 621     #else
 622         /* no IPv6 exclude-mode filtering */
 623         return IOS_UNAVAILABLE;
 624     #endif
 625 }
 626 
 627 JNIEXPORT void JNICALL
 628 Java_sun_nio_ch_Net_setInterface4(JNIEnv* env, jobject this, jobject fdo, jint infAddress)
 629 {
 630     struct in_addr in;
 631     socklen_t arglen = sizeof(struct in_addr);
 632     int n;
 633 
 634     in.s_addr = htonl(infAddress);

 635     n = setsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF,
 636                    (void*)&(in.s_addr), arglen);
 637     if (n < 0) {
 638         handleSocketError(env, errno);
 639     }
 640 }
 641 
 642 JNIEXPORT jint JNICALL
 643 Java_sun_nio_ch_Net_getInterface4(JNIEnv* env, jobject this, jobject fdo)
 644 {
 645     struct in_addr in;
 646     socklen_t arglen = sizeof(struct in_addr);
 647     int n;
 648 
 649     n = getsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF, (void*)&in, &arglen);
 650     if (n < 0) {
 651         handleSocketError(env, errno);
 652         return -1;
 653     }
 654     return ntohl(in.s_addr);


< prev index next >