< prev index next >
src/java.base/unix/native/libnio/ch/Net.c
Print this page
rev 57536 : [mq]: Cleanup
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -39,88 +39,28 @@
#include "net_util.h"
#include "net_util_md.h"
#include "nio_util.h"
#include "nio.h"
-#ifdef _AIX
-#include <stdlib.h>
-#include <sys/utsname.h>
+/**
+ * Use MCAST_JOIN_GROUP/MCAST_BLOCK_SOURCE on platforms that support it.
+ */
+#if defined(__linux__) || defined(__solaris__)
+ #include "nio_multicast.h"
+ #define USE_MCAST_XXX 1
#endif
/**
- * IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
- * build time.
+ * IP_MULTICAST_ALL supported since 2.6.31 (and glibc 2.15) but may not be
+ * available at build time.
*/
#ifdef __linux__
#ifndef IP_MULTICAST_ALL
#define IP_MULTICAST_ALL 49
#endif
#endif
-/**
- * IPV6_ADD_MEMBERSHIP/IPV6_DROP_MEMBERSHIP may not be defined on OSX and AIX
- */
-#if defined(__APPLE__) || defined(_AIX)
- #ifndef IPV6_ADD_MEMBERSHIP
- #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
- #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
- #endif
-#endif
-
-#define COPY_INET6_ADDRESS(env, source, target) \
- (*env)->GetByteArrayRegion(env, source, 0, 16, target)
-
-/*
- * Copy IPv6 group, interface index, and IPv6 source address
- * into group_source_req structure.
- */
-static void initGroupSourceReq(JNIEnv* env, jbyteArray group, jint index,
- jbyteArray source, struct group_source_req *req)
-{
- struct sockaddr_in6* sin6;
-
- req->gsr_interface = (uint32_t)index;
-
- sin6 = (struct sockaddr_in6 *)&(req->gsr_group);
- sin6->sin6_family = AF_INET6;
- COPY_INET6_ADDRESS(env, group, (jbyte *)&(sin6->sin6_addr));
-
- sin6 = (struct sockaddr_in6 *)&(req->gsr_source);
- sin6->sin6_family = AF_INET6;
- COPY_INET6_ADDRESS(env, source, (jbyte *)&(sin6->sin6_addr));
-}
-
-#ifdef _AIX
-
-/*
- * Checks whether or not "socket extensions for multicast source filters" is supported.
- * Returns JNI_TRUE if it is supported, JNI_FALSE otherwise
- */
-static jboolean isSourceFilterSupported(){
- static jboolean alreadyChecked = JNI_FALSE;
- static jboolean result = JNI_TRUE;
- if (alreadyChecked != JNI_TRUE){
- struct utsname uts;
- memset(&uts, 0, sizeof(uts));
- strcpy(uts.sysname, "?");
- const int utsRes = uname(&uts);
- int major = -1;
- int minor = -1;
- major = atoi(uts.version);
- minor = atoi(uts.release);
- if (strcmp(uts.sysname, "AIX") == 0) {
- if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
- result = JNI_FALSE;
- }
- }
- alreadyChecked = JNI_TRUE;
- }
- return result;
-}
-
-#endif /* _AIX */
-
static jclass isa_class; /* java.net.InetSocketAddress */
static jmethodID isa_ctorID; /* InetSocketAddress(InetAddress, int) */
JNIEXPORT void JNICALL
Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
@@ -181,14 +121,14 @@
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
{
#if defined(__APPLE__) || defined(__solaris__)
- /* IPV6_ADD_MEMBERSHIP can be used to join IPv4 multicast groups */
+ /* IPv6 sockets use IPPROTO_IPV6 level options to join IPv4 multicast groups */
return JNI_TRUE;
#else
- /* IPV6_ADD_MEMBERSHIP cannot be used to join IPv4 multicast groups */
+ /* IPv6 sockets use IPPROTO_IP level options to join IPv4 multicast groups */
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL
@@ -554,153 +494,146 @@
}
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_joinOrDrop4(JNIEnv *env, jobject this, jboolean join, jobject fdo,
- jint group, jint interf, jint source)
+ jint group, jint index, jint infAddress, jint source)
{
- struct ip_mreq mreq;
- struct ip_mreq_source mreq_source;
- int opt, n, optlen;
- void* optval;
-
+ int n;
+ int fd = fdval(env, fdo);
+ #ifdef USE_MCAST_XXX
if (source == 0) {
- mreq.imr_multiaddr.s_addr = htonl(group);
- mreq.imr_interface.s_addr = htonl(interf);
- opt = (join) ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
- optval = (void*)&mreq;
- optlen = sizeof(mreq);
+ int opt = (join) ? MCAST_JOIN_GROUP : MCAST_LEAVE_GROUP;
+ struct group_req req;
+ initGroupReq4(env, &req, index, group);
+ n = setsockopt(fd, IPPROTO_IP, opt, (const void*)&req, sizeof(req));
} else {
-
-#ifdef _AIX
- /* check AIX for support of source filtering */
- if (isSourceFilterSupported() != JNI_TRUE){
- return IOS_UNAVAILABLE;
+ int opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP;
+ struct group_source_req req;
+ initGroupSourceReq4(env, &req, index, group, source);
+ n = setsockopt(fd, IPPROTO_IP, opt, (const void*)&req, sizeof(req));
}
-#endif
-
+ #else
+ if (source == 0) {
+ int opt = (join) ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr.s_addr = htonl(group);
+ mreq.imr_interface.s_addr = htonl(infAddress);
+ n = setsockopt(fd, IPPROTO_IP, opt, (const void*)&mreq, sizeof(mreq));
+ } else {
+ int opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
+ struct ip_mreq_source mreq_source;
mreq_source.imr_multiaddr.s_addr = htonl(group);
+ mreq_source.imr_interface.s_addr = htonl(infAddress);
mreq_source.imr_sourceaddr.s_addr = htonl(source);
- mreq_source.imr_interface.s_addr = htonl(interf);
- opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
- optval = (void*)&mreq_source;
- optlen = sizeof(mreq_source);
+ n = setsockopt(fd, IPPROTO_IP, opt, (const void*)&mreq_source, sizeof(mreq_source));
}
-
- n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
- if (n < 0) {
- if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
- return IOS_UNAVAILABLE;
+ #endif
+ if (n == -1) {
handleSocketError(env, errno);
}
return 0;
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_blockOrUnblock4(JNIEnv *env, jobject this, jboolean block, jobject fdo,
- jint group, jint interf, jint source)
+ jint group, jint index, jint infAddress, jint source)
{
-#ifdef __APPLE__
- /* no IPv4 exclude-mode filtering for now */
+ #if defined(__APPLE__)
+ /* no IPv4 exclude-mode filtering on this platform */
return IOS_UNAVAILABLE;
-#else
- struct ip_mreq_source mreq_source;
+ #else
int n;
+ int fd = fdval(env, fdo);
+ #if USE_MCAST_XXX
+ int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE;
+ struct group_source_req req;
+ initGroupSourceReq4(env, &req, index, group, source);
+ n = setsockopt(fd, IPPROTO_IP, opt, (const char*)&req, sizeof(req));
+ #else
int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
-
-#ifdef _AIX
- /* check AIX for support of source filtering */
- if (isSourceFilterSupported() != JNI_TRUE){
- return IOS_UNAVAILABLE;
- }
-#endif
-
+ struct ip_mreq_source mreq_source;
mreq_source.imr_multiaddr.s_addr = htonl(group);
+ mreq_source.imr_interface.s_addr = htonl(infAddress);
mreq_source.imr_sourceaddr.s_addr = htonl(source);
- mreq_source.imr_interface.s_addr = htonl(interf);
-
- n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
- (void*)&mreq_source, sizeof(mreq_source));
- if (n < 0) {
- if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
- return IOS_UNAVAILABLE;
+ n = setsockopt(fd, IPPROTO_IP, opt, (void*)&mreq_source, sizeof(mreq_source));
+ #endif
+ if (n == -1) {
handleSocketError(env, errno);
}
return 0;
-#endif
+ #endif
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_joinOrDrop6(JNIEnv *env, jobject this, jboolean join, jobject fdo,
jbyteArray group, jint index, jbyteArray source)
{
- struct ipv6_mreq mreq6;
+ int n;
+ int fd = fdval(env, fdo);
+ #ifdef USE_MCAST_XXX
+ if (source == NULL) {
+ int opt = (join) ? MCAST_JOIN_GROUP : MCAST_LEAVE_GROUP;
+ struct group_req req;
+ initGroupReq6(env, &req, index, group);
+ n = setsockopt(fd, IPPROTO_IPV6, opt, (const void*)&req, sizeof(req));
+ } else {
+ int opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP;
struct group_source_req req;
- int opt, n, optlen;
- void* optval;
-
+ initGroupSourceReq6(env, &req, index, group, source);
+ n = setsockopt(fd, IPPROTO_IPV6, opt, (const void*)&req, sizeof(req));
+ }
+ #else
+ #ifndef IPV6_ADD_MEMBERSHIP
+ #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+ #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+ #endif
if (source == NULL) {
- COPY_INET6_ADDRESS(env, group, (jbyte*)&(mreq6.ipv6mr_multiaddr));
+ int opt = (join) ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP;
+ struct ipv6_mreq mreq6;
mreq6.ipv6mr_interface = (int)index;
- opt = (join) ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP;
- optval = (void*)&mreq6;
- optlen = sizeof(mreq6);
+ (*env)->GetByteArrayRegion(env, group, 0, 16, (jbyte*)&(mreq6.ipv6mr_multiaddr));
+ n = setsockopt(fd, IPPROTO_IPV6, opt, (const void*)&mreq6, sizeof(mreq6));
} else {
-#ifdef __APPLE__
- /* no IPv6 include-mode filtering for now */
+ /* no IPv6 include-mode filtering */
return IOS_UNAVAILABLE;
-#else
- initGroupSourceReq(env, group, index, source, &req);
- opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP;
- optval = (void*)&req;
- optlen = sizeof(req);
-#endif
}
-
- n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
- if (n < 0) {
- if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
- return IOS_UNAVAILABLE;
+ #endif
+ if (n == -1) {
handleSocketError(env, errno);
}
return 0;
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_blockOrUnblock6(JNIEnv *env, jobject this, jboolean block, jobject fdo,
jbyteArray group, jint index, jbyteArray source)
{
-#ifdef __APPLE__
- /* no IPv6 exclude-mode filtering for now */
- return IOS_UNAVAILABLE;
-#else
- struct group_source_req req;
+ #ifdef USE_MCAST_XXX
int n;
int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE;
-
- initGroupSourceReq(env, group, index, source, &req);
-
- n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
- (void*)&req, sizeof(req));
- if (n < 0) {
- if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
- return IOS_UNAVAILABLE;
+ struct group_source_req req;
+ initGroupSourceReq6(env, &req, index, group, source);
+ n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, (void*)&req, sizeof(req));
+ if (n == -1) {
handleSocketError(env, errno);
}
return 0;
-#endif
+ #else
+ /* no IPv6 exclude-mode filtering */
+ return IOS_UNAVAILABLE;
+ #endif
}
JNIEXPORT void JNICALL
-Java_sun_nio_ch_Net_setInterface4(JNIEnv* env, jobject this, jobject fdo, jint interf)
+Java_sun_nio_ch_Net_setInterface4(JNIEnv* env, jobject this, jobject fdo, jint infAddress)
{
struct in_addr in;
socklen_t arglen = sizeof(struct in_addr);
int n;
- in.s_addr = htonl(interf);
-
+ in.s_addr = htonl(infAddress);
n = setsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF,
(void*)&(in.s_addr), arglen);
if (n < 0) {
handleSocketError(env, errno);
}
< prev index next >