< 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 >