< prev index next >

src/java.base/unix/native/libnet/net_util_md.c

Print this page

        

@@ -776,10 +776,20 @@
 JNIEXPORT int JNICALL
 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
                           SOCKETADDRESS *sa, int *len,
                           jboolean v4MappedAddress)
 {
+    return NET_InetAddressToSockaddr0(env, iaObj, port, sa, len, v4MappedAddress,
+                                      JNI_FALSE);
+}
+
+JNIEXPORT int JNICALL
+NET_InetAddressToSockaddr0(JNIEnv *env, jobject iaObj, int port,
+                           SOCKETADDRESS *sa, int *len,
+                           jboolean v4MappedAddress,
+                           jboolean includeScopeId)
+{
     jint family = getInetAddress_family(env, iaObj);
     JNU_CHECK_EXCEPTION_RETURN(env, -1);
     memset((char *)sa, 0, sizeof(SOCKETADDRESS));
 
     if (ipv6_available() &&

@@ -816,22 +826,29 @@
             *len = sizeof(struct sockaddr_in6);
         }
 
 #ifdef __linux__
         /*
-         * On Linux if we are connecting to a link-local address
-         * we need to specify the interface in the scope_id (2.4 kernel only)
+         * On Linux if we are connecting to a
+         *
+         *   - link-local address
+         *   - multicast interface-local or link-local address
+         *
+         * we need to specify the interface in the scope_id.
          *
          * If the scope was cached then we use the cached value. If not cached but
          * specified in the Inet6Address we use that, but we first check if the
          * address needs to be routed via the loopback interface. In this case,
          * we override the specified value with that of the loopback interface.
          * If no cached value exists and no value was specified by user, then
          * we try to determine a value from the routing table. In all these
          * cases the used value is cached for further use.
          */
-        if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) {
+        if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)
+            || (includeScopeId == JNI_TRUE
+                && (IN6_IS_ADDR_MC_NODELOCAL(&sa->sa6.sin6_addr)
+                    || IN6_IS_ADDR_MC_LINKLOCAL(&sa->sa6.sin6_addr)))) {
             unsigned int cached_scope_id = 0, scope_id = 0;
 
             if (ia6_cachedscopeidID) {
                 cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
                 /* if cached value exists then use it. Otherwise, check
< prev index next >