Bug Summary

File:jdk/src/jdk.sctp/unix/native/libsctp/SctpChannelImpl.c
Warning:line 407, column 17
4th function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SctpChannelImpl.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -I /home/daniel/Projects/java/jdk/src/jdk.sctp/unix/native/libsctp -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/jdk.sctp -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.base -I /home/daniel/Projects/java/jdk/src/java.base/linux/native/libnet -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libnet -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libnet -I /home/daniel/Projects/java/jdk/src/java.base/linux/native/libnio/ch -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libnio/ch -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libnio/ch -D _FORTIFY_SOURCE=2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wno-unused -Wno-undef -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c /home/daniel/Projects/java/jdk/src/jdk.sctp/unix/native/libsctp/SctpChannelImpl.c
1/*
2 * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include <stdlib.h>
27#include <string.h>
28#include "Sctp.h"
29
30#include "jni.h"
31#include "nio_util.h"
32#include "nio.h"
33#include "net_util.h"
34#include "net_util_md.h"
35#include "sun_nio_ch_sctp_SctpNet.h"
36#include "sun_nio_ch_sctp_SctpChannelImpl.h"
37#include "sun_nio_ch_sctp_AssociationChange.h"
38#include "sun_nio_ch_sctp_ResultContainer.h"
39#include "sun_nio_ch_sctp_PeerAddrChange.h"
40
41static int SCTP_NOTIFICATION_SIZE = sizeof(union sctp_notification);
42
43#define MESSAGE_IMPL_CLASS"sun/nio/ch/sctp/MessageInfoImpl" "sun/nio/ch/sctp/MessageInfoImpl"
44#define RESULT_CONTAINER_CLASS"sun/nio/ch/sctp/ResultContainer" "sun/nio/ch/sctp/ResultContainer"
45#define SEND_FAILED_CLASS"sun/nio/ch/sctp/SendFailed" "sun/nio/ch/sctp/SendFailed"
46#define ASSOC_CHANGE_CLASS"sun/nio/ch/sctp/AssociationChange" "sun/nio/ch/sctp/AssociationChange"
47#define PEER_CHANGE_CLASS"sun/nio/ch/sctp/PeerAddrChange" "sun/nio/ch/sctp/PeerAddrChange"
48#define SHUTDOWN_CLASS"sun/nio/ch/sctp/Shutdown" "sun/nio/ch/sctp/Shutdown"
49
50struct controlData {
51 int assocId;
52 unsigned short streamNumber;
53 jboolean unordered;
54 unsigned int ppid;
55};
56
57static jclass smi_class; /* sun.nio.ch.sctp.MessageInfoImpl */
58static jmethodID smi_ctrID; /* sun.nio.ch.sctp.MessageInfoImpl.<init> */
59static jfieldID src_valueID; /* sun.nio.ch.sctp.ResultContainer.value */
60static jfieldID src_typeID; /* sun.nio.ch.sctp.ResultContainer.type */
61static jclass ssf_class; /* sun.nio.ch.sctp.SendFailed */
62static jmethodID ssf_ctrID; /* sun.nio.ch.sctp.SendFailed.<init> */
63static jclass sac_class; /* sun.nio.ch.sctp.AssociationChange */
64static jmethodID sac_ctrID; /* sun.nio.ch.sctp.AssociationChange.<init> */
65static jclass spc_class; /* sun.nio.ch.sctp.PeerAddressChanged */
66static jmethodID spc_ctrID; /* sun.nio.ch.sctp.PeerAddressChanged.<init> */
67static jclass ss_class; /* sun.nio.ch.sctp.Shutdown */
68static jmethodID ss_ctrID; /* sun.nio.ch.sctp.Shutdown.<init> */
69
70/* defined in SctpNet.c */
71jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
72
73jint handleSocketError(JNIEnv *env, jint errorValue);
74
75/*
76 * Class: sun_nio_ch_sctp_SctpChannelImpl
77 * Method: initIDs
78 * Signature: ()V
79 */
80JNIEXPORT__attribute__((visibility("default"))) void JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_initIDs
81 (JNIEnv *env, jclass klass) {
82 jclass cls;
83
84 /* MessageInfoImpl */
85 cls = (*env)->FindClass(env, MESSAGE_IMPL_CLASS"sun/nio/ch/sctp/MessageInfoImpl");
86 CHECK_NULL(cls)do { if ((cls) == ((void*)0)) { return; } } while (0);
87 smi_class = (*env)->NewGlobalRef(env, cls);
88 CHECK_NULL(smi_class)do { if ((smi_class) == ((void*)0)) { return; } } while (0);
89 smi_ctrID = (*env)->GetMethodID(env, cls, "<init>",
90 "(ILjava/net/SocketAddress;IIZZI)V");
91 CHECK_NULL(smi_ctrID)do { if ((smi_ctrID) == ((void*)0)) { return; } } while (0);
92
93 /* ResultContainer */
94 cls = (*env)->FindClass(env, RESULT_CONTAINER_CLASS"sun/nio/ch/sctp/ResultContainer");
95 CHECK_NULL(cls)do { if ((cls) == ((void*)0)) { return; } } while (0);
96 src_valueID = (*env)->GetFieldID(env, cls, "value", "Ljava/lang/Object;");
97 CHECK_NULL(src_valueID)do { if ((src_valueID) == ((void*)0)) { return; } } while (0);
98 src_typeID = (*env)->GetFieldID(env, cls, "type", "I");
99 CHECK_NULL(src_typeID)do { if ((src_typeID) == ((void*)0)) { return; } } while (0);
100
101 /* SendFailed */
102 cls = (*env)->FindClass(env, SEND_FAILED_CLASS"sun/nio/ch/sctp/SendFailed");
103 CHECK_NULL(cls)do { if ((cls) == ((void*)0)) { return; } } while (0);
104 ssf_class = (*env)->NewGlobalRef(env, cls);
105 CHECK_NULL(ssf_class)do { if ((ssf_class) == ((void*)0)) { return; } } while (0);
106 ssf_ctrID = (*env)->GetMethodID(env, cls, "<init>",
107 "(ILjava/net/SocketAddress;Ljava/nio/ByteBuffer;II)V");
108 CHECK_NULL(ssf_ctrID)do { if ((ssf_ctrID) == ((void*)0)) { return; } } while (0);
109
110 /* AssociationChange */
111 cls = (*env)->FindClass(env, ASSOC_CHANGE_CLASS"sun/nio/ch/sctp/AssociationChange");
112 CHECK_NULL(cls)do { if ((cls) == ((void*)0)) { return; } } while (0);
113 sac_class = (*env)->NewGlobalRef(env, cls);
114 CHECK_NULL(sac_class)do { if ((sac_class) == ((void*)0)) { return; } } while (0);
115 sac_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(IIII)V");
116 CHECK_NULL(sac_ctrID)do { if ((sac_ctrID) == ((void*)0)) { return; } } while (0);
117
118 /* PeerAddrChange */
119 cls = (*env)->FindClass(env, PEER_CHANGE_CLASS"sun/nio/ch/sctp/PeerAddrChange");
120 CHECK_NULL(cls)do { if ((cls) == ((void*)0)) { return; } } while (0);
121 spc_class = (*env)->NewGlobalRef(env, cls);
122 CHECK_NULL(spc_class)do { if ((spc_class) == ((void*)0)) { return; } } while (0);
123 spc_ctrID = (*env)->GetMethodID(env, cls, "<init>",
124 "(ILjava/net/SocketAddress;I)V");
125 CHECK_NULL(spc_ctrID)do { if ((spc_ctrID) == ((void*)0)) { return; } } while (0);
126
127 /* Shutdown */
128 cls = (*env)->FindClass(env, SHUTDOWN_CLASS"sun/nio/ch/sctp/Shutdown");
129 CHECK_NULL(cls)do { if ((cls) == ((void*)0)) { return; } } while (0);
130 ss_class = (*env)->NewGlobalRef(env, cls);
131 CHECK_NULL(ss_class)do { if ((ss_class) == ((void*)0)) { return; } } while (0);
132 ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
133 CHECK_NULL(ss_ctrID)do { if ((ss_ctrID) == ((void*)0)) { return; } } while (0);
134}
135
136void getControlData
137 (struct msghdr* msg, struct controlData* cdata) {
138 struct cmsghdr* cmsg;
139
140 for (cmsg = CMSG_FIRSTHDR(msg)((size_t) (msg)->msg_controllen >= sizeof (struct cmsghdr
) ? (struct cmsghdr *) (msg)->msg_control : (struct cmsghdr
*) 0)
; cmsg != NULL((void*)0); cmsg = CMSG_NXTHDR(msg, cmsg)__cmsg_nxthdr (msg, cmsg)) {
15
Assuming the condition is false
16
'?' condition is false
17
Loop condition is false. Execution continues on line 154
141 if (cmsg->cmsg_level == IPPROTO_SCTPIPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCVSCTP_SNDRCV) {
142 struct sctp_sndrcvinfo *sri;
143
144 sri = (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg)((cmsg)->__cmsg_data);
145 cdata->assocId = sri->sinfo_assoc_id;
146 cdata->streamNumber = sri->sinfo_stream;
147 cdata->unordered = (sri->sinfo_flags & SCTP_UNORDERED) ? JNI_TRUE1 :
148 JNI_FALSE0;
149 cdata->ppid = ntohl(sri->sinfo_ppid)(__extension__ ({ unsigned int __v, __x = (sri->sinfo_ppid
); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
150
151 return;
152 }
153 }
154 return;
18
Returning without writing to 'cdata->assocId'
155}
156
157void setControlData
158 (struct msghdr* msg, struct controlData* cdata) {
159 struct cmsghdr* cmsg;
160 struct sctp_sndrcvinfo *sri;
161
162 cmsg = CMSG_FIRSTHDR(msg)((size_t) (msg)->msg_controllen >= sizeof (struct cmsghdr
) ? (struct cmsghdr *) (msg)->msg_control : (struct cmsghdr
*) 0)
;
163 cmsg->cmsg_level = IPPROTO_SCTPIPPROTO_SCTP;
164 cmsg->cmsg_type = SCTP_SNDRCVSCTP_SNDRCV;
165 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo))((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (sizeof(struct sctp_sndrcvinfo)))
;
166
167 /* Initialize the payload */
168 sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg)((cmsg)->__cmsg_data);
169 memset(sri, 0, sizeof (*sri));
170
171 if (cdata->streamNumber > 0) {
172 sri->sinfo_stream = cdata->streamNumber;
173 }
174 if (cdata->assocId > 0) {
175 sri->sinfo_assoc_id = cdata->assocId;
176 }
177 if (cdata->unordered == JNI_TRUE1) {
178 sri->sinfo_flags = sri->sinfo_flags | SCTP_UNORDERED;
179 }
180
181 if (cdata->ppid > 0) {
182 sri->sinfo_ppid = htonl(cdata->ppid)(__extension__ ({ unsigned int __v, __x = (cdata->ppid); if
(__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
183 }
184
185 /* Sum of the length of all control messages in the buffer. */
186 msg->msg_controllen = cmsg->cmsg_len;
187}
188
189// TODO: test: can create send failed without any data? if so need to
190// update API so that buffer can be null if no data.
191void handleSendFailed
192 (JNIEnv* env, int fd, jobject resultContainerObj, struct sctp_send_failed *ssf,
193 int read, jboolean isEOR, struct sockaddr* sap) {
194 jobject bufferObj = NULL((void*)0), resultObj, isaObj;
195 char *addressP;
196 struct sctp_sndrcvinfo *sri;
197 int remaining, dataLength;
198
199 /* the actual undelivered message data is directly after the ssf */
200 int dataOffset = sizeof(struct sctp_send_failed);
201
202 sri = (struct sctp_sndrcvinfo*) &ssf->ssf_info;
203
204 /* the number of bytes remaining to be read in the sctp_send_failed notif*/
205 remaining = ssf->ssf_length - read;
206
207 /* the size of the actual undelivered message */
208 dataLength = ssf->ssf_length - dataOffset;
209
210 /* retrieved address from sockaddr */
211 isaObj = SockAddrToInetSocketAddress(env, sap);
212 CHECK_NULL(isaObj)do { if ((isaObj) == ((void*)0)) { return; } } while (0);
213
214 /* data retrieved from sff_data */
215 if (dataLength > 0) {
216 struct iovec iov[1];
217 struct msghdr msg[1];
218 int rv, alreadyRead;
219 char *dataP = (char*) ssf;
220 dataP += dataOffset;
221
222 if ((addressP = malloc(dataLength)) == NULL((void*)0)) {
223 JNU_ThrowOutOfMemoryError(env, "handleSendFailed");
224 return;
225 }
226
227 memset(msg, 0, sizeof (*msg));
228 msg->msg_iov = iov;
229 msg->msg_iovlen = 1;
230
231 bufferObj = (*env)->NewDirectByteBuffer(env, addressP, dataLength);
232 if (bufferObj == NULL((void*)0)) {
233 free(addressP);
234 return;
235 }
236
237 alreadyRead = read - dataOffset;
238 if (alreadyRead > 0) {
239 memcpy(addressP, /*ssf->ssf_data*/ dataP, alreadyRead);
240 iov->iov_base = addressP + alreadyRead;
241 iov->iov_len = dataLength - alreadyRead;
242 } else {
243 iov->iov_base = addressP;
244 iov->iov_len = dataLength;
245 }
246
247 if (remaining > 0) {
248 if ((rv = recvmsg(fd, msg, 0)) < 0) {
249 free(addressP);
250 handleSocketError(env, errno(*__errno_location ()));
251 return;
252 }
253
254 if (rv != (dataLength - alreadyRead) || !(msg->msg_flags & MSG_EORMSG_EOR)) {
255 //TODO: assert false: "should not reach here";
256 free(addressP);
257 return;
258 }
259 // TODO: Set and document (in API) buffers position.
260 }
261 }
262
263 /* create SendFailed */
264 resultObj = (*env)->NewObject(env, ssf_class, ssf_ctrID, ssf->ssf_assoc_id,
265 isaObj, bufferObj, ssf->ssf_error, sri->sinfo_stream);
266 if (resultObj == NULL((void*)0)) {
267 if (bufferObj != NULL((void*)0)) free(addressP);
268 return;
269 }
270 (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
271 (*env)->SetIntField(env, resultContainerObj, src_typeID,
272 sun_nio_ch_sctp_ResultContainer_SEND_FAILED2L);
273}
274
275void handleAssocChange
276 (JNIEnv* env, jobject resultContainerObj, struct sctp_assoc_change *sac) {
277 jobject resultObj;
278 int state = 0;
279
280 switch (sac->sac_state) {
281 case SCTP_COMM_UP :
282 state = sun_nio_ch_sctp_AssociationChange_SCTP_COMM_UP1L;
283 break;
284 case SCTP_COMM_LOST :
285 state = sun_nio_ch_sctp_AssociationChange_SCTP_COMM_LOST2L;
286 break;
287 case SCTP_RESTART :
288 state = sun_nio_ch_sctp_AssociationChange_SCTP_RESTART3L;
289 break;
290 case SCTP_SHUTDOWN_COMP :
291 state = sun_nio_ch_sctp_AssociationChange_SCTP_SHUTDOWN4L;
292 break;
293 case SCTP_CANT_STR_ASSOC :
294 state = sun_nio_ch_sctp_AssociationChange_SCTP_CANT_START5L;
295 }
296
297 /* create AssociationChange */
298 resultObj = (*env)->NewObject(env, sac_class, sac_ctrID, sac->sac_assoc_id,
299 state, sac->sac_outbound_streams, sac->sac_inbound_streams);
300 CHECK_NULL(resultObj)do { if ((resultObj) == ((void*)0)) { return; } } while (0);
301 (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
302 (*env)->SetIntField(env, resultContainerObj, src_typeID,
303 sun_nio_ch_sctp_ResultContainer_ASSOCIATION_CHANGED3L);
304}
305
306void handleShutdown
307 (JNIEnv* env, jobject resultContainerObj, struct sctp_shutdown_event* sse) {
308 /* create Shutdown */
309 jobject resultObj = (*env)->NewObject(env, ss_class, ss_ctrID, sse->sse_assoc_id);
310 CHECK_NULL(resultObj)do { if ((resultObj) == ((void*)0)) { return; } } while (0);
311 (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
312 (*env)->SetIntField(env, resultContainerObj, src_typeID,
313 sun_nio_ch_sctp_ResultContainer_SHUTDOWN5L);
314}
315
316void handlePeerAddrChange
317 (JNIEnv* env, jobject resultContainerObj, struct sctp_paddr_change* spc) {
318 int event = 0;
319 jobject addressObj, resultObj;
320 unsigned int state = spc->spc_state;
321
322 switch (state) {
323 case SCTP_ADDR_AVAILABLE :
324 event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_AVAILABLE1L;
325 break;
326 case SCTP_ADDR_UNREACHABLE :
327 event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_UNREACHABLE2L;
328 break;
329 case SCTP_ADDR_REMOVED :
330 event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_REMOVED3L;
331 break;
332 case SCTP_ADDR_ADDED :
333 event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_ADDED4L;
334 break;
335 case SCTP_ADDR_MADE_PRIM :
336 event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_MADE_PRIM5L;
337 break;
338#ifdef __linux__1
339 case SCTP_ADDR_CONFIRMED :
340 event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_CONFIRMED6L;
341 break;
342#endif /* __linux__ */
343 }
344
345 addressObj = SockAddrToInetSocketAddress(env, (struct sockaddr*)&spc->spc_aaddr);
346 CHECK_NULL(addressObj)do { if ((addressObj) == ((void*)0)) { return; } } while (0);
347
348 /* create PeerAddressChanged */
349 resultObj = (*env)->NewObject(env, spc_class, spc_ctrID, spc->spc_assoc_id,
350 addressObj, event);
351 CHECK_NULL(resultObj)do { if ((resultObj) == ((void*)0)) { return; } } while (0);
352 (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
353 (*env)->SetIntField(env, resultContainerObj, src_typeID,
354 sun_nio_ch_sctp_ResultContainer_PEER_ADDRESS_CHANGED4L);
355}
356
357void handleUninteresting
358 (union sctp_notification *snp) {
359 //fprintf(stdout,"\nNative: handleUninterestingNotification: Receive notification type [%u]", snp->sn_header.sn_type);
360}
361
362/**
363 * Handle notifications from the SCTP stack.
364 * Returns JNI_TRUE if the notification is one that is of interest to the
365 * Java API, otherwise JNI_FALSE.
366 */
367jboolean handleNotification
368 (JNIEnv* env, int fd, jobject resultContainerObj, union sctp_notification* snp,
369 int read, jboolean isEOR, struct sockaddr* sap) {
370 switch (snp->sn_header.sn_type) {
371 case SCTP_SEND_FAILED:
372 handleSendFailed(env, fd, resultContainerObj, &snp->sn_send_failed,
373 read, isEOR, sap);
374 return JNI_TRUE1;
375 case SCTP_ASSOC_CHANGE:
376 handleAssocChange(env, resultContainerObj, &snp->sn_assoc_change);
377 return JNI_TRUE1;
378 case SCTP_SHUTDOWN_EVENT:
379 handleShutdown(env, resultContainerObj, &snp->sn_shutdown_event);
380 return JNI_TRUE1;
381 case SCTP_PEER_ADDR_CHANGE:
382 handlePeerAddrChange(env, resultContainerObj, &snp->sn_paddr_change);
383 return JNI_TRUE1;
384 default :
385 /* the Java API is not interested in this event, maybe we are? */
386 handleUninteresting(snp);
387 }
388 return JNI_FALSE0;
389}
390
391void handleMessage
392 (JNIEnv* env, jobject resultContainerObj, struct msghdr* msg,int read,
393 jboolean isEOR, struct sockaddr* sap) {
394 jobject isa, resultObj;
395 struct controlData cdata[1];
396
397 if (read == 0) {
9
Assuming 'read' is not equal to 0
10
Taking false branch
398 /* we reached EOF */
399 read = -1;
400 }
401
402 isa = SockAddrToInetSocketAddress(env, sap);
403 CHECK_NULL(isa)do { if ((isa) == ((void*)0)) { return; } } while (0);
11
Assuming 'isa' is not equal to null
12
Taking false branch
13
Loop condition is false. Exiting loop
404 getControlData(msg, cdata);
14
Calling 'getControlData'
19
Returning from 'getControlData'
405
406 /* create MessageInfoImpl */
407 resultObj = (*env)->NewObject(env, smi_class, smi_ctrID, cdata->assocId,
22
4th function call argument is an uninitialized value
408 isa, read, cdata->streamNumber,
409 isEOR ? JNI_TRUE1 : JNI_FALSE0,
20
Assuming 'isEOR' is 0
21
'?' condition is false
410 cdata->unordered, cdata->ppid);
411 CHECK_NULL(resultObj)do { if ((resultObj) == ((void*)0)) { return; } } while (0);
412 (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
413 (*env)->SetIntField(env, resultContainerObj, src_typeID,
414 sun_nio_ch_sctp_ResultContainer_MESSAGE1L);
415}
416
417/*
418 * Class: sun_nio_ch_sctp_SctpChannelImpl
419 * Method: receive0
420 * Signature: (ILsun/nio/ch/sctp/ResultContainer;JIZ)I
421 */
422JNIEXPORT__attribute__((visibility("default"))) jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_receive0
423 (JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj,
424 jlong address, jint length, jboolean peek) {
425 SOCKETADDRESS sa;
426 ssize_t rv = 0;
427 jlong *addr = jlong_to_ptr(address)((void*)(address));
428 struct iovec iov[1];
429 struct msghdr msg[1];
430 char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))((((sizeof (struct sctp_sndrcvinfo)) + sizeof (size_t) - 1) &
(size_t) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr
)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1
)))
];
431 int flags = peek == JNI_TRUE1 ? MSG_PEEKMSG_PEEK : 0;
1
Assuming 'peek' is not equal to JNI_TRUE
2
'?' condition is false
432
433 /* Set up the msghdr structure for receiving */
434 memset(msg, 0, sizeof (*msg));
435 msg->msg_name = &sa;
436 msg->msg_namelen = sizeof(sa);
437 iov->iov_base = addr;
438 iov->iov_len = length;
439 msg->msg_iov = iov;
440 msg->msg_iovlen = 1;
441 msg->msg_control = cbuf;
442 msg->msg_controllen = sizeof(cbuf);
443 msg->msg_flags = 0;
444
445 do {
7
Loop condition is false. Exiting loop
446 if ((rv = recvmsg(fd, msg, flags)) < 0) {
3
Assuming the condition is false
4
Taking false branch
447 if (errno(*__errno_location ()) == EAGAIN11 || errno(*__errno_location ()) == EWOULDBLOCK11) {
448 return IOS_UNAVAILABLE(-2L);
449 } else if (errno(*__errno_location ()) == EINTR4) {
450 return IOS_INTERRUPTED(-3L);
451
452#ifdef __linux__1
453 } else if (errno(*__errno_location ()) == ENOTCONN107) {
454 /* ENOTCONN when EOF reached */
455 rv = 0;
456 /* there will be no control data */
457 msg->msg_controllen = 0;
458#endif /* __linux__ */
459
460 } else {
461 handleSocketError(env, errno(*__errno_location ()));
462 return 0;
463 }
464 }
465
466 if (msg->msg_flags & MSG_NOTIFICATIONMSG_NOTIFICATION) {
5
Assuming the condition is false
6
Taking false branch
467 char *bufp = (char*)addr;
468 union sctp_notification *snp;
469 jboolean allocated = JNI_FALSE0;
470
471 if (!(msg->msg_flags & MSG_EORMSG_EOR) && length < SCTP_NOTIFICATION_SIZE) {
472 char* newBuf;
473 int rvSAVE = rv;
474
475 if ((newBuf = malloc(SCTP_NOTIFICATION_SIZE)) == NULL((void*)0)) {
476 JNU_ThrowOutOfMemoryError(env, "Out of native heap space.");
477 return -1;
478 }
479 allocated = JNI_TRUE1;
480
481 memcpy(newBuf, addr, rv);
482 iov->iov_base = newBuf + rv;
483 iov->iov_len = SCTP_NOTIFICATION_SIZE - rv;
484 if ((rv = recvmsg(fd, msg, flags)) < 0) {
485 handleSocketError(env, errno(*__errno_location ()));
486 free(newBuf);
487 return 0;
488 }
489 bufp = newBuf;
490 rv += rvSAVE;
491 }
492 snp = (union sctp_notification *) bufp;
493 if (handleNotification(env, fd, resultContainerObj, snp, rv,
494 (msg->msg_flags & MSG_EORMSG_EOR),
495 &sa.sa) == JNI_TRUE1) {
496 /* We have received a notification that is of interest
497 to the Java API. The appropriate notification will be
498 set in the result container. */
499 if (allocated == JNI_TRUE1) {
500 free(bufp);
501 }
502 return 0;
503 }
504
505 if (allocated == JNI_TRUE1) {
506 free(bufp);
507 }
508
509 // set iov back to addr, and reset msg_controllen
510 iov->iov_base = addr;
511 iov->iov_len = length;
512 msg->msg_control = cbuf;
513 msg->msg_controllen = sizeof(cbuf);
514 }
515 } while (msg->msg_flags & MSG_NOTIFICATIONMSG_NOTIFICATION);
516
517 handleMessage(env, resultContainerObj, msg, rv,
8
Calling 'handleMessage'
518 (msg->msg_flags & MSG_EORMSG_EOR), &sa.sa);
519 return rv;
520}
521
522/*
523 * Class: sun_nio_ch_sctp_SctpChannelImpl
524 * Method: send0
525 * Signature: (IJILjava/net/InetAddress;IIIZI)I
526 */
527JNIEXPORT__attribute__((visibility("default"))) jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0
528 (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
529 jobject targetAddress, jint targetPort, jint assocId, jint streamNumber,
530 jboolean unordered, jint ppid) {
531 SOCKETADDRESS sa;
532 int sa_len = 0;
533 ssize_t rv = 0;
534 jlong *addr = jlong_to_ptr(address)((void*)(address));
535 struct iovec iov[1];
536 struct msghdr msg[1];
537 int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))((((sizeof (struct sctp_sndrcvinfo)) + sizeof (size_t) - 1) &
(size_t) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr
)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1
)))
;
538 char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))((((sizeof (struct sctp_sndrcvinfo)) + sizeof (size_t) - 1) &
(size_t) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr
)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1
)))
];
539 struct controlData cdata[1];
540
541 /* SctpChannel:
542 * targetAddress may contain the preferred address or NULL to use primary,
543 * assocId will always be -1
544 * SctpMultiChannell:
545 * Setup new association, targetAddress will contain address, assocId = -1
546 * Association already existing, assocId != -1, targetAddress = preferred addr
547 */
548 if (targetAddress != NULL((void*)0) /*&& assocId <= 0*/) {
549 if (NET_InetAddressToSockaddr(env, targetAddress, targetPort, &sa,
550 &sa_len, JNI_TRUE1) != 0) {
551 return IOS_THROWN(-5L);
552 }
553 } else {
554 memset(&sa, '\x0', sizeof(sa));
555 }
556
557 /* Set up the msghdr structure for sending */
558 memset(msg, 0, sizeof (*msg));
559 memset(cbuf, 0, cbuf_size);
560 msg->msg_name = &sa;
561 msg->msg_namelen = sa_len;
562 iov->iov_base = addr;
563 iov->iov_len = length;
564 msg->msg_iov = iov;
565 msg->msg_iovlen = 1;
566 msg->msg_control = cbuf;
567 msg->msg_controllen = cbuf_size;
568 msg->msg_flags = 0;
569
570 cdata->streamNumber = streamNumber;
571 cdata->assocId = assocId;
572 cdata->unordered = unordered;
573 cdata->ppid = ppid;
574 setControlData(msg, cdata);
575
576 if ((rv = sendmsg(fd, msg, 0)) < 0) {
577 if (errno(*__errno_location ()) == EAGAIN11 || errno(*__errno_location ()) == EWOULDBLOCK11) {
578 return IOS_UNAVAILABLE(-2L);
579 } else if (errno(*__errno_location ()) == EINTR4) {
580 return IOS_INTERRUPTED(-3L);
581 } else if (errno(*__errno_location ()) == EPIPE32) {
582 JNU_ThrowByName(env, JNU_JAVANETPKG"java/net/" "SocketException",
583 "Socket is shutdown for writing");
584 } else {
585 handleSocketError(env, errno(*__errno_location ()));
586 return 0;
587 }
588 }
589
590 return rv;
591}
592