761 flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s); 762 if (flagSet != NULL) { 763 useExclBind = 1; 764 } 765 #endif 766 } 767 768 JNIEXPORT jint JNICALL 769 NET_EnableFastTcpLoopback(int fd) { 770 return 0; 771 } 772 773 /** 774 * See net_util.h for documentation 775 */ 776 JNIEXPORT int JNICALL 777 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, 778 SOCKETADDRESS *sa, int *len, 779 jboolean v4MappedAddress) 780 { 781 jint family = getInetAddress_family(env, iaObj); 782 JNU_CHECK_EXCEPTION_RETURN(env, -1); 783 memset((char *)sa, 0, sizeof(SOCKETADDRESS)); 784 785 if (ipv6_available() && 786 !(family == java_net_InetAddress_IPv4 && 787 v4MappedAddress == JNI_FALSE)) 788 { 789 jbyte caddr[16]; 790 jint address; 791 792 if (family == java_net_InetAddress_IPv4) { 793 // convert to IPv4-mapped address 794 memset((char *)caddr, 0, 16); 795 address = getInetAddress_addr(env, iaObj); 796 JNU_CHECK_EXCEPTION_RETURN(env, -1); 797 if (address == INADDR_ANY) { 798 /* we would always prefer IPv6 wildcard address 799 * caddr[10] = 0xff; 800 * caddr[11] = 0xff; */ 801 } else { 802 caddr[10] = 0xff; 803 caddr[11] = 0xff; 804 caddr[12] = ((address >> 24) & 0xff); 805 caddr[13] = ((address >> 16) & 0xff); 806 caddr[14] = ((address >> 8) & 0xff); 807 caddr[15] = (address & 0xff); 808 } 809 } else { 810 getInet6Address_ipaddress(env, iaObj, (char *)caddr); 811 } 812 sa->sa6.sin6_port = htons(port); 813 memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr)); 814 sa->sa6.sin6_family = AF_INET6; 815 if (len != NULL) { 816 *len = sizeof(struct sockaddr_in6); 817 } 818 819 #ifdef __linux__ 820 /* 821 * On Linux if we are connecting to a link-local address 822 * we need to specify the interface in the scope_id (2.4 kernel only) 823 * 824 * If the scope was cached then we use the cached value. If not cached but 825 * specified in the Inet6Address we use that, but we first check if the 826 * address needs to be routed via the loopback interface. In this case, 827 * we override the specified value with that of the loopback interface. 828 * If no cached value exists and no value was specified by user, then 829 * we try to determine a value from the routing table. In all these 830 * cases the used value is cached for further use. 831 */ 832 if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) { 833 unsigned int cached_scope_id = 0, scope_id = 0; 834 835 if (ia6_cachedscopeidID) { 836 cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID); 837 /* if cached value exists then use it. Otherwise, check 838 * if scope is set in the address. 839 */ 840 if (!cached_scope_id) { 841 if (ia6_scopeidID) { 842 scope_id = getInet6Address_scopeid(env, iaObj); 843 } 844 if (scope_id != 0) { 845 /* check user-specified value for loopback case 846 * that needs to be overridden 847 */ 848 if (kernelIsV24() && needsLoopbackRoute(&sa->sa6.sin6_addr)) { 849 cached_scope_id = lo_scope_id; 850 (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id); 851 } 852 } else { | 761 flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s); 762 if (flagSet != NULL) { 763 useExclBind = 1; 764 } 765 #endif 766 } 767 768 JNIEXPORT jint JNICALL 769 NET_EnableFastTcpLoopback(int fd) { 770 return 0; 771 } 772 773 /** 774 * See net_util.h for documentation 775 */ 776 JNIEXPORT int JNICALL 777 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, 778 SOCKETADDRESS *sa, int *len, 779 jboolean v4MappedAddress) 780 { 781 return NET_InetAddressToSockaddr0(env, iaObj, port, sa, len, v4MappedAddress, 782 JNI_FALSE); 783 } 784 785 JNIEXPORT int JNICALL 786 NET_InetAddressToSockaddr0(JNIEnv *env, jobject iaObj, int port, 787 SOCKETADDRESS *sa, int *len, 788 jboolean v4MappedAddress, 789 jboolean includeScopeId) 790 { 791 jint family = getInetAddress_family(env, iaObj); 792 JNU_CHECK_EXCEPTION_RETURN(env, -1); 793 memset((char *)sa, 0, sizeof(SOCKETADDRESS)); 794 795 if (ipv6_available() && 796 !(family == java_net_InetAddress_IPv4 && 797 v4MappedAddress == JNI_FALSE)) 798 { 799 jbyte caddr[16]; 800 jint address; 801 802 if (family == java_net_InetAddress_IPv4) { 803 // convert to IPv4-mapped address 804 memset((char *)caddr, 0, 16); 805 address = getInetAddress_addr(env, iaObj); 806 JNU_CHECK_EXCEPTION_RETURN(env, -1); 807 if (address == INADDR_ANY) { 808 /* we would always prefer IPv6 wildcard address 809 * caddr[10] = 0xff; 810 * caddr[11] = 0xff; */ 811 } else { 812 caddr[10] = 0xff; 813 caddr[11] = 0xff; 814 caddr[12] = ((address >> 24) & 0xff); 815 caddr[13] = ((address >> 16) & 0xff); 816 caddr[14] = ((address >> 8) & 0xff); 817 caddr[15] = (address & 0xff); 818 } 819 } else { 820 getInet6Address_ipaddress(env, iaObj, (char *)caddr); 821 } 822 sa->sa6.sin6_port = htons(port); 823 memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr)); 824 sa->sa6.sin6_family = AF_INET6; 825 if (len != NULL) { 826 *len = sizeof(struct sockaddr_in6); 827 } 828 829 #ifdef __linux__ 830 /* 831 * On Linux if we are connecting to a 832 * 833 * - link-local address 834 * - multicast interface-local or link-local address 835 * 836 * we need to specify the interface in the scope_id. 837 * 838 * If the scope was cached then we use the cached value. If not cached but 839 * specified in the Inet6Address we use that, but we first check if the 840 * address needs to be routed via the loopback interface. In this case, 841 * we override the specified value with that of the loopback interface. 842 * If no cached value exists and no value was specified by user, then 843 * we try to determine a value from the routing table. In all these 844 * cases the used value is cached for further use. 845 */ 846 if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr) 847 || (includeScopeId == JNI_TRUE 848 && (IN6_IS_ADDR_MC_NODELOCAL(&sa->sa6.sin6_addr) 849 || IN6_IS_ADDR_MC_LINKLOCAL(&sa->sa6.sin6_addr)))) { 850 unsigned int cached_scope_id = 0, scope_id = 0; 851 852 if (ia6_cachedscopeidID) { 853 cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID); 854 /* if cached value exists then use it. Otherwise, check 855 * if scope is set in the address. 856 */ 857 if (!cached_scope_id) { 858 if (ia6_scopeidID) { 859 scope_id = getInet6Address_scopeid(env, iaObj); 860 } 861 if (scope_id != 0) { 862 /* check user-specified value for loopback case 863 * that needs to be overridden 864 */ 865 if (kernelIsV24() && needsLoopbackRoute(&sa->sa6.sin6_addr)) { 866 cached_scope_id = lo_scope_id; 867 (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id); 868 } 869 } else { |