src/java.base/windows/native/libnet/net_util_md.c
changeset 55375 96c7427456f9
parent 54627 22323f20401b
equal deleted inserted replaced
55374:5c4f1b7c753b 55375:96c7427456f9
   750         CLOSE_SOCKETS_AND_RETURN;
   750         CLOSE_SOCKETS_AND_RETURN;
   751     }
   751     }
   752     return 0;
   752     return 0;
   753 }
   753 }
   754 
   754 
   755 /*
       
   756  * Determine the default interface for an IPv6 address.
       
   757  *
       
   758  * Returns :-
       
   759  *      0 if error
       
   760  *      > 0 interface index to use
       
   761  */
       
   762 jint getDefaultIPv6Interface(JNIEnv *env, struct sockaddr_in6 *target_addr)
       
   763 {
       
   764     int ret;
       
   765     DWORD b;
       
   766     struct sockaddr_in6 route;
       
   767     SOCKET fd = socket(AF_INET6, SOCK_STREAM, 0);
       
   768     if (fd == INVALID_SOCKET) {
       
   769         return 0;
       
   770     }
       
   771 
       
   772     ret = WSAIoctl(fd, SIO_ROUTING_INTERFACE_QUERY,
       
   773                    (void *)target_addr, sizeof(struct sockaddr_in6),
       
   774                    (void *)&route, sizeof(struct sockaddr_in6),
       
   775                    &b, 0, 0);
       
   776     if (ret == SOCKET_ERROR) {
       
   777         // error
       
   778         closesocket(fd);
       
   779         return 0;
       
   780     } else {
       
   781         closesocket(fd);
       
   782         return route.sin6_scope_id;
       
   783     }
       
   784 }
       
   785 
       
   786 /**
   755 /**
   787  * Enables SIO_LOOPBACK_FAST_PATH
   756  * Enables SIO_LOOPBACK_FAST_PATH
   788  */
   757  */
   789 JNIEXPORT jint JNICALL
   758 JNIEXPORT jint JNICALL
   790 NET_EnableFastTcpLoopback(int fd) {
   759 NET_EnableFastTcpLoopback(int fd) {
   818         !(family == java_net_InetAddress_IPv4 &&
   787         !(family == java_net_InetAddress_IPv4 &&
   819           v4MappedAddress == JNI_FALSE))
   788           v4MappedAddress == JNI_FALSE))
   820     {
   789     {
   821         jbyte caddr[16];
   790         jbyte caddr[16];
   822         jint address;
   791         jint address;
   823         unsigned int scopeid = 0, cached_scope_id = 0;
   792         unsigned int scopeid = 0;
   824 
   793 
   825         if (family == java_net_InetAddress_IPv4) {
   794         if (family == java_net_InetAddress_IPv4) {
   826             // convert to IPv4-mapped address
   795             // convert to IPv4-mapped address
   827             memset((char *)caddr, 0, 16);
   796             memset((char *)caddr, 0, 16);
   828             address = getInetAddress_addr(env, iaObj);
   797             address = getInetAddress_addr(env, iaObj);
   840                 caddr[15] = (address & 0xff);
   809                 caddr[15] = (address & 0xff);
   841             }
   810             }
   842         } else {
   811         } else {
   843             getInet6Address_ipaddress(env, iaObj, (char *)caddr);
   812             getInet6Address_ipaddress(env, iaObj, (char *)caddr);
   844             scopeid = getInet6Address_scopeid(env, iaObj);
   813             scopeid = getInet6Address_scopeid(env, iaObj);
   845             cached_scope_id = (unsigned int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
       
   846         }
   814         }
   847         sa->sa6.sin6_port = (u_short)htons((u_short)port);
   815         sa->sa6.sin6_port = (u_short)htons((u_short)port);
   848         memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr));
   816         memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr));
   849         sa->sa6.sin6_family = AF_INET6;
   817         sa->sa6.sin6_family = AF_INET6;
   850         if ((family == java_net_InetAddress_IPv6) &&
   818         sa->sa6.sin6_scope_id = scopeid;
   851             IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr) &&
       
   852             (!scopeid && !cached_scope_id))
       
   853         {
       
   854             cached_scope_id = getDefaultIPv6Interface(env, &sa->sa6);
       
   855             (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
       
   856         }
       
   857         sa->sa6.sin6_scope_id = scopeid == 0 ? cached_scope_id : scopeid;
       
   858         if (len != NULL) {
   819         if (len != NULL) {
   859             *len = sizeof(struct sockaddr_in6);
   820             *len = sizeof(struct sockaddr_in6);
   860         }
   821         }
   861     } else {
   822     } else {
   862         jint address;
   823         jint address;