Path: blob/master/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c
43745 views
/*1* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <netdb.h>26#include <sys/types.h>27#include <sys/socket.h>28#include <stdlib.h>29#include <string.h>30#include <errno.h>3132#if defined(__linux__) || defined(_ALLBSD_SOURCE)33#include <netinet/in.h>34#endif3536#include "jni.h"37#include "jni_util.h"38#include "jlong.h"39#include "net_util.h"40#include "nio.h"41#include "nio_util.h"4243#include "sun_nio_ch_DatagramChannelImpl.h"4445JNIEXPORT void JNICALL46Java_sun_nio_ch_DatagramChannelImpl_disconnect0(JNIEnv *env, jclass clazz,47jobject fdo, jboolean isIPv6)48{49jint fd = fdval(env, fdo);50int rv;5152SOCKETADDRESS sa;53socklen_t len = isIPv6 ? sizeof(struct sockaddr_in6) :54sizeof(struct sockaddr_in);5556memset(&sa, 0, sizeof(sa));57#if defined(_ALLBSD_SOURCE)58sa.sa.sa_family = isIPv6 ? AF_INET6 : AF_INET;59#else60sa.sa.sa_family = AF_UNSPEC;61#endif6263rv = connect(fd, &sa.sa, len);6465#if defined(_ALLBSD_SOURCE)66if (rv < 0 && errno == EADDRNOTAVAIL)67rv = errno = 0;68#elif defined(_AIX)69/* See W. Richard Stevens, "UNIX Network Programming, Volume 1", p. 254:70* 'Setting the address family to AF_UNSPEC might return EAFNOSUPPORT71* but that is acceptable.72*/73if (rv < 0 && errno == EAFNOSUPPORT)74rv = errno = 0;75#endif // defined(_ALLBSD_SOURCE) || defined(_AIX)7677if (rv < 0)78handleSocketError(env, errno);79}8081JNIEXPORT jint JNICALL82Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jclass clazz,83jobject fdo, jlong bufAddress,84jint len, jlong senderAddress,85jboolean connected)86{87jint fd = fdval(env, fdo);88void *buf = (void *)jlong_to_ptr(bufAddress);89SOCKETADDRESS *sa = (SOCKETADDRESS *)jlong_to_ptr(senderAddress);90socklen_t sa_len = sizeof(SOCKETADDRESS);91jboolean retry = JNI_FALSE;92jint n;9394if (len > MAX_PACKET_LEN) {95len = MAX_PACKET_LEN;96}9798do {99retry = JNI_FALSE;100n = recvfrom(fd, buf, len, 0, (struct sockaddr *)sa, &sa_len);101if (n < 0) {102if (errno == EAGAIN || errno == EWOULDBLOCK) {103return IOS_UNAVAILABLE;104}105if (errno == EINTR) {106return IOS_INTERRUPTED;107}108if (errno == ECONNREFUSED) {109if (connected == JNI_FALSE) {110retry = JNI_TRUE;111} else {112JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);113return IOS_THROWN;114}115} else {116return handleSocketError(env, errno);117}118}119} while (retry == JNI_TRUE);120121return n;122}123124JNIEXPORT jint JNICALL125Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jclass clazz,126jobject fdo, jlong bufAddress, jint len,127jlong targetAddress, jint targetAddressLen)128{129jint fd = fdval(env, fdo);130void *buf = (void *)jlong_to_ptr(bufAddress);131SOCKETADDRESS *sa = (SOCKETADDRESS *)jlong_to_ptr(targetAddress);132socklen_t sa_len = (socklen_t) targetAddressLen;133jint n;134135if (len > MAX_PACKET_LEN) {136len = MAX_PACKET_LEN;137}138139n = sendto(fd, buf, len, 0, (struct sockaddr *)sa, sa_len);140if (n < 0) {141if (errno == EAGAIN || errno == EWOULDBLOCK) {142return IOS_UNAVAILABLE;143}144if (errno == EINTR) {145return IOS_INTERRUPTED;146}147if (errno == ECONNREFUSED) {148JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);149return IOS_THROWN;150}151return handleSocketError(env, errno);152}153return n;154}155156157