jdk/src/solaris/native/sun/nio/ch/SctpChannelImpl.c
changeset 12128 09f5d262e329
parent 12127 eab1e4be8495
parent 11872 c51754cddc03
child 12129 561811d8ba18
--- a/jdk/src/solaris/native/sun/nio/ch/SctpChannelImpl.c	Fri Feb 17 10:18:50 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,594 +0,0 @@
-/*
- * Copyright (c) 2009, 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.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "Sctp.h"
-
-#include "jni.h"
-#include "nio_util.h"
-#include "nio.h"
-#include "net_util.h"
-#include "net_util_md.h"
-#include "sun_nio_ch_SctpNet.h"
-#include "sun_nio_ch_SctpChannelImpl.h"
-#include "sun_nio_ch_SctpAssocChange.h"
-#include "sun_nio_ch_SctpResultContainer.h"
-#include "sun_nio_ch_SctpPeerAddrChange.h"
-
-/* sizeof(union sctp_notification */
-#define NOTIFICATION_BUFFER_SIZE 280
-
-#define MESSAGE_IMPL_CLASS              "sun/nio/ch/SctpMessageInfoImpl"
-#define RESULT_CONTAINER_CLASS          "sun/nio/ch/SctpResultContainer"
-#define SEND_FAILED_CLASS               "sun/nio/ch/SctpSendFailed"
-#define ASSOC_CHANGE_CLASS              "sun/nio/ch/SctpAssocChange"
-#define PEER_CHANGE_CLASS               "sun/nio/ch/SctpPeerAddrChange"
-#define SHUTDOWN_CLASS                  "sun/nio/ch/SctpShutdown"
-
-struct controlData {
-    int assocId;
-    unsigned short streamNumber;
-    jboolean unordered;
-    unsigned int ppid;
-};
-
-static jclass    smi_class;    /* sun.nio.ch.SctpMessageInfoImpl            */
-static jmethodID smi_ctrID;    /* sun.nio.ch.SctpMessageInfoImpl.<init>     */
-static jfieldID  src_valueID;  /* sun.nio.ch.SctpResultContainer.value      */
-static jfieldID  src_typeID;   /* sun.nio.ch.SctpResultContainer.type       */
-static jclass    ssf_class;    /* sun.nio.ch.SctpSendFailed                 */
-static jmethodID ssf_ctrID;    /* sun.nio.ch.SctpSendFailed.<init>          */
-static jclass    sac_class;    /* sun.nio.ch.SctpAssociationChanged         */
-static jmethodID sac_ctrID;    /* sun.nio.ch.SctpAssociationChanged.<init>  */
-static jclass    spc_class;    /* sun.nio.ch.SctpPeerAddressChanged         */
-static jmethodID spc_ctrID;    /* sun.nio.ch.SctpPeerAddressChanged.<init>  */
-static jclass    ss_class;     /* sun.nio.ch.SctpShutdown                   */
-static jmethodID ss_ctrID;     /* sun.nio.ch.SctpShutdown.<init>            */
-static jfieldID  isa_addrID;   /* java.net.InetSocketAddress.addr           */
-static jfieldID  isa_portID;   /* java.net.InetSocketAddress.port           */
-
-/* defined in SctpNet.c */
-jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
-
-/* use SocketChannelImpl's checkConnect implementation */
-extern jint Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv* env,
-    jobject this, jobject fdo, jboolean block, jboolean ready);
-
-/*
- * Class:     sun_nio_ch_SctpChannelImpl
- * Method:    initIDs
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpChannelImpl_initIDs
-  (JNIEnv *env, jclass klass) {
-    jclass cls;
-
-    /* SctpMessageInfoImpl */
-    cls = (*env)->FindClass(env, MESSAGE_IMPL_CLASS);
-    CHECK_NULL(cls);
-    smi_class = (*env)->NewGlobalRef(env, cls);
-    CHECK_NULL(smi_class);
-    smi_ctrID = (*env)->GetMethodID(env, cls, "<init>",
-            "(ILjava/net/SocketAddress;IIZZI)V");
-    CHECK_NULL(smi_ctrID);
-
-    /* SctpResultContainer */
-    cls = (*env)->FindClass(env, RESULT_CONTAINER_CLASS);
-    CHECK_NULL(cls);
-    src_valueID = (*env)->GetFieldID(env, cls, "value", "Ljava/lang/Object;");
-    CHECK_NULL(src_valueID);
-    src_typeID = (*env)->GetFieldID(env, cls, "type", "I");
-    CHECK_NULL(src_typeID);
-
-    /* SctpSendFailed */
-    cls = (*env)->FindClass(env, SEND_FAILED_CLASS);
-    CHECK_NULL(cls);
-    ssf_class = (*env)->NewGlobalRef(env, cls);
-    CHECK_NULL(ssf_class);
-    ssf_ctrID = (*env)->GetMethodID(env, cls, "<init>",
-        "(ILjava/net/SocketAddress;Ljava/nio/ByteBuffer;II)V");
-    CHECK_NULL(ssf_ctrID);
-
-    /* SctpAssocChange */
-    cls = (*env)->FindClass(env, ASSOC_CHANGE_CLASS);
-    CHECK_NULL(cls);
-    sac_class = (*env)->NewGlobalRef(env, cls);
-    CHECK_NULL(sac_class);
-    sac_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(IIII)V");
-    CHECK_NULL(sac_ctrID);
-
-    /* SctpPeerAddrChange */
-    cls = (*env)->FindClass(env, PEER_CHANGE_CLASS);
-    CHECK_NULL(cls);
-    spc_class = (*env)->NewGlobalRef(env, cls);
-    CHECK_NULL(spc_class);
-    spc_ctrID = (*env)->GetMethodID(env, cls, "<init>",
-            "(ILjava/net/SocketAddress;I)V");
-    CHECK_NULL(spc_ctrID);
-
-    /* sun.nio.ch.SctpShutdown */
-    cls = (*env)->FindClass(env, SHUTDOWN_CLASS);
-    CHECK_NULL(cls);
-    ss_class = (*env)->NewGlobalRef(env, cls);
-    CHECK_NULL(ss_class);
-    ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
-    CHECK_NULL(ss_ctrID);
-
-    /* InetSocketAddress */
-    cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
-    CHECK_NULL(cls);
-    isa_addrID = (*env)->GetFieldID(env, cls, "addr", "Ljava/net/InetAddress;");
-    CHECK_NULL(isa_addrID);
-    isa_portID = (*env)->GetFieldID(env, cls, "port", "I");
-}
-
-void getControlData
-  (struct msghdr* msg, struct controlData* cdata) {
-    struct cmsghdr* cmsg;
-
-    for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
-        if (cmsg->cmsg_level == IPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCV) {
-            struct sctp_sndrcvinfo *sri;
-
-            sri = (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg);
-            cdata->assocId = sri->sinfo_assoc_id;
-            cdata->streamNumber = sri->sinfo_stream;
-            cdata->unordered = (sri->sinfo_flags & SCTP_UNORDERED) ? JNI_TRUE :
-                JNI_FALSE;
-            cdata->ppid = ntohl(sri->sinfo_ppid);
-
-            return;
-        }
-    }
-    return;
-}
-
-void setControlData
-  (struct msghdr* msg, struct controlData* cdata) {
-    struct cmsghdr* cmsg;
-    struct sctp_sndrcvinfo *sri;
-
-    cmsg = CMSG_FIRSTHDR(msg);
-    cmsg->cmsg_level = IPPROTO_SCTP;
-    cmsg->cmsg_type = SCTP_SNDRCV;
-    cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
-
-    /* Initialize the payload */
-    sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);
-    memset(sri, 0, sizeof (*sri));
-
-    if (cdata->streamNumber > 0) {
-        sri->sinfo_stream = cdata->streamNumber;
-    }
-    if (cdata->assocId > 0) {
-        sri->sinfo_assoc_id = cdata->assocId;
-    }
-    if (cdata->unordered == JNI_TRUE) {
-        sri->sinfo_flags = sri->sinfo_flags | SCTP_UNORDERED;
-    }
-
-    if (cdata->ppid > 0) {
-        sri->sinfo_ppid = htonl(cdata->ppid);
-    }
-
-    /* Sum of the length of all control messages in the buffer. */
-    msg->msg_controllen = cmsg->cmsg_len;
-}
-
-// TODO: test: can create send failed without any data? if so need to
-// update API so that buffer can be null if no data.
-void handleSendFailed
-  (JNIEnv* env, int fd, jobject resultContainerObj, struct sctp_send_failed *ssf,
-   int read, jboolean isEOR, struct sockaddr* sap) {
-    jobject bufferObj = NULL, resultObj, isaObj;
-    char *addressP;
-    struct sctp_sndrcvinfo *sri;
-    int remaining, dataLength;
-
-    /* the actual undelivered message data is directly after the ssf */
-    int dataOffset = sizeof(struct sctp_send_failed);
-
-    sri = (struct sctp_sndrcvinfo*) &ssf->ssf_info;
-
-    /* the number of bytes remaining to be read in the sctp_send_failed notif*/
-    remaining = ssf->ssf_length - read;
-
-    /* the size of the actual undelivered message */
-    dataLength = ssf->ssf_length - dataOffset;
-
-    /* retrieved address from sockaddr */
-    isaObj = SockAddrToInetSocketAddress(env, sap);
-
-    /* data retrieved from sff_data */
-    if (dataLength > 0) {
-        struct iovec iov[1];
-        struct msghdr msg[1];
-        int rv, alreadyRead;
-        char *dataP = (char*) ssf;
-        dataP += dataOffset;
-
-        if ((addressP = malloc(dataLength)) == NULL) {
-            JNU_ThrowOutOfMemoryError(env, "handleSendFailed");
-            return;
-        }
-
-        memset(msg, 0, sizeof (*msg));
-        msg->msg_iov = iov;
-        msg->msg_iovlen = 1;
-
-        bufferObj = (*env)->NewDirectByteBuffer(env, addressP, dataLength);
-        CHECK_NULL(bufferObj);
-
-        alreadyRead = read - dataOffset;
-        if (alreadyRead > 0) {
-            memcpy(addressP, /*ssf->ssf_data*/ dataP, alreadyRead);
-            iov->iov_base = addressP + alreadyRead;
-            iov->iov_len = dataLength - alreadyRead;
-        } else {
-            iov->iov_base = addressP;
-            iov->iov_len = dataLength;
-        }
-
-        if (remaining > 0) {
-            if ((rv = recvmsg(fd, msg, 0)) < 0) {
-                handleSocketError(env, errno);
-                return;
-            }
-
-            if (rv != (dataLength - alreadyRead) || !(msg->msg_flags & MSG_EOR)) {
-                //TODO: assert false: "should not reach here";
-                return;
-            }
-            // TODO: Set and document (in API) buffers position.
-        }
-    }
-
-    /* create SctpSendFailed */
-    resultObj = (*env)->NewObject(env, ssf_class, ssf_ctrID, ssf->ssf_assoc_id,
-            isaObj, bufferObj, ssf->ssf_error, sri->sinfo_stream);
-    CHECK_NULL(resultObj);
-    (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
-    (*env)->SetIntField(env, resultContainerObj, src_typeID,
-            sun_nio_ch_SctpResultContainer_SEND_FAILED);
-}
-
-void handleAssocChange
-  (JNIEnv* env, jobject resultContainerObj, struct sctp_assoc_change *sac) {
-    jobject resultObj;
-    int state = 0;
-
-    switch (sac->sac_state) {
-        case SCTP_COMM_UP :
-            state = sun_nio_ch_SctpAssocChange_SCTP_COMM_UP;
-            break;
-        case SCTP_COMM_LOST :
-            state = sun_nio_ch_SctpAssocChange_SCTP_COMM_LOST;
-            break;
-        case SCTP_RESTART :
-            state = sun_nio_ch_SctpAssocChange_SCTP_RESTART;
-            break;
-        case SCTP_SHUTDOWN_COMP :
-            state = sun_nio_ch_SctpAssocChange_SCTP_SHUTDOWN;
-            break;
-        case SCTP_CANT_STR_ASSOC :
-            state = sun_nio_ch_SctpAssocChange_SCTP_CANT_START;
-    }
-
-    /* create SctpAssociationChanged */
-    resultObj = (*env)->NewObject(env, sac_class, sac_ctrID, sac->sac_assoc_id,
-        state, sac->sac_outbound_streams, sac->sac_inbound_streams);
-    CHECK_NULL(resultObj);
-    (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
-    (*env)->SetIntField(env, resultContainerObj, src_typeID,
-            sun_nio_ch_SctpResultContainer_ASSOCIATION_CHANGED);
-}
-
-void handleShutdown
-  (JNIEnv* env, jobject resultContainerObj, struct sctp_shutdown_event* sse) {
-    /* create SctpShutdown */
-    jobject resultObj = (*env)->NewObject(env, ss_class, ss_ctrID, sse->sse_assoc_id);
-    CHECK_NULL(resultObj);
-    (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
-    (*env)->SetIntField(env, resultContainerObj, src_typeID,
-            sun_nio_ch_SctpResultContainer_SHUTDOWN);
-}
-
-void handlePeerAddrChange
-  (JNIEnv* env, jobject resultContainerObj, struct sctp_paddr_change* spc) {
-    int event = 0;
-    jobject addressObj, resultObj;
-    unsigned int state = spc->spc_state;
-
-    switch (state) {
-        case SCTP_ADDR_AVAILABLE :
-            event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_AVAILABLE;
-            break;
-        case SCTP_ADDR_UNREACHABLE :
-            event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_UNREACHABLE;
-            break;
-        case SCTP_ADDR_REMOVED :
-            event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_REMOVED;
-            break;
-        case SCTP_ADDR_ADDED :
-            event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_ADDED;
-            break;
-        case SCTP_ADDR_MADE_PRIM :
-            event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_MADE_PRIM;
-#ifdef __linux__  /* Solaris currently doesn't support SCTP_ADDR_CONFIRMED */
-            break;
-        case SCTP_ADDR_CONFIRMED :
-            event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_CONFIRMED;
-#endif  /* __linux__ */
-    }
-
-    addressObj = SockAddrToInetSocketAddress(env, (struct sockaddr*)&spc->spc_aaddr);
-
-    /* create SctpPeerAddressChanged */
-    resultObj = (*env)->NewObject(env, spc_class, spc_ctrID, spc->spc_assoc_id,
-            addressObj, event);
-    CHECK_NULL(resultObj);
-    (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
-    (*env)->SetIntField(env, resultContainerObj, src_typeID,
-            sun_nio_ch_SctpResultContainer_PEER_ADDRESS_CHANGED);
-}
-
-void handleUninteresting
-  (union sctp_notification *snp) {
-    //fprintf(stdout,"\nNative: handleUninterestingNotification: Receive notification type [%u]", snp->sn_header.sn_type);
-}
-
-/**
- * Handle notifications from the SCTP stack.
- * Returns JNI_TRUE if the notification is one that is of interest to the
- * Java API, otherwise JNI_FALSE.
- */
-jboolean handleNotification
-  (JNIEnv* env, int fd, jobject resultContainerObj, union sctp_notification* snp,
-   int read, jboolean isEOR, struct sockaddr* sap) {
-    switch (snp->sn_header.sn_type) {
-        case SCTP_SEND_FAILED:
-            handleSendFailed(env, fd, resultContainerObj, &snp->sn_send_failed,
-                    read, isEOR, sap);
-            return JNI_TRUE;
-        case SCTP_ASSOC_CHANGE:
-            handleAssocChange(env, resultContainerObj, &snp->sn_assoc_change);
-            return JNI_TRUE;
-        case SCTP_SHUTDOWN_EVENT:
-            handleShutdown(env, resultContainerObj, &snp->sn_shutdown_event);
-            return JNI_TRUE;
-        case SCTP_PEER_ADDR_CHANGE:
-            handlePeerAddrChange(env, resultContainerObj, &snp->sn_paddr_change);
-            return JNI_TRUE;
-        default :
-            /* the Java API is not interested in this event, maybe we are? */
-            handleUninteresting(snp);
-    }
-    return JNI_FALSE;
-}
-
-void handleMessage
-  (JNIEnv* env, jobject resultContainerObj, struct msghdr* msg,int read,
-   jboolean isEOR, struct sockaddr* sap) {
-    jobject isa, resultObj;
-    struct controlData cdata[1];
-
-    if (read == 0) {
-        /* we reached EOF */
-        read = -1;
-    }
-
-    isa = SockAddrToInetSocketAddress(env, sap);
-    getControlData(msg, cdata);
-
-    /* create SctpMessageInfoImpl */
-    resultObj = (*env)->NewObject(env, smi_class, smi_ctrID, cdata->assocId,
-                                  isa, read, cdata->streamNumber,
-                                  isEOR ? JNI_TRUE : JNI_FALSE,
-                                  cdata->unordered, cdata->ppid);
-    CHECK_NULL(resultObj);
-    (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
-    (*env)->SetIntField(env, resultContainerObj, src_typeID,
-                        sun_nio_ch_SctpResultContainer_MESSAGE);
-}
-
-/*
- * Class:     sun_nio_ch_SctpChannelImpl
- * Method:    receive0
- * Signature: (ILsun/nio/ch/SctpResultContainer;JIZ)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_receive0
-  (JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj,
-   jlong address, jint length, jboolean peek) {
-    SOCKADDR sa;
-    int sa_len = sizeof(sa);
-    ssize_t rv = 0;
-    jlong *addr = jlong_to_ptr(address);
-    struct iovec iov[1];
-    struct msghdr msg[1];
-    char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
-    int flags = peek == JNI_TRUE ? MSG_PEEK : 0;
-
-    /* Set up the msghdr structure for receiving */
-    memset(msg, 0, sizeof (*msg));
-    msg->msg_name = &sa;
-    msg->msg_namelen = sa_len;
-    iov->iov_base = addr;
-    iov->iov_len = length;
-    msg->msg_iov = iov;
-    msg->msg_iovlen = 1;
-    msg->msg_control = cbuf;
-    msg->msg_controllen = sizeof(cbuf);
-    msg->msg_flags = 0;
-
-    do {
-        if ((rv = recvmsg(fd, msg, flags)) < 0) {
-            if (errno == EWOULDBLOCK) {
-                return IOS_UNAVAILABLE;
-            } else if (errno == EINTR) {
-                return IOS_INTERRUPTED;
-
-#ifdef __linux__
-            } else if (errno == ENOTCONN) {
-                /* ENOTCONN when EOF reached */
-                rv = 0;
-                /* there will be no control data */
-                msg->msg_controllen = 0;
-#endif /* __linux__ */
-
-            } else {
-                handleSocketError(env, errno);
-                return 0;
-            }
-        }
-
-        if (msg->msg_flags & MSG_NOTIFICATION) {
-            char *bufp = (char*)addr;
-            union sctp_notification *snp;
-
-            if (!(msg->msg_flags & MSG_EOR) && length < NOTIFICATION_BUFFER_SIZE) {
-                char buf[NOTIFICATION_BUFFER_SIZE];
-                int rvSAVE = rv;
-                memcpy(buf, addr, rv);
-                iov->iov_base = buf + rv;
-                iov->iov_len = NOTIFICATION_BUFFER_SIZE - rv;
-                if ((rv = recvmsg(fd, msg, flags)) < 0) {
-                    handleSocketError(env, errno);
-                    return 0;
-                }
-                bufp = buf;
-                rv += rvSAVE;
-            }
-            snp = (union sctp_notification *) bufp;
-            if (handleNotification(env, fd, resultContainerObj, snp, rv,
-                                   (msg->msg_flags & MSG_EOR),
-                                   (struct sockaddr*)&sa ) == JNI_TRUE) {
-                /* We have received a notification that is of interest to
-                   to the Java API. The appropriate notification will be
-                   set in the result container. */
-                return 0;
-            }
-
-            // set iov back to addr, and reset msg_controllen
-            iov->iov_base = addr;
-            iov->iov_len = length;
-            msg->msg_control = cbuf;
-            msg->msg_controllen = sizeof(cbuf);
-        }
-    } while (msg->msg_flags & MSG_NOTIFICATION);
-
-    handleMessage(env, resultContainerObj, msg, rv,
-            (msg->msg_flags & MSG_EOR), (struct sockaddr*)&sa);
-    return rv;
-}
-
-/*
- * Class:     sun_nio_ch_SctpChannelImpl
- * Method:    send0
- * Signature: (IJILjava/net/SocketAddress;IIZI)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_send0
-  (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
-   jobject saTarget, jint assocId, jint streamNumber, jboolean unordered,
-   jint ppid) {
-    SOCKADDR sa;
-    int sa_len = sizeof(sa);
-    ssize_t rv = 0;
-    jlong *addr = jlong_to_ptr(address);
-    struct iovec iov[1];
-    struct msghdr msg[1];
-    int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
-    char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
-    struct controlData cdata[1];
-
-    /* SctpChannel:
-     *    saTarget may contain the preferred address or NULL to use primary,
-     *    assocId will always be -1
-     * SctpMultiChannell:
-     *    Setup new association, saTarget will contain address, assocId = -1
-     *    Association already existing, assocId != -1, saTarget = preferred addr
-     */
-    if (saTarget != NULL /*&& assocId <= 0*/) {
-
-        jobject targetAddress = (*env)->GetObjectField(env, saTarget, isa_addrID);
-        jint targetPort = (*env)->GetIntField(env, saTarget, isa_portID);
-
-        if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
-                                      (struct sockaddr *)&sa,
-                                      &sa_len, JNI_TRUE) != 0) {
-            return IOS_THROWN;
-        }
-    } else {
-        memset(&sa, '\x0', sa_len);
-        sa_len = 0;
-    }
-
-    /* Set up the msghdr structure for sending */
-    memset(msg, 0, sizeof (*msg));
-    memset(cbuf, 0, cbuf_size);
-    msg->msg_name = &sa;
-    msg->msg_namelen = sa_len;
-    iov->iov_base = addr;
-    iov->iov_len = length;
-    msg->msg_iov = iov;
-    msg->msg_iovlen = 1;
-    msg->msg_control = cbuf;
-    msg->msg_controllen = cbuf_size;
-    msg->msg_flags = 0;
-
-    cdata->streamNumber = streamNumber;
-    cdata->assocId = assocId;
-    cdata->unordered = unordered;
-    cdata->ppid = ppid;
-    setControlData(msg, cdata);
-
-    if ((rv = sendmsg(fd, msg, 0)) < 0) {
-        if (errno == EWOULDBLOCK) {
-            return IOS_UNAVAILABLE;
-        } else if (errno == EINTR) {
-            return IOS_INTERRUPTED;
-        } else if (errno == EPIPE) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "Socket is shutdown for writing");
-        } else {
-            handleSocketError(env, errno);
-            return 0;
-        }
-    }
-
-    return rv;
-}
-
-/*
- * Class:     sun_nio_ch_SctpChannelImpl
- * Method:    checkConnect
- * Signature: (Ljava/io/FileDescriptor;ZZ)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_checkConnect
-  (JNIEnv* env, jobject this, jobject fdo, jboolean block, jboolean ready) {
-    return Java_sun_nio_ch_SocketChannelImpl_checkConnect(env, this,
-                                                          fdo, block, ready);
-}
-