jdk/src/java.base/unix/native/libnet/net_util_md.c
changeset 43100 a7e3457672c7
parent 42475 c80ab3b11401
child 44916 54d70322b32c
equal deleted inserted replaced
43099:47f8baf1fcbd 43100:a7e3457672c7
   232         }
   232         }
   233         vinit24 = 1;
   233         vinit24 = 1;
   234     }
   234     }
   235     return kernelV24;
   235     return kernelV24;
   236 }
   236 }
   237 
       
   238 int getScopeID (struct sockaddr *him) {
       
   239     struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him;
       
   240     return hext->sin6_scope_id;
       
   241 }
       
   242 
       
   243 int cmpScopeID (unsigned int scope, struct sockaddr *him) {
       
   244     struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him;
       
   245     return hext->sin6_scope_id == scope;
       
   246 }
       
   247 
       
   248 #else
       
   249 
       
   250 int getScopeID (struct sockaddr *him) {
       
   251     struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
       
   252     return him6->sin6_scope_id;
       
   253 }
       
   254 
       
   255 int cmpScopeID (unsigned int scope, struct sockaddr *him) {
       
   256     struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
       
   257     return him6->sin6_scope_id == scope;
       
   258 }
       
   259 
       
   260 #endif
   237 #endif
   261 
   238 
   262 void
   239 void
   263 NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
   240 NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
   264                    const char *defaultDetail) {
   241                    const char *defaultDetail) {
   773 JNIEXPORT jint JNICALL
   750 JNIEXPORT jint JNICALL
   774 NET_EnableFastTcpLoopback(int fd) {
   751 NET_EnableFastTcpLoopback(int fd) {
   775     return 0;
   752     return 0;
   776 }
   753 }
   777 
   754 
   778 /* In the case of an IPv4 Inetaddress this method will return an
   755 /**
   779  * IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE.
   756  * See net_util.h for documentation
   780  * Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress.
   757  */
   781 */
       
   782 JNIEXPORT int JNICALL
   758 JNIEXPORT int JNICALL
   783 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him,
   759 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
   784                           int *len, jboolean v4MappedAddress) {
   760                           SOCKETADDRESS *sa, int *len,
   785     jint family;
   761                           jboolean v4MappedAddress)
   786     family = getInetAddress_family(env, iaObj);
   762 {
   787     /* needs work. 1. family 2. clean up him6 etc deallocate memory */
   763     jint family = getInetAddress_family(env, iaObj);
   788     if (ipv6_available() && !(family == java_net_InetAddress_IPv4 &&
   764     memset((char *)sa, 0, sizeof(SOCKETADDRESS));
   789                               v4MappedAddress == JNI_FALSE)) {
   765 
   790         struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
   766     if (ipv6_available() &&
       
   767         !(family == java_net_InetAddress_IPv4 &&
       
   768           v4MappedAddress == JNI_FALSE))
       
   769     {
   791         jbyte caddr[16];
   770         jbyte caddr[16];
   792         jint address;
   771         jint address;
   793 
   772 
   794         if (family == java_net_InetAddress_IPv4) {
   773         if (family == java_net_InetAddress_IPv4) {
   795             // convert to IPv4-mapped address
   774             // convert to IPv4-mapped address
   796             memset((char *) caddr, 0, 16);
   775             memset((char *)caddr, 0, 16);
   797             address = getInetAddress_addr(env, iaObj);
   776             address = getInetAddress_addr(env, iaObj);
   798             if (address == INADDR_ANY) {
   777             if (address == INADDR_ANY) {
   799                 /* we would always prefer IPv6 wildcard address
   778                 /* we would always prefer IPv6 wildcard address
   800                    caddr[10] = 0xff;
   779                  * caddr[10] = 0xff;
   801                    caddr[11] = 0xff; */
   780                  * caddr[11] = 0xff; */
   802             } else {
   781             } else {
   803                 caddr[10] = 0xff;
   782                 caddr[10] = 0xff;
   804                 caddr[11] = 0xff;
   783                 caddr[11] = 0xff;
   805                 caddr[12] = ((address >> 24) & 0xff);
   784                 caddr[12] = ((address >> 24) & 0xff);
   806                 caddr[13] = ((address >> 16) & 0xff);
   785                 caddr[13] = ((address >> 16) & 0xff);
   808                 caddr[15] = (address & 0xff);
   787                 caddr[15] = (address & 0xff);
   809             }
   788             }
   810         } else {
   789         } else {
   811             getInet6Address_ipaddress(env, iaObj, (char *)caddr);
   790             getInet6Address_ipaddress(env, iaObj, (char *)caddr);
   812         }
   791         }
   813         memset((char *)him6, 0, sizeof(struct sockaddr_in6));
   792         sa->sa6.sin6_port = htons(port);
   814         him6->sin6_port = htons(port);
   793         memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr));
   815         memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) );
   794         sa->sa6.sin6_family = AF_INET6;
   816         him6->sin6_family = AF_INET6;
   795         if (len != NULL) {
   817         *len = sizeof(struct sockaddr_in6);
   796             *len = sizeof(struct sockaddr_in6);
   818 
   797         }
   819 #if defined(_ALLBSD_SOURCE)
   798 
   820 // XXXBSD: should we do something with scope id here ? see below linux comment
   799 #ifdef __linux__
   821 /* MMM: Come back to this! */
       
   822 #endif
       
   823 
       
   824         /*
   800         /*
   825          * On Linux if we are connecting to a link-local address
   801          * On Linux if we are connecting to a link-local address
   826          * we need to specify the interface in the scope_id (2.4 kernel only)
   802          * we need to specify the interface in the scope_id (2.4 kernel only)
   827          *
   803          *
   828          * If the scope was cached the we use the cached value. If not cached but
   804          * If the scope was cached then we use the cached value. If not cached but
   829          * specified in the Inet6Address we use that, but we first check if the
   805          * specified in the Inet6Address we use that, but we first check if the
   830          * address needs to be routed via the loopback interface. In this case,
   806          * address needs to be routed via the loopback interface. In this case,
   831          * we override the specified value with that of the loopback interface.
   807          * we override the specified value with that of the loopback interface.
   832          * If no cached value exists and no value was specified by user, then
   808          * If no cached value exists and no value was specified by user, then
   833          * we try to determine a value from the routing table. In all these
   809          * we try to determine a value from the routing table. In all these
   834          * cases the used value is cached for further use.
   810          * cases the used value is cached for further use.
   835          */
   811          */
   836 #ifdef __linux__
   812         if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) {
   837         if (IN6_IS_ADDR_LINKLOCAL(&(him6->sin6_addr))) {
   813             unsigned int cached_scope_id = 0, scope_id = 0;
   838             int cached_scope_id = 0, scope_id = 0;
       
   839 
   814 
   840             if (ia6_cachedscopeidID) {
   815             if (ia6_cachedscopeidID) {
   841                 cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
   816                 cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
   842                 /* if cached value exists then use it. Otherwise, check
   817                 /* if cached value exists then use it. Otherwise, check
   843                  * if scope is set in the address.
   818                  * if scope is set in the address.
   848                     }
   823                     }
   849                     if (scope_id != 0) {
   824                     if (scope_id != 0) {
   850                         /* check user-specified value for loopback case
   825                         /* check user-specified value for loopback case
   851                          * that needs to be overridden
   826                          * that needs to be overridden
   852                          */
   827                          */
   853                         if (kernelIsV24() && needsLoopbackRoute (&him6->sin6_addr)) {
   828                         if (kernelIsV24() && needsLoopbackRoute(&sa->sa6.sin6_addr)) {
   854                             cached_scope_id = lo_scope_id;
   829                             cached_scope_id = lo_scope_id;
   855                             (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
   830                             (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
   856                         }
   831                         }
   857                     } else {
   832                     } else {
   858                         /*
   833                         /*
   859                          * Otherwise consult the IPv6 routing tables to
   834                          * Otherwise consult the IPv6 routing tables to
   860                          * try determine the appropriate interface.
   835                          * try determine the appropriate interface.
   861                          */
   836                          */
   862                         if (kernelIsV24()) {
   837                         if (kernelIsV24()) {
   863                             cached_scope_id = getDefaultIPv6Interface(&(him6->sin6_addr));
   838                             cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr);
   864                         } else {
   839                         } else {
   865                             cached_scope_id = getLocalScopeID((char *)&(him6->sin6_addr));
   840                             cached_scope_id = getLocalScopeID((char *)&(sa->sa6.sin6_addr));
   866                             if (cached_scope_id == 0) {
   841                             if (cached_scope_id == 0) {
   867                                 cached_scope_id = getDefaultIPv6Interface(&(him6->sin6_addr));
   842                                 cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr);
   868                             }
   843                             }
   869                         }
   844                         }
   870                         (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
   845                         (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
   871                     }
   846                     }
   872                 }
   847                 }
   874 
   849 
   875             /*
   850             /*
   876              * If we have a scope_id use the extended form
   851              * If we have a scope_id use the extended form
   877              * of sockaddr_in6.
   852              * of sockaddr_in6.
   878              */
   853              */
   879 
   854             sa->sa6.sin6_scope_id = cached_scope_id == 0 ? scope_id : cached_scope_id;
   880             struct sockaddr_in6 *him6 =
       
   881                     (struct sockaddr_in6 *)him;
       
   882             him6->sin6_scope_id = cached_scope_id != 0 ?
       
   883                                         cached_scope_id    : scope_id;
       
   884             *len = sizeof(struct sockaddr_in6);
       
   885         }
   855         }
   886 #else
   856 #else
   887         /* handle scope_id for solaris */
   857         /* handle scope_id */
   888 
       
   889         if (family != java_net_InetAddress_IPv4) {
   858         if (family != java_net_InetAddress_IPv4) {
   890             if (ia6_scopeidID) {
   859             if (ia6_scopeidID) {
   891                 him6->sin6_scope_id = getInet6Address_scopeid(env, iaObj);
   860                 sa->sa6.sin6_scope_id = getInet6Address_scopeid(env, iaObj);
   892             }
   861             }
   893         }
   862         }
   894 #endif
   863 #endif
   895     } else {
   864     } else {
   896         struct sockaddr_in *him4 = (struct sockaddr_in *)him;
       
   897         jint address;
   865         jint address;
   898         if (family == java_net_InetAddress_IPv6) {
   866         if (family != java_net_InetAddress_IPv4) {
   899             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
   867             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
   900             return -1;
   868             return -1;
   901         }
   869         }
   902         memset((char *)him4, 0, sizeof(struct sockaddr_in));
       
   903         address = getInetAddress_addr(env, iaObj);
   870         address = getInetAddress_addr(env, iaObj);
   904         him4->sin_port = htons((short) port);
   871         sa->sa4.sin_port = htons(port);
   905         him4->sin_addr.s_addr = htonl(address);
   872         sa->sa4.sin_addr.s_addr = htonl(address);
   906         him4->sin_family = AF_INET;
   873         sa->sa4.sin_family = AF_INET;
   907         *len = sizeof(struct sockaddr_in);
   874         if (len != NULL) {
       
   875             *len = sizeof(struct sockaddr_in);
       
   876         }
   908     }
   877     }
   909     return 0;
   878     return 0;
   910 }
   879 }
   911 
   880 
   912 void
   881 void
   913 NET_SetTrafficClass(struct sockaddr *him, int trafficClass) {
   882 NET_SetTrafficClass(SOCKETADDRESS *sa, int trafficClass) {
   914     if (him->sa_family == AF_INET6) {
   883     if (sa->sa.sa_family == AF_INET6) {
   915         struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
   884         sa->sa6.sin6_flowinfo = htonl((trafficClass & 0xff) << 20);
   916         him6->sin6_flowinfo = htonl((trafficClass & 0xff) << 20);
       
   917     }
       
   918 }
       
   919 
       
   920 JNIEXPORT jint JNICALL
       
   921 NET_GetPortFromSockaddr(struct sockaddr *him) {
       
   922     if (him->sa_family == AF_INET6) {
       
   923         return ntohs(((struct sockaddr_in6*)him)->sin6_port);
       
   924     } else {
       
   925         return ntohs(((struct sockaddr_in*)him)->sin_port);
       
   926     }
   885     }
   927 }
   886 }
   928 
   887 
   929 int
   888 int
   930 NET_IsIPv4Mapped(jbyte* caddr) {
   889 NET_IsIPv4Mapped(jbyte* caddr) {
  1486  * bind to guarantee a unique port number across the IPv4 and
  1445  * bind to guarantee a unique port number across the IPv4 and
  1487  * IPv6 port spaces.
  1446  * IPv6 port spaces.
  1488  *
  1447  *
  1489  */
  1448  */
  1490 int
  1449 int
  1491 NET_Bind(int fd, struct sockaddr *him, int len)
  1450 NET_Bind(int fd, SOCKETADDRESS *sa, int len)
  1492 {
  1451 {
  1493 #if defined(__solaris__)
  1452 #if defined(__solaris__)
  1494     int level = -1;
  1453     int level = -1;
  1495     int exclbind = -1;
  1454     int exclbind = -1;
  1496 #endif
  1455 #endif
  1501     /*
  1460     /*
  1502      * ## get bugId for this issue - goes back to 1.2.2 port ##
  1461      * ## get bugId for this issue - goes back to 1.2.2 port ##
  1503      * ## When IPv6 is enabled this will be an IPv4-mapped
  1462      * ## When IPv6 is enabled this will be an IPv4-mapped
  1504      * ## with family set to AF_INET6
  1463      * ## with family set to AF_INET6
  1505      */
  1464      */
  1506     if (him->sa_family == AF_INET) {
  1465     if (sa->sa.sa_family == AF_INET) {
  1507         struct sockaddr_in *sa = (struct sockaddr_in *)him;
  1466         if ((ntohl(sa->sa4.sin_addr.s_addr) & 0x7f0000ff) == 0x7f0000ff) {
  1508         if ((ntohl(sa->sin_addr.s_addr) & 0x7f0000ff) == 0x7f0000ff) {
       
  1509             errno = EADDRNOTAVAIL;
  1467             errno = EADDRNOTAVAIL;
  1510             return -1;
  1468             return -1;
  1511         }
  1469         }
  1512     }
  1470     }
  1513 #endif
  1471 #endif
  1522      * results in a late bind that fails because the
  1480      * results in a late bind that fails because the
  1523      * corresponding IPv4 port is in use.
  1481      * corresponding IPv4 port is in use.
  1524      */
  1482      */
  1525     alen = sizeof(arg);
  1483     alen = sizeof(arg);
  1526 
  1484 
  1527     if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
  1485     if (useExclBind ||
  1528                    (char *)&arg, &alen) == 0) {
  1486         getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, &alen) == 0)
       
  1487     {
  1529         if (useExclBind || arg == 0) {
  1488         if (useExclBind || arg == 0) {
  1530             /*
  1489             /*
  1531              * SO_REUSEADDR is disabled or sun.net.useExclusiveBind
  1490              * SO_REUSEADDR is disabled or sun.net.useExclusiveBind
  1532              * property is true so enable TCP_EXCLBIND or
  1491              * property is true so enable TCP_EXCLBIND or
  1533              * UDP_EXCLBIND
  1492              * UDP_EXCLBIND
  1534              */
  1493              */
  1535             alen = sizeof(arg);
  1494             alen = sizeof(arg);
  1536             if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg,
  1495             if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg, &alen) == 0)
  1537                            &alen) == 0) {
  1496             {
  1538                 if (arg == SOCK_STREAM) {
  1497                 if (arg == SOCK_STREAM) {
  1539                     level = IPPROTO_TCP;
  1498                     level = IPPROTO_TCP;
  1540                     exclbind = TCP_EXCLBIND;
  1499                     exclbind = TCP_EXCLBIND;
  1541                 } else {
  1500                 } else {
  1542                     level = IPPROTO_UDP;
  1501                     level = IPPROTO_UDP;
  1543                     exclbind = UDP_EXCLBIND;
  1502                     exclbind = UDP_EXCLBIND;
  1544                 }
  1503                 }
  1545             }
  1504             }
  1546 
  1505 
  1547             arg = 1;
  1506             arg = 1;
  1548             setsockopt(fd, level, exclbind, (char *)&arg,
  1507             setsockopt(fd, level, exclbind, (char *)&arg, sizeof(arg));
  1549                        sizeof(arg));
  1508         }
  1550         }
  1509     }
  1551     }
  1510 
  1552 
  1511 #endif
  1553 #endif
  1512 
  1554 
  1513     rv = bind(fd, &sa->sa, len);
  1555     rv = bind(fd, him, len);
       
  1556 
  1514 
  1557 #if defined(__solaris__)
  1515 #if defined(__solaris__)
  1558     if (rv < 0) {
  1516     if (rv < 0) {
  1559         int en = errno;
  1517         int en = errno;
  1560         /* Restore *_EXCLBIND if the bind fails */
  1518         /* Restore *_EXCLBIND if the bind fails */