50
51 struct controlData {
52 int assocId;
53 unsigned short streamNumber;
54 jboolean unordered;
55 unsigned int ppid;
56 };
57
58 static jclass smi_class; /* sun.nio.ch.SctpMessageInfoImpl */
59 static jmethodID smi_ctrID; /* sun.nio.ch.SctpMessageInfoImpl.<init> */
60 static jfieldID src_valueID; /* sun.nio.ch.SctpResultContainer.value */
61 static jfieldID src_typeID; /* sun.nio.ch.SctpResultContainer.type */
62 static jclass ssf_class; /* sun.nio.ch.SctpSendFailed */
63 static jmethodID ssf_ctrID; /* sun.nio.ch.SctpSendFailed.<init> */
64 static jclass sac_class; /* sun.nio.ch.SctpAssociationChanged */
65 static jmethodID sac_ctrID; /* sun.nio.ch.SctpAssociationChanged.<init> */
66 static jclass spc_class; /* sun.nio.ch.SctpPeerAddressChanged */
67 static jmethodID spc_ctrID; /* sun.nio.ch.SctpPeerAddressChanged.<init> */
68 static jclass ss_class; /* sun.nio.ch.SctpShutdown */
69 static jmethodID ss_ctrID; /* sun.nio.ch.SctpShutdown.<init> */
70 static jfieldID isa_addrID; /* java.net.InetSocketAddress.addr */
71 static jfieldID isa_portID; /* java.net.InetSocketAddress.port */
72
73 /* defined in SctpNet.c */
74 jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
75
76 /* use SocketChannelImpl's checkConnect implementation */
77 extern jint Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv* env,
78 jobject this, jobject fdo, jboolean block, jboolean ready);
79
80 /*
81 * Class: sun_nio_ch_SctpChannelImpl
82 * Method: initIDs
83 * Signature: ()V
84 */
85 JNIEXPORT void JNICALL Java_sun_nio_ch_SctpChannelImpl_initIDs
86 (JNIEnv *env, jclass klass) {
87 jclass cls;
88
89 /* SctpMessageInfoImpl */
90 cls = (*env)->FindClass(env, MESSAGE_IMPL_CLASS);
91 CHECK_NULL(cls);
119 CHECK_NULL(sac_class);
120 sac_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(IIII)V");
121 CHECK_NULL(sac_ctrID);
122
123 /* SctpPeerAddrChange */
124 cls = (*env)->FindClass(env, PEER_CHANGE_CLASS);
125 CHECK_NULL(cls);
126 spc_class = (*env)->NewGlobalRef(env, cls);
127 CHECK_NULL(spc_class);
128 spc_ctrID = (*env)->GetMethodID(env, cls, "<init>",
129 "(ILjava/net/SocketAddress;I)V");
130 CHECK_NULL(spc_ctrID);
131
132 /* sun.nio.ch.SctpShutdown */
133 cls = (*env)->FindClass(env, SHUTDOWN_CLASS);
134 CHECK_NULL(cls);
135 ss_class = (*env)->NewGlobalRef(env, cls);
136 CHECK_NULL(ss_class);
137 ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
138 CHECK_NULL(ss_ctrID);
139
140 /* InetSocketAddress */
141 cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
142 CHECK_NULL(cls);
143 isa_addrID = (*env)->GetFieldID(env, cls, "addr", "Ljava/net/InetAddress;");
144 CHECK_NULL(isa_addrID);
145 isa_portID = (*env)->GetFieldID(env, cls, "port", "I");
146 }
147
148 void getControlData
149 (struct msghdr* msg, struct controlData* cdata) {
150 struct cmsghdr* cmsg;
151
152 for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
153 if (cmsg->cmsg_level == IPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCV) {
154 struct sctp_sndrcvinfo *sri;
155
156 sri = (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg);
157 cdata->assocId = sri->sinfo_assoc_id;
158 cdata->streamNumber = sri->sinfo_stream;
159 cdata->unordered = (sri->sinfo_flags & SCTP_UNORDERED) ? JNI_TRUE :
160 JNI_FALSE;
161 cdata->ppid = ntohl(sri->sinfo_ppid);
162
163 return;
164 }
165 }
490 set in the result container. */
491 return 0;
492 }
493
494 // set iov back to addr, and reset msg_controllen
495 iov->iov_base = addr;
496 iov->iov_len = length;
497 msg->msg_control = cbuf;
498 msg->msg_controllen = sizeof(cbuf);
499 }
500 } while (msg->msg_flags & MSG_NOTIFICATION);
501
502 handleMessage(env, resultContainerObj, msg, rv,
503 (msg->msg_flags & MSG_EOR), (struct sockaddr*)&sa);
504 return rv;
505 }
506
507 /*
508 * Class: sun_nio_ch_SctpChannelImpl
509 * Method: send0
510 * Signature: (IJILjava/net/SocketAddress;IIZI)I
511 */
512 JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_send0
513 (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
514 jobject saTarget, jint assocId, jint streamNumber, jboolean unordered,
515 jint ppid) {
516 SOCKADDR sa;
517 int sa_len = sizeof(sa);
518 ssize_t rv = 0;
519 jlong *addr = jlong_to_ptr(address);
520 struct iovec iov[1];
521 struct msghdr msg[1];
522 int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
523 char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
524 struct controlData cdata[1];
525
526 /* SctpChannel:
527 * saTarget may contain the preferred address or NULL to use primary,
528 * assocId will always be -1
529 * SctpMultiChannell:
530 * Setup new association, saTarget will contain address, assocId = -1
531 * Association already existing, assocId != -1, saTarget = preferred addr
532 */
533 if (saTarget != NULL /*&& assocId <= 0*/) {
534
535 jobject targetAddress = (*env)->GetObjectField(env, saTarget, isa_addrID);
536 jint targetPort = (*env)->GetIntField(env, saTarget, isa_portID);
537
538 if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
539 (struct sockaddr *)&sa,
540 &sa_len, JNI_TRUE) != 0) {
541 return IOS_THROWN;
542 }
543 } else {
544 memset(&sa, '\x0', sa_len);
545 sa_len = 0;
546 }
547
548 /* Set up the msghdr structure for sending */
549 memset(msg, 0, sizeof (*msg));
550 memset(cbuf, 0, cbuf_size);
551 msg->msg_name = &sa;
552 msg->msg_namelen = sa_len;
553 iov->iov_base = addr;
554 iov->iov_len = length;
555 msg->msg_iov = iov;
556 msg->msg_iovlen = 1;
557 msg->msg_control = cbuf;
|
50
51 struct controlData {
52 int assocId;
53 unsigned short streamNumber;
54 jboolean unordered;
55 unsigned int ppid;
56 };
57
58 static jclass smi_class; /* sun.nio.ch.SctpMessageInfoImpl */
59 static jmethodID smi_ctrID; /* sun.nio.ch.SctpMessageInfoImpl.<init> */
60 static jfieldID src_valueID; /* sun.nio.ch.SctpResultContainer.value */
61 static jfieldID src_typeID; /* sun.nio.ch.SctpResultContainer.type */
62 static jclass ssf_class; /* sun.nio.ch.SctpSendFailed */
63 static jmethodID ssf_ctrID; /* sun.nio.ch.SctpSendFailed.<init> */
64 static jclass sac_class; /* sun.nio.ch.SctpAssociationChanged */
65 static jmethodID sac_ctrID; /* sun.nio.ch.SctpAssociationChanged.<init> */
66 static jclass spc_class; /* sun.nio.ch.SctpPeerAddressChanged */
67 static jmethodID spc_ctrID; /* sun.nio.ch.SctpPeerAddressChanged.<init> */
68 static jclass ss_class; /* sun.nio.ch.SctpShutdown */
69 static jmethodID ss_ctrID; /* sun.nio.ch.SctpShutdown.<init> */
70
71 /* defined in SctpNet.c */
72 jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
73
74 /* use SocketChannelImpl's checkConnect implementation */
75 extern jint Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv* env,
76 jobject this, jobject fdo, jboolean block, jboolean ready);
77
78 /*
79 * Class: sun_nio_ch_SctpChannelImpl
80 * Method: initIDs
81 * Signature: ()V
82 */
83 JNIEXPORT void JNICALL Java_sun_nio_ch_SctpChannelImpl_initIDs
84 (JNIEnv *env, jclass klass) {
85 jclass cls;
86
87 /* SctpMessageInfoImpl */
88 cls = (*env)->FindClass(env, MESSAGE_IMPL_CLASS);
89 CHECK_NULL(cls);
117 CHECK_NULL(sac_class);
118 sac_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(IIII)V");
119 CHECK_NULL(sac_ctrID);
120
121 /* SctpPeerAddrChange */
122 cls = (*env)->FindClass(env, PEER_CHANGE_CLASS);
123 CHECK_NULL(cls);
124 spc_class = (*env)->NewGlobalRef(env, cls);
125 CHECK_NULL(spc_class);
126 spc_ctrID = (*env)->GetMethodID(env, cls, "<init>",
127 "(ILjava/net/SocketAddress;I)V");
128 CHECK_NULL(spc_ctrID);
129
130 /* sun.nio.ch.SctpShutdown */
131 cls = (*env)->FindClass(env, SHUTDOWN_CLASS);
132 CHECK_NULL(cls);
133 ss_class = (*env)->NewGlobalRef(env, cls);
134 CHECK_NULL(ss_class);
135 ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
136 CHECK_NULL(ss_ctrID);
137 }
138
139 void getControlData
140 (struct msghdr* msg, struct controlData* cdata) {
141 struct cmsghdr* cmsg;
142
143 for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
144 if (cmsg->cmsg_level == IPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCV) {
145 struct sctp_sndrcvinfo *sri;
146
147 sri = (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg);
148 cdata->assocId = sri->sinfo_assoc_id;
149 cdata->streamNumber = sri->sinfo_stream;
150 cdata->unordered = (sri->sinfo_flags & SCTP_UNORDERED) ? JNI_TRUE :
151 JNI_FALSE;
152 cdata->ppid = ntohl(sri->sinfo_ppid);
153
154 return;
155 }
156 }
481 set in the result container. */
482 return 0;
483 }
484
485 // set iov back to addr, and reset msg_controllen
486 iov->iov_base = addr;
487 iov->iov_len = length;
488 msg->msg_control = cbuf;
489 msg->msg_controllen = sizeof(cbuf);
490 }
491 } while (msg->msg_flags & MSG_NOTIFICATION);
492
493 handleMessage(env, resultContainerObj, msg, rv,
494 (msg->msg_flags & MSG_EOR), (struct sockaddr*)&sa);
495 return rv;
496 }
497
498 /*
499 * Class: sun_nio_ch_SctpChannelImpl
500 * Method: send0
501 * Signature: (IJILjava/net/InetAddress;IIIZI)I
502 */
503 JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_send0
504 (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
505 jobject targetAddress, jint targetPort, jint assocId, jint streamNumber,
506 jboolean unordered, jint ppid) {
507 SOCKADDR sa;
508 int sa_len = sizeof(sa);
509 ssize_t rv = 0;
510 jlong *addr = jlong_to_ptr(address);
511 struct iovec iov[1];
512 struct msghdr msg[1];
513 int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
514 char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
515 struct controlData cdata[1];
516
517 /* SctpChannel:
518 * targetAddress may contain the preferred address or NULL to use primary,
519 * assocId will always be -1
520 * SctpMultiChannell:
521 * Setup new association, targetAddress will contain address, assocId = -1
522 * Association already existing, assocId != -1, targetAddress = preferred addr
523 */
524 if (targetAddress != NULL /*&& assocId <= 0*/) {
525 if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
526 (struct sockaddr *)&sa,
527 &sa_len, JNI_TRUE) != 0) {
528 return IOS_THROWN;
529 }
530 } else {
531 memset(&sa, '\x0', sa_len);
532 sa_len = 0;
533 }
534
535 /* Set up the msghdr structure for sending */
536 memset(msg, 0, sizeof (*msg));
537 memset(cbuf, 0, cbuf_size);
538 msg->msg_name = &sa;
539 msg->msg_namelen = sa_len;
540 iov->iov_base = addr;
541 iov->iov_len = length;
542 msg->msg_iov = iov;
543 msg->msg_iovlen = 1;
544 msg->msg_control = cbuf;
|