Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c
32301 views
/*1* Copyright (c) 2009, 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 <stdlib.h>26#include <string.h>27#include <dlfcn.h>2829#include "Sctp.h"30#include "jni.h"31#include "jni_util.h"32#include "nio_util.h"33#include "nio.h"34#include "net_util.h"35#include "net_util_md.h"36#include "sun_nio_ch_sctp_SctpNet.h"37#include "sun_nio_ch_sctp_SctpStdSocketOption.h"3839static jclass isaCls = 0;40static jmethodID isaCtrID = 0;4142static const char* nativeSctpLib = "libsctp.so.1";43static jboolean funcsLoaded = JNI_FALSE;4445sctp_getladdrs_func* nio_sctp_getladdrs;46sctp_freeladdrs_func* nio_sctp_freeladdrs;47sctp_getpaddrs_func* nio_sctp_getpaddrs;48sctp_freepaddrs_func* nio_sctp_freepaddrs;49sctp_bindx_func* nio_sctp_bindx;50sctp_peeloff_func* nio_sctp_peeloff;5152JNIEXPORT jint JNICALL JNI_OnLoad53(JavaVM *vm, void *reserved) {54return JNI_VERSION_1_2;55}5657static int preCloseFD = -1; /* File descriptor to which we dup other fd's58before closing them for real */5960/**61* Loads the native sctp library that contains the socket extension62* functions, as well as locating the individual functions.63* There will be a pending exception if this method returns false.64*/65jboolean loadSocketExtensionFuncs66(JNIEnv* env) {67if (dlopen(nativeSctpLib, RTLD_GLOBAL | RTLD_LAZY) == NULL) {68JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",69dlerror());70return JNI_FALSE;71}7273if ((nio_sctp_getladdrs = (sctp_getladdrs_func*)74dlsym(RTLD_DEFAULT, "sctp_getladdrs")) == NULL) {75JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",76dlerror());77return JNI_FALSE;78}7980if ((nio_sctp_freeladdrs = (sctp_freeladdrs_func*)81dlsym(RTLD_DEFAULT, "sctp_freeladdrs")) == NULL) {82JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",83dlerror());84return JNI_FALSE;85}8687if ((nio_sctp_getpaddrs = (sctp_getpaddrs_func*)88dlsym(RTLD_DEFAULT, "sctp_getpaddrs")) == NULL) {89JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",90dlerror());91return JNI_FALSE;92}9394if ((nio_sctp_freepaddrs = (sctp_freepaddrs_func*)95dlsym(RTLD_DEFAULT, "sctp_freepaddrs")) == NULL) {96JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",97dlerror());98return JNI_FALSE;99}100101if ((nio_sctp_bindx = (sctp_bindx_func*)102dlsym(RTLD_DEFAULT, "sctp_bindx")) == NULL) {103JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",104dlerror());105return JNI_FALSE;106}107108if ((nio_sctp_peeloff = (sctp_peeloff_func*)109dlsym(RTLD_DEFAULT, "sctp_peeloff")) == NULL) {110JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",111dlerror());112return JNI_FALSE;113}114115funcsLoaded = JNI_TRUE;116return JNI_TRUE;117}118119jint120handleSocketError(JNIEnv *env, jint errorValue)121{122char *xn;123switch (errorValue) {124case EINPROGRESS: /* Non-blocking connect */125return 0;126case EPROTO:127xn= JNU_JAVANETPKG "ProtocolException";128break;129case ECONNREFUSED:130xn = JNU_JAVANETPKG "ConnectException";131break;132case ETIMEDOUT:133xn = JNU_JAVANETPKG "ConnectException";134break;135case EHOSTUNREACH:136xn = JNU_JAVANETPKG "NoRouteToHostException";137break;138case EADDRINUSE: /* Fall through */139case EADDRNOTAVAIL:140xn = JNU_JAVANETPKG "BindException";141break;142default:143xn = JNU_JAVANETPKG "SocketException";144break;145}146errno = errorValue;147JNU_ThrowByNameWithLastError(env, xn, "NioSocketError");148return IOS_THROWN;149}150151/*152* Class: sun_nio_ch_sctp_SctpNet153* Method: init154* Signature: ()V155*/156JNIEXPORT void JNICALL157Java_sun_nio_ch_sctp_SctpNet_init158(JNIEnv *env, jclass cl) {159int sp[2];160if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {161JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");162return;163}164preCloseFD = sp[0];165close(sp[1]);166initInetAddressIDs(env);167}168169/*170* Class: sun_nio_ch_sctp_SctpNet171* Method: socket0172* Signature: (Z)I173*/174JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpNet_socket0175(JNIEnv *env, jclass klass, jboolean oneToOne) {176int fd;177struct sctp_event_subscribe event;178#ifdef AF_INET6179int domain = ipv6_available() ? AF_INET6 : AF_INET;180#else181int domain = AF_INET;182#endif183184/* Try to load the socket API extension functions */185if (!funcsLoaded && !loadSocketExtensionFuncs(env)) {186return 0;187}188189fd = socket(domain, (oneToOne ? SOCK_STREAM : SOCK_SEQPACKET), IPPROTO_SCTP);190191if (fd < 0) {192return handleSocketError(env, errno);193}194195/* Enable events */196memset(&event, 0, sizeof(event));197event.sctp_data_io_event = 1;198event.sctp_association_event = 1;199event.sctp_address_event = 1;200event.sctp_send_failure_event = 1;201//event.sctp_peer_error_event = 1;202event.sctp_shutdown_event = 1;203//event.sctp_partial_delivery_event = 1;204//event.sctp_adaptation_layer_event = 1;205if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) {206handleSocketError(env, errno);207}208return fd;209}210211/*212* Class: sun_nio_ch_sctp_SctpNet213* Method: bindx214* Signature: (I[Ljava/net/InetAddress;IIZ)V215*/216JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_bindx217(JNIEnv *env, jclass klass, jint fd, jobjectArray addrs, jint port,218jint addrsLength, jboolean add, jboolean preferIPv6) {219SOCKADDR *sap, *tmpSap;220int i, sa_len = sizeof(SOCKADDR);221jobject ia;222223if (addrsLength < 1)224return;225226if ((sap = calloc(addrsLength, sa_len)) == NULL) {227JNU_ThrowOutOfMemoryError(env, "heap allocation failure");228return;229}230231tmpSap = sap;232for (i=0; i<addrsLength; i++) {233ia = (*env)->GetObjectArrayElement(env, addrs, i);234if (NET_InetAddressToSockaddr(env, ia, port, (struct sockaddr*)tmpSap,235&sa_len, preferIPv6) != 0) {236free(sap);237return;238}239tmpSap++;240}241242if (nio_sctp_bindx(fd, (void*)sap, addrsLength, add ? SCTP_BINDX_ADD_ADDR :243SCTP_BINDX_REM_ADDR) != 0) {244handleSocketError(env, errno);245}246247free(sap);248}249250/*251* Class: sun_nio_ch_sctp_SctpNet252* Method: listen0253* Signature: (II)V254*/255JNIEXPORT void JNICALL256Java_sun_nio_ch_sctp_SctpNet_listen0257(JNIEnv *env, jclass cl, jint fd, jint backlog) {258if (listen(fd, backlog) < 0)259handleSocketError(env, errno);260}261262/*263* Class: sun_nio_ch_sctp_SctpNet264* Method: connect0265* Signature: (ILjava/net/InetAddress;I)I266*/267JNIEXPORT jint JNICALL268Java_sun_nio_ch_sctp_SctpNet_connect0269(JNIEnv *env, jclass clazz, int fd, jobject iao, jint port) {270SOCKADDR sa;271int sa_len = SOCKADDR_LEN;272int rv;273274if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *) &sa,275&sa_len, JNI_TRUE) != 0) {276return IOS_THROWN;277}278279rv = connect(fd, (struct sockaddr *)&sa, sa_len);280if (rv != 0) {281if (errno == EINPROGRESS) {282return IOS_UNAVAILABLE;283} else if (errno == EINTR) {284return IOS_INTERRUPTED;285}286return handleSocketError(env, errno);287}288return 1;289}290291/*292* Class: sun_nio_ch_sctp_SctpNet293* Method: close0294* Signature: (I)V295*/296JNIEXPORT void JNICALL297Java_sun_nio_ch_sctp_SctpNet_close0298(JNIEnv *env, jclass clazz, jint fd) {299if (fd != -1) {300int rv = close(fd);301if (rv < 0)302JNU_ThrowIOExceptionWithLastError(env, "Close failed");303}304}305306/*307* Class: sun_nio_ch_sctp_SctpNet308* Method: preClose0309* Signature: (I)V310*/311JNIEXPORT void JNICALL312Java_sun_nio_ch_sctp_SctpNet_preClose0313(JNIEnv *env, jclass clazz, jint fd) {314if (preCloseFD >= 0) {315if (dup2(preCloseFD, fd) < 0)316JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");317}318}319320void initializeISA321(JNIEnv* env) {322if (isaCls == 0) {323jclass c = (*env)->FindClass(env, "java/net/InetSocketAddress");324CHECK_NULL(c);325isaCtrID = (*env)->GetMethodID(env, c, "<init>",326"(Ljava/net/InetAddress;I)V");327CHECK_NULL(isaCtrID);328isaCls = (*env)->NewGlobalRef(env, c);329CHECK_NULL(isaCls);330(*env)->DeleteLocalRef(env, c);331}332}333334jobject SockAddrToInetSocketAddress335(JNIEnv *env, struct sockaddr* sap) {336int port = 0;337338jobject ia = NET_SockaddrToInetAddress(env, sap, &port);339if (ia == NULL)340return NULL;341342if (isaCls == 0) {343initializeISA(env);344CHECK_NULL_RETURN(isaCls, NULL);345}346347return (*env)->NewObject(env, isaCls, isaCtrID, ia, port);348}349350/*351* Class: sun_nio_ch_sctp_SctpNet352* Method: getLocalAddresses0353* Signature: (I)[Ljava/net/SocketAddress;354*/355JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_sctp_SctpNet_getLocalAddresses0356(JNIEnv *env, jclass klass, jint fd) {357void *addr_buf, *laddr;358struct sockaddr* sap;359int i, addrCount;360jobjectArray isaa;361362#ifdef __solaris__363if ((addrCount = nio_sctp_getladdrs(fd, 0, (void **)&addr_buf)) == -1) {364#else /* __linux__ */365if ((addrCount = nio_sctp_getladdrs(fd, 0, (struct sockaddr **)&addr_buf)) == -1) {366#endif367handleSocketError(env, errno);368return NULL;369}370371if (addrCount < 1)372return NULL;373374if (isaCls == 0) {375initializeISA(env);376CHECK_NULL_RETURN(isaCls, NULL);377}378379isaa = (*env)->NewObjectArray(env, addrCount, isaCls, NULL);380if (isaa == NULL) {381nio_sctp_freeladdrs(addr_buf);382return NULL;383}384385laddr = addr_buf;386for (i=0; i<addrCount; i++) {387int port = 0;388jobject isa = NULL, ia;389sap = (struct sockaddr*)addr_buf;390ia = NET_SockaddrToInetAddress(env, sap, &port);391if (ia != NULL)392isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);393if (isa == NULL)394break;395(*env)->SetObjectArrayElement(env, isaa, i, isa);396397if (sap->sa_family == AF_INET)398addr_buf = ((struct sockaddr_in*)addr_buf) + 1;399else400addr_buf = ((struct sockaddr_in6*)addr_buf) + 1;401}402403nio_sctp_freeladdrs(laddr);404return isaa;405}406407jobjectArray getRemoteAddresses408(JNIEnv *env, jint fd, sctp_assoc_t id) {409void *addr_buf, *paddr;410struct sockaddr* sap;411int i, addrCount;412jobjectArray isaa;413414#if __solaris__415if ((addrCount = nio_sctp_getpaddrs(fd, id, (void **)&addr_buf)) == -1) {416#else /* __linux__ */417if ((addrCount = nio_sctp_getpaddrs(fd, id, (struct sockaddr**)&addr_buf)) == -1) {418#endif419handleSocketError(env, errno);420return NULL;421}422423if (addrCount < 1)424return NULL;425426if (isaCls == 0) {427initializeISA(env);428CHECK_NULL_RETURN(isaCls, NULL);429}430431isaa = (*env)->NewObjectArray(env, addrCount, isaCls, NULL);432if (isaa == NULL) {433nio_sctp_freepaddrs(addr_buf);434return NULL;435}436437paddr = addr_buf;438for (i=0; i<addrCount; i++) {439jobject ia, isa = NULL;440int port = 0;441sap = (struct sockaddr*)addr_buf;442ia = NET_SockaddrToInetAddress(env, sap, &port);443if (ia != NULL)444isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);445if (isa == NULL)446break;447(*env)->SetObjectArrayElement(env, isaa, i, isa);448449if (sap->sa_family == AF_INET)450addr_buf = ((struct sockaddr_in*)addr_buf) + 1;451else452addr_buf = ((struct sockaddr_in6*)addr_buf) + 1;453}454455nio_sctp_freepaddrs(paddr);456457return isaa;458}459460/*461* Class: sun_nio_ch_sctp_SctpNet462* Method: getRemoteAddresses0463* Signature: (II)[Ljava/net/SocketAddress;464*/465JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_sctp_SctpNet_getRemoteAddresses0466(JNIEnv *env, jclass klass, jint fd, jint assocId) {467return getRemoteAddresses(env, fd, assocId);468}469470/* Map the Java level option to the native level */471int mapSocketOption472(jint cmd, int *level, int *optname) {473static struct {474jint cmd;475int level;476int optname;477} const opts[] = {478{ sun_nio_ch_sctp_SctpStdSocketOption_SCTP_DISABLE_FRAGMENTS, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS },479{ sun_nio_ch_sctp_SctpStdSocketOption_SCTP_EXPLICIT_COMPLETE, IPPROTO_SCTP, SCTP_EXPLICIT_EOR },480{ sun_nio_ch_sctp_SctpStdSocketOption_SCTP_FRAGMENT_INTERLEAVE, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE },481{ sun_nio_ch_sctp_SctpStdSocketOption_SCTP_NODELAY, IPPROTO_SCTP, SCTP_NODELAY },482{ sun_nio_ch_sctp_SctpStdSocketOption_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF },483{ sun_nio_ch_sctp_SctpStdSocketOption_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },484{ sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER, SOL_SOCKET, SO_LINGER } };485486int i;487for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) {488if (cmd == opts[i].cmd) {489*level = opts[i].level;490*optname = opts[i].optname;491return 0;492}493}494495/* not found */496return -1;497}498499/*500* Class: sun_nio_ch_sctp_SctpNet501* Method: setIntOption0502* Signature: (III)V503*/504JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setIntOption0505(JNIEnv *env, jclass klass, jint fd, jint opt, int arg) {506int klevel, kopt;507int result;508struct linger linger;509void *parg;510int arglen;511512if (mapSocketOption(opt, &klevel, &kopt) < 0) {513JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",514"Unsupported socket option");515return;516}517518if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER) {519parg = (void *)&linger;520arglen = sizeof(linger);521if (arg >= 0) {522linger.l_onoff = 1;523linger.l_linger = arg;524} else {525linger.l_onoff = 0;526linger.l_linger = 0;527}528} else {529parg = (void *)&arg;530arglen = sizeof(arg);531}532533if (NET_SetSockOpt(fd, klevel, kopt, parg, arglen) < 0) {534JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",535"sun_nio_ch_sctp_SctpNet.setIntOption0");536}537}538539/*540* Class: sun_nio_ch_sctp_SctpNet541* Method: getIntOption0542* Signature: (II)I543*/544JNIEXPORT int JNICALL Java_sun_nio_ch_sctp_SctpNet_getIntOption0545(JNIEnv *env, jclass klass, jint fd, jint opt) {546int klevel, kopt;547int result;548struct linger linger;549void *arg;550int arglen;551552memset((char *) &linger, 0, sizeof(linger));553if (mapSocketOption(opt, &klevel, &kopt) < 0) {554JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",555"Unsupported socket option");556return -1;557}558559if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER) {560arg = (void *)&linger;561arglen = sizeof(linger);562} else {563arg = (void *)&result;564arglen = sizeof(result);565}566567if (NET_GetSockOpt(fd, klevel, kopt, arg, &arglen) < 0) {568JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",569"sun.nio.ch.Net.getIntOption");570return -1;571}572573if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER)574return linger.l_onoff ? linger.l_linger : -1;575else576return result;577}578579/*580* Class: sun_nio_ch_sctp_SctpNet581* Method: getPrimAddrOption0582* Signature: (II)Ljava/net/SocketAddress;583*/584JNIEXPORT jobject JNICALL Java_sun_nio_ch_sctp_SctpNet_getPrimAddrOption0585(JNIEnv *env, jclass klass, jint fd, jint assocId) {586struct sctp_setprim prim;587unsigned int prim_len = sizeof(prim);588struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;589590prim.ssp_assoc_id = assocId;591592if (getsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, &prim_len) < 0) {593JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",594"sun.nio.ch.SctpNet.getPrimAddrOption0");595return NULL;596}597598return SockAddrToInetSocketAddress(env, sap);599}600601/*602* Class: sun_nio_ch_sctp_SctpNet603* Method: setPrimAddrOption0604* Signature: (IILjava/net/InetAddress;I)V605*/606JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setPrimAddrOption0607(JNIEnv *env, jclass klass, jint fd, jint assocId, jobject iaObj, jint port) {608struct sctp_setprim prim;609struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;610int sap_len = sizeof(sap);611612if (NET_InetAddressToSockaddr(env, iaObj, port, sap,613&sap_len, JNI_TRUE) != 0) {614return;615}616617prim.ssp_assoc_id = assocId;618619if (setsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, sizeof(prim)) < 0) {620JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",621"sun.nio.ch.SctpNet.setPrimAddrOption0");622}623}624625/*626* Class: sun_nio_ch_sctp_SctpNet627* Method: setPeerPrimAddrOption0628* Signature: (IILjava/net/InetAddress;I)V629*/630JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setPeerPrimAddrOption0631(JNIEnv *env, jclass klass, jint fd, jint assocId,632jobject iaObj, jint port, jboolean preferIPv6) {633struct sctp_setpeerprim prim;634struct sockaddr* sap = (struct sockaddr*)&prim.sspp_addr;635int sap_len = sizeof(sap);636637if (NET_InetAddressToSockaddr(env, iaObj, port, sap,638&sap_len, preferIPv6) != 0) {639return;640}641642prim.sspp_assoc_id = assocId;643644if (setsockopt(fd, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, &prim,645sizeof(prim)) < 0) {646JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",647"sun.nio.ch.SctpNet.setPeerPrimAddrOption0");648}649}650651/*652* Class: sun_nio_ch_sctp_SctpNet653* Method: getInitMsgOption0654* Signature: (I[I)V655*/656JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_getInitMsgOption0657(JNIEnv *env, jclass klass, jint fd, jintArray retVal) {658struct sctp_initmsg sctp_initmsg;659unsigned int sim_len = sizeof(sctp_initmsg);660int vals[2];661662if (getsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg,663&sim_len) < 0) {664JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",665"sun.nio.ch.SctpNet.getInitMsgOption0");666return;667}668669vals[0] = sctp_initmsg.sinit_max_instreams;670vals[1] = sctp_initmsg.sinit_num_ostreams;671(*env)->SetIntArrayRegion(env, retVal, 0, 2, vals);672}673674/*675* Class: sun_nio_ch_sctp_SctpNet676* Method: setInitMsgOption0677* Signature: (III)V678*/679JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setInitMsgOption0680(JNIEnv *env, jclass klass, jint fd, jint inArg, jint outArg) {681struct sctp_initmsg sctp_initmsg;682683sctp_initmsg.sinit_max_instreams = (unsigned int)inArg;684sctp_initmsg.sinit_num_ostreams = (unsigned int)outArg;685sctp_initmsg.sinit_max_attempts = 0; // default686sctp_initmsg.sinit_max_init_timeo = 0; // default687688if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg,689sizeof(sctp_initmsg)) < 0) {690JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",691"sun.nio.ch.SctpNet.setInitMsgOption0");692}693}694695/*696* Class: sun_nio_ch_sctp_SctpNet697* Method: shutdown0698* Signature: (II)V699*/700JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_shutdown0701(JNIEnv *env, jclass klass, jint fd, jint assocId) {702int rv;703struct msghdr msg[1];704struct iovec iov[1];705int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));706char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];707struct cmsghdr* cmsg;708struct sctp_sndrcvinfo *sri;709710/* SctpSocketChannel */711if (assocId < 0) {712shutdown(fd, SHUT_WR);713return;714}715716memset(msg, 0, sizeof (*msg));717memset(cbuf, 0, cbuf_size);718msg->msg_name = NULL;719msg->msg_namelen = 0;720iov->iov_base = NULL;721iov->iov_len = 0;722msg->msg_iov = iov;723msg->msg_iovlen = 1;724msg->msg_control = cbuf;725msg->msg_controllen = cbuf_size;726msg->msg_flags = 0;727728cmsg = CMSG_FIRSTHDR(msg);729cmsg->cmsg_level = IPPROTO_SCTP;730cmsg->cmsg_type = SCTP_SNDRCV;731cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));732733/* Initialize the payload: */734sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);735memset(sri, 0, sizeof (*sri));736737if (assocId > 0) {738sri->sinfo_assoc_id = assocId;739}740741sri->sinfo_flags = sri->sinfo_flags | SCTP_EOF;742743/* Sum of the length of all control messages in the buffer. */744msg->msg_controllen = cmsg->cmsg_len;745746if ((rv = sendmsg(fd, msg, 0)) < 0) {747handleSocketError(env, errno);748}749}750751/*752* Class: sun_nio_ch_sctp_SctpNet753* Method: branch754* Signature: (II)I755*/756JNIEXPORT int JNICALL Java_sun_nio_ch_sctp_SctpNet_branch0757(JNIEnv *env, jclass klass, jint fd, jint assocId) {758int newfd = 0;759if ((newfd = nio_sctp_peeloff(fd, assocId)) < 0) {760handleSocketError(env, errno);761}762763return newfd;764}765766767