/* * Copyright (c) 2001, 2022, 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 * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/** * IP_MULTICAST_ALL supported since 2.6.31 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
*/ #ifdefined(__APPLE__) || defined(_AIX) #ifndef IPV6_ADD_MEMBERSHIP #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP #endif #endif
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_Net_shouldSetBothIPv4AndIPv6Options0(JNIEnv* env, jclass cl)
{ #ifdefined(__linux__) /* Set both IPv4 and IPv6 socket options when setting multicast options */ return JNI_TRUE; #else /* Do not set both IPv4 and IPv6 socket options when setting multicast options */ return JNI_FALSE; #endif
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
{ #ifdefined(__APPLE__) /* IPV6_ADD_MEMBERSHIP can be used to join IPv4 multicast groups */ return JNI_TRUE; #else /* IPV6_ADD_MEMBERSHIP cannot be used to join IPv4 multicast groups */ return JNI_FALSE; #endif
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_Net_canUseIPv6OptionsWithIPv4LocalAddress0(JNIEnv* env, jclass cl)
{ /* IPV6_XXX socket options can be used on IPv6 sockets bound to IPv4 address */ return JNI_TRUE;
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
jboolean stream, jboolean reuse, jboolean ignored)
{ int fd; int type = (stream ? SOCK_STREAM : SOCK_DGRAM); int domain = (ipv6_available() && preferIPv6) ? AF_INET6 : AF_INET;
/* * If IPv4 is available, disable IPV6_V6ONLY to ensure dual-socket support.
*/ if (domain == AF_INET6 && ipv4_available()) { int arg = 0; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg, sizeof(int)) < 0) {
JNU_ThrowByNameWithLastError(env,
JNU_JAVANETPKG "SocketException", "Unable to set IPV6_V6ONLY");
close(fd); return -1;
}
}
if (reuse) { int arg = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg)) < 0) {
JNU_ThrowByNameWithLastError(env,
JNU_JAVANETPKG "SocketException", "Unable to set SO_REUSEADDR");
close(fd); return -1;
}
}
#ifdefined(__linux__) if (type == SOCK_DGRAM) { int arg = 0; int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP; if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) &&
(errno != ENOPROTOOPT)) {
JNU_ThrowByNameWithLastError(env,
JNU_JAVANETPKG "SocketException", "Unable to set IP_MULTICAST_ALL");
close(fd); return -1;
}
}
/* By default, Linux uses the route default */ if (domain == AF_INET6 && type == SOCK_DGRAM) { int arg = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &arg, sizeof(arg)) < 0) {
JNU_ThrowByNameWithLastError(env,
JNU_JAVANETPKG "SocketException", "Unable to set IPV6_MULTICAST_HOPS");
close(fd); return -1;
}
} #endif
#ifdef __APPLE__ /** * Attempt to set SO_SNDBUF to a minimum size to allow sending large datagrams * (net.inet.udp.maxdgram defaults to 9216).
*/ if (type == SOCK_DGRAM) { int size;
socklen_t arglen = sizeof(size); if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, &arglen) == 0) { int minSize = (domain == AF_INET6) ? 65527 : 65507; if (size < minSize) {
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &minSize, sizeof(minSize));
}
}
} #endif
return fd;
}
JNIEXPORT void JNICALL
Java_sun_nio_ch_Net_bind0(JNIEnv *env, jclass clazz, jobject fdo, jboolean preferIPv6,
jboolean useExclBind, jobject iao, int port)
{
SOCKETADDRESS sa; int sa_len = 0; int rv = 0;
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo)
{
SOCKETADDRESS sa;
socklen_t sa_len = sizeof(SOCKETADDRESS); if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) { #ifdef _ALLBSD_SOURCE /* * XXXBSD: * ECONNRESET is specific to the BSDs. We can not return an error, * as the calling Java code with raise a java.lang.Error given the expectation * that getsockname() will never fail. According to the Single UNIX Specification, * it shouldn't fail. As such, we just fill in generic Linux-compatible values.
*/ if (errno == ECONNRESET) {
bzero(&sa.sa4, sizeof(sa));
sa.sa4.sin_len = sizeof(struct sockaddr_in);
sa.sa4.sin_family = AF_INET;
sa.sa4.sin_port = htonl(0);
sa.sa4.sin_addr.s_addr = INADDR_ANY;
} else {
handleSocketError(env, errno); return -1;
} #else/* _ALLBSD_SOURCE */
handleSocketError(env, errno); return -1; #endif/* _ALLBSD_SOURCE */
} return NET_GetPortFromSockaddr(&sa);
}
JNIEXPORT jobject JNICALL
Java_sun_nio_ch_Net_localInetAddress(JNIEnv *env, jclass clazz, jobject fdo)
{
SOCKETADDRESS sa;
socklen_t sa_len = sizeof(SOCKETADDRESS); int port; if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) { #ifdef _ALLBSD_SOURCE /* * XXXBSD: * ECONNRESET is specific to the BSDs. We can not return an error, * as the calling Java code with raise a java.lang.Error with the expectation * that getsockname() will never fail. According to the Single UNIX Specification, * it shouldn't fail. As such, we just fill in generic Linux-compatible values.
*/ if (errno == ECONNRESET) {
bzero(&sa.sa4, sizeof(sa));
sa.sa4.sin_len = sizeof(struct sockaddr_in);
sa.sa4.sin_family = AF_INET;
sa.sa4.sin_port = htonl(0);
sa.sa4.sin_addr.s_addr = INADDR_ANY;
} else {
handleSocketError(env, errno); return NULL;
} #else/* _ALLBSD_SOURCE */
handleSocketError(env, errno); return NULL; #endif/* _ALLBSD_SOURCE */
} return NET_SockaddrToInetAddress(env, &sa, &port);
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_sendOOB(JNIEnv* env, jclass this, jobject fdo, jbyte b)
{ int n = send(fdval(env, fdo), (constvoid*)&b, 1, MSG_OOB); return convertReturnVal(env, n, JNI_FALSE);
}
/* Declared in nio_util.h */
jint handleSocketError(JNIEnv *env, jint errorValue)
{ char *xn; switch (errorValue) { case EINPROGRESS: /* Non-blocking connect */ return 0; #ifdef EPROTO case EPROTO:
xn = JNU_JAVANETPKG "ProtocolException"; break; #endif case ECONNREFUSED: case ETIMEDOUT: case ENOTCONN:
xn = JNU_JAVANETPKG "ConnectException"; break;
case EHOSTUNREACH:
xn = JNU_JAVANETPKG "NoRouteToHostException"; break; case EADDRINUSE: /* Fall through */ case EADDRNOTAVAIL: case EACCES:
xn = JNU_JAVANETPKG "BindException"; break; default:
xn = JNU_JAVANETPKG "SocketException"; break;
}
errno = errorValue;
JNU_ThrowByNameWithLastError(env, xn, "NioSocketError"); return IOS_THROWN;
}
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.4Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.