1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 #include <sys/types.h>
27 #include <sys/t_lock.h>
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/buf.h>
31 #include <sys/vfs.h>
32 #include <sys/vnode.h>
33 #include <sys/fcntl.h>
34 #include <sys/debug.h>
35 #include <sys/errno.h>
36 #include <sys/stropts.h>
37 #include <sys/cmn_err.h>
38 #include <sys/sysmacros.h>
39 #include <sys/filio.h>
40 #include <sys/policy.h>
41
42 #include <sys/project.h>
43 #include <sys/tihdr.h>
44 #include <sys/strsubr.h>
45 #include <sys/esunddi.h>
46 #include <sys/ddi.h>
47
48 #include <sys/sockio.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/strsun.h>
52
53 #include <netinet/sctp.h>
54 #include <inet/sctp_itf.h>
55 #include <fs/sockfs/sockcommon.h>
56 #include "socksctp.h"
57
58 /*
59 * SCTP sockfs sonode operations, 1-1 socket
60 */
61 static int sosctp_init(struct sonode *, struct sonode *, struct cred *, int);
62 static int sosctp_accept(struct sonode *, int, struct cred *, struct sonode **);
63 static int sosctp_bind(struct sonode *, struct sockaddr *, socklen_t, int,
64 struct cred *);
65 static int sosctp_listen(struct sonode *, int, struct cred *);
66 static int sosctp_connect(struct sonode *, struct sockaddr *, socklen_t,
67 int, int, struct cred *);
68 static int sosctp_recvmsg(struct sonode *, struct nmsghdr *, struct uio *,
69 struct cred *);
70 static int sosctp_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
71 struct cred *);
72 static int sosctp_getpeername(struct sonode *, struct sockaddr *, socklen_t *,
73 boolean_t, struct cred *);
74 static int sosctp_getsockname(struct sonode *, struct sockaddr *, socklen_t *,
75 struct cred *);
76 static int sosctp_shutdown(struct sonode *, int, struct cred *);
77 static int sosctp_getsockopt(struct sonode *, int, int, void *, socklen_t *,
78 int, struct cred *);
79 static int sosctp_setsockopt(struct sonode *, int, int, const void *,
80 socklen_t, struct cred *);
81 static int sosctp_ioctl(struct sonode *, int, intptr_t, int, struct cred *,
82 int32_t *);
83 static int sosctp_close(struct sonode *, int, struct cred *);
84 void sosctp_fini(struct sonode *, struct cred *);
85
86 /*
87 * SCTP sockfs sonode operations, 1-N socket
88 */
89 static int sosctp_seq_connect(struct sonode *, struct sockaddr *,
90 socklen_t, int, int, struct cred *);
91 static int sosctp_seq_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
92 struct cred *);
93
94 /*
95 * Socket association upcalls, 1-N socket connection
96 */
97 sock_upper_handle_t sctp_assoc_newconn(sock_upper_handle_t,
98 sock_lower_handle_t, sock_downcalls_t *, struct cred *, pid_t,
99 sock_upcalls_t **);
100 static void sctp_assoc_connected(sock_upper_handle_t, sock_connid_t,
101 struct cred *, pid_t);
102 static int sctp_assoc_disconnected(sock_upper_handle_t, sock_connid_t, int);
103 static void sctp_assoc_disconnecting(sock_upper_handle_t, sock_opctl_action_t,
104 uintptr_t arg);
105 static ssize_t sctp_assoc_recv(sock_upper_handle_t, mblk_t *, size_t, int,
106 int *, boolean_t *);
107 static void sctp_assoc_xmitted(sock_upper_handle_t, boolean_t);
108 static void sctp_assoc_properties(sock_upper_handle_t,
109 struct sock_proto_props *);
110 static mblk_t *sctp_get_sock_pid_mblk(sock_upper_handle_t);
111
112 sonodeops_t sosctp_sonodeops = {
113 sosctp_init, /* sop_init */
114 sosctp_accept, /* sop_accept */
115 sosctp_bind, /* sop_bind */
116 sosctp_listen, /* sop_listen */
117 sosctp_connect, /* sop_connect */
118 sosctp_recvmsg, /* sop_recvmsg */
119 sosctp_sendmsg, /* sop_sendmsg */
120 so_sendmblk_notsupp, /* sop_sendmblk */
121 sosctp_getpeername, /* sop_getpeername */
122 sosctp_getsockname, /* sop_getsockname */
123 sosctp_shutdown, /* sop_shutdown */
124 sosctp_getsockopt, /* sop_getsockopt */
125 sosctp_setsockopt, /* sop_setsockopt */
126 sosctp_ioctl, /* sop_ioctl */
127 so_poll, /* sop_poll */
128 sosctp_close, /* sop_close */
129 };
130
131 sonodeops_t sosctp_seq_sonodeops = {
132 sosctp_init, /* sop_init */
133 so_accept_notsupp, /* sop_accept */
134 sosctp_bind, /* sop_bind */
135 sosctp_listen, /* sop_listen */
136 sosctp_seq_connect, /* sop_connect */
137 sosctp_recvmsg, /* sop_recvmsg */
138 sosctp_seq_sendmsg, /* sop_sendmsg */
139 so_sendmblk_notsupp, /* sop_sendmblk */
140 so_getpeername_notsupp, /* sop_getpeername */
141 sosctp_getsockname, /* sop_getsockname */
142 so_shutdown_notsupp, /* sop_shutdown */
143 sosctp_getsockopt, /* sop_getsockopt */
144 sosctp_setsockopt, /* sop_setsockopt */
145 sosctp_ioctl, /* sop_ioctl */
146 so_poll, /* sop_poll */
147 sosctp_close, /* sop_close */
148 };
149
150 /* All the upcalls expect the upper handle to be sonode. */
151 sock_upcalls_t sosctp_sock_upcalls = {
152 so_newconn,
153 so_connected,
154 so_disconnected,
155 so_opctl,
156 so_queue_msg,
157 so_set_prop,
158 so_txq_full,
159 NULL, /* su_signal_oob */
160 };
161
162 /* All the upcalls expect the upper handle to be sctp_sonode/sctp_soassoc. */
163 sock_upcalls_t sosctp_assoc_upcalls = {
164 sctp_assoc_newconn,
165 sctp_assoc_connected,
166 sctp_assoc_disconnected,
167 sctp_assoc_disconnecting,
168 sctp_assoc_recv,
169 sctp_assoc_properties,
170 sctp_assoc_xmitted,
171 NULL, /* su_recv_space */
172 NULL, /* su_signal_oob */
173 NULL, /* su_set_error */
174 NULL, /* su_closed */
175 sctp_get_sock_pid_mblk
176 };
177
178 /* ARGSUSED */
179 static int
180 sosctp_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
181 {
182 struct sctp_sonode *ss;
183 struct sctp_sonode *pss;
184 sctp_sockbuf_limits_t sbl;
185 int err;
186
187 ss = SOTOSSO(so);
188
189 if (pso != NULL) {
190 /*
191 * Passive open, just inherit settings from parent. We should
192 * not end up here for SOCK_SEQPACKET type sockets, since no
193 * new sonode is created in that case.
194 */
195 ASSERT(so->so_type == SOCK_STREAM);
196 pss = SOTOSSO(pso);
197
198 mutex_enter(&pso->so_lock);
199 so->so_state |= (SS_ISBOUND | SS_ISCONNECTED |
200 (pso->so_state & SS_ASYNC));
201 sosctp_so_inherit(pss, ss);
202 so->so_proto_props = pso->so_proto_props;
203 so->so_mode = pso->so_mode;
204 mutex_exit(&pso->so_lock);
205
206 return (0);
207 }
208
209 if ((err = secpolicy_basic_net_access(cr)) != 0)
210 return (err);
211
212 if (so->so_type == SOCK_STREAM) {
213 so->so_proto_handle = (sock_lower_handle_t)sctp_create(so,
214 NULL, so->so_family, so->so_type, SCTP_CAN_BLOCK,
215 &sosctp_sock_upcalls, &sbl, cr);
216 so->so_mode = SM_CONNREQUIRED;
217 } else {
218 ASSERT(so->so_type == SOCK_SEQPACKET);
219 so->so_proto_handle = (sock_lower_handle_t)sctp_create(ss,
220 NULL, so->so_family, so->so_type, SCTP_CAN_BLOCK,
221 &sosctp_assoc_upcalls, &sbl, cr);
222 }
223
224 if (so->so_proto_handle == NULL)
225 return (ENOMEM);
226
227 so->so_rcvbuf = sbl.sbl_rxbuf;
228 so->so_rcvlowat = sbl.sbl_rxlowat;
229 so->so_sndbuf = sbl.sbl_txbuf;
230 so->so_sndlowat = sbl.sbl_txlowat;
231
232 return (0);
233 }
234
235 /*
236 * Accept incoming connection.
237 */
238 /*ARGSUSED*/
239 static int
240 sosctp_accept(struct sonode *so, int fflag, struct cred *cr,
241 struct sonode **nsop)
242 {
243 int error = 0;
244
245 if ((so->so_state & SS_ACCEPTCONN) == 0)
246 return (EINVAL);
247
248 error = so_acceptq_dequeue(so, (fflag & (FNONBLOCK|FNDELAY)), nsop);
249
250 return (error);
251 }
252
253 /*
254 * Bind local endpoint.
255 */
256 /*ARGSUSED*/
257 static int
258 sosctp_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen,
259 int flags, struct cred *cr)
260 {
261 int error;
262
263 if (!(flags & _SOBIND_LOCK_HELD)) {
264 mutex_enter(&so->so_lock);
265 so_lock_single(so); /* Set SOLOCKED */
266 } else {
267 ASSERT(MUTEX_HELD(&so->so_lock));
268 }
269
270 /*
271 * X/Open requires this check
272 */
273 if (so->so_state & SS_CANTSENDMORE) {
274 error = EINVAL;
275 goto done;
276 }
277
278
279 /*
280 * Protocol module does address family checks.
281 */
282 mutex_exit(&so->so_lock);
283
284 error = sctp_bind((struct sctp_s *)so->so_proto_handle, name, namelen);
285
286 mutex_enter(&so->so_lock);
287 if (error == 0) {
288 so->so_state |= SS_ISBOUND;
289 } else {
290 eprintsoline(so, error);
291 }
292 done:
293 if (!(flags & _SOBIND_LOCK_HELD)) {
294 so_unlock_single(so, SOLOCKED);
295 mutex_exit(&so->so_lock);
296 } else {
297 /* If the caller held the lock don't release it here */
298 ASSERT(MUTEX_HELD(&so->so_lock));
299 ASSERT(so->so_flag & SOLOCKED);
300 }
301
302 return (error);
303 }
304
305 /*
306 * Turn socket into a listen socket.
307 */
308 /* ARGSUSED */
309 static int
310 sosctp_listen(struct sonode *so, int backlog, struct cred *cr)
311 {
312 int error = 0;
313
314 mutex_enter(&so->so_lock);
315 so_lock_single(so);
316
317 /*
318 * If this socket is trying to do connect, or if it has
319 * been connected, disallow.
320 */
321 if (so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED |
322 SS_ISDISCONNECTING | SS_CANTRCVMORE | SS_CANTSENDMORE)) {
323 error = EINVAL;
324 eprintsoline(so, error);
325 goto done;
326 }
327
328 if (backlog < 0) {
329 backlog = 0;
330 }
331
332 /*
333 * If listen() is only called to change backlog, we don't
334 * need to notify protocol module.
335 */
336 if (so->so_state & SS_ACCEPTCONN) {
337 so->so_backlog = backlog;
338 goto done;
339 }
340
341 mutex_exit(&so->so_lock);
342 error = sctp_listen((struct sctp_s *)so->so_proto_handle);
343 mutex_enter(&so->so_lock);
344 if (error == 0) {
345 so->so_state |= (SS_ACCEPTCONN|SS_ISBOUND);
346 so->so_backlog = backlog;
347 } else {
348 eprintsoline(so, error);
349 }
350 done:
351 so_unlock_single(so, SOLOCKED);
352 mutex_exit(&so->so_lock);
353
354 return (error);
355 }
356
357 /*
358 * Active open.
359 */
360 /*ARGSUSED*/
361 static int
362 sosctp_connect(struct sonode *so, struct sockaddr *name,
363 socklen_t namelen, int fflag, int flags, struct cred *cr)
364 {
365 int error = 0;
366 pid_t pid = curproc->p_pid;
367
368 ASSERT(so->so_type == SOCK_STREAM);
369
370 mutex_enter(&so->so_lock);
371 so_lock_single(so);
372
373 /*
374 * Can't connect() after listen(), or if the socket is already
375 * connected.
376 */
377 if (so->so_state & (SS_ACCEPTCONN|SS_ISCONNECTED|SS_ISCONNECTING)) {
378 if (so->so_state & SS_ISCONNECTED) {
379 error = EISCONN;
380 } else if (so->so_state & SS_ISCONNECTING) {
381 error = EALREADY;
382 } else {
383 error = EOPNOTSUPP;
384 }
385 eprintsoline(so, error);
386 goto done;
387 }
388
389 /*
390 * Check for failure of an earlier call
391 */
392 if (so->so_error != 0) {
393 error = sogeterr(so, B_TRUE);
394 eprintsoline(so, error);
395 goto done;
396 }
397
398 /*
399 * Connection is closing, or closed, don't allow reconnect.
400 * TCP allows this to proceed, but the socket remains unwriteable.
401 * BSD returns EINVAL.
402 */
403 if (so->so_state & (SS_ISDISCONNECTING|SS_CANTRCVMORE|
404 SS_CANTSENDMORE)) {
405 error = EINVAL;
406 eprintsoline(so, error);
407 goto done;
408 }
409
410 if (name == NULL || namelen == 0) {
411 mutex_exit(&so->so_lock);
412 error = EINVAL;
413 eprintsoline(so, error);
414 goto done;
415 }
416
417 soisconnecting(so);
418 mutex_exit(&so->so_lock);
419
420 error = sctp_connect((struct sctp_s *)so->so_proto_handle,
421 name, namelen, cr, pid);
422
423 mutex_enter(&so->so_lock);
424 if (error == 0) {
425 /*
426 * Allow other threads to access the socket
427 */
428 error = sowaitconnected(so, fflag, 0);
429 }
430 done:
431 so_unlock_single(so, SOLOCKED);
432 mutex_exit(&so->so_lock);
433 return (error);
434 }
435
436 /*
437 * Active open for 1-N sockets, create a new association and
438 * call connect on that.
439 * If there parent hasn't been bound yet (this is the first association),
440 * make it so.
441 */
442 static int
443 sosctp_seq_connect(struct sonode *so, struct sockaddr *name,
444 socklen_t namelen, int fflag, int flags, struct cred *cr)
445 {
446 struct sctp_soassoc *ssa;
447 struct sctp_sonode *ss;
448 int error;
449
450 ASSERT(so->so_type == SOCK_SEQPACKET);
451
452 mutex_enter(&so->so_lock);
453 so_lock_single(so);
454
455 if (name == NULL || namelen == 0) {
456 error = EINVAL;
457 eprintsoline(so, error);
458 goto done;
459 }
460
461 ss = SOTOSSO(so);
462
463 error = sosctp_assoc_createconn(ss, name, namelen, NULL, 0, fflag,
464 cr, &ssa);
465 if (error != 0) {
466 if ((error == EHOSTUNREACH) && (flags & _SOCONNECT_XPG4_2)) {
467 error = ENETUNREACH;
468 }
469 }
470 if (ssa != NULL) {
471 SSA_REFRELE(ss, ssa);
472 }
473
474 done:
475 so_unlock_single(so, SOLOCKED);
476 mutex_exit(&so->so_lock);
477 return (error);
478 }
479
480 /*
481 * Receive data.
482 */
483 /* ARGSUSED */
484 static int
485 sosctp_recvmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
486 struct cred *cr)
487 {
488 struct sctp_sonode *ss = SOTOSSO(so);
489 struct sctp_soassoc *ssa = NULL;
490 int flags, error = 0;
491 struct T_unitdata_ind *tind;
492 ssize_t orig_resid = uiop->uio_resid;
493 int len, count, readcnt = 0;
494 socklen_t controllen, namelen;
495 void *opt;
496 mblk_t *mp;
497 rval_t rval;
498
499 controllen = msg->msg_controllen;
500 namelen = msg->msg_namelen;
501 flags = msg->msg_flags;
502 msg->msg_flags = 0;
503 msg->msg_controllen = 0;
504 msg->msg_namelen = 0;
505
506 if (so->so_type == SOCK_STREAM) {
507 if (!(so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING|
508 SS_CANTRCVMORE))) {
509 return (ENOTCONN);
510 }
511 } else {
512 /* NOTE: Will come here from vop_read() as well */
513 /* For 1-N socket, recv() cannot be used. */
514 if (namelen == 0)
515 return (EOPNOTSUPP);
516 /*
517 * If there are no associations, and no new connections are
518 * coming in, there's not going to be new messages coming
519 * in either.
520 */
521 if (so->so_rcv_q_head == NULL && so->so_rcv_head == NULL &&
522 ss->ss_assoccnt == 0 && !(so->so_state & SS_ACCEPTCONN)) {
523 return (ENOTCONN);
524 }
525 }
526
527 /*
528 * out-of-band data not supported.
529 */
530 if (flags & MSG_OOB) {
531 return (EOPNOTSUPP);
532 }
533
534 /*
535 * flag possibilities:
536 *
537 * MSG_PEEK Don't consume data
538 * MSG_WAITALL Wait for full quantity of data (ignored if MSG_PEEK)
539 * MSG_DONTWAIT Non-blocking (same as FNDELAY | FNONBLOCK)
540 *
541 * MSG_WAITALL can return less than the full buffer if either
542 *
543 * 1. we would block and we are non-blocking
544 * 2. a full message cannot be delivered
545 *
546 * Given that we always get a full message from proto below,
547 * MSG_WAITALL is not meaningful.
548 */
549
550 mutex_enter(&so->so_lock);
551
552 /*
553 * Allow just one reader at a time.
554 */
555 error = so_lock_read_intr(so,
556 uiop->uio_fmode | ((flags & MSG_DONTWAIT) ? FNONBLOCK : 0));
557 if (error) {
558 mutex_exit(&so->so_lock);
559 return (error);
560 }
561 mutex_exit(&so->so_lock);
562 again:
563 error = so_dequeue_msg(so, &mp, uiop, &rval, flags | MSG_DUPCTRL);
564 if (mp != NULL) {
565 if (so->so_type == SOCK_SEQPACKET) {
566 ssa = *(struct sctp_soassoc **)DB_BASE(mp);
567 }
568
569 tind = (struct T_unitdata_ind *)mp->b_rptr;
570
571 len = tind->SRC_length;
572
573 if (namelen > 0 && len > 0) {
574
575 opt = sogetoff(mp, tind->SRC_offset, len, 1);
576
577 ASSERT(opt != NULL);
578
579 msg->msg_name = kmem_alloc(len, KM_SLEEP);
580 msg->msg_namelen = len;
581
582 bcopy(opt, msg->msg_name, len);
583 }
584
585 len = tind->OPT_length;
586 if (controllen == 0) {
587 if (len > 0) {
588 msg->msg_flags |= MSG_CTRUNC;
589 }
590 } else if (len > 0) {
591 opt = sogetoff(mp, tind->OPT_offset, len,
592 __TPI_ALIGN_SIZE);
593
594 ASSERT(opt != NULL);
595 sosctp_pack_cmsg(opt, msg, len);
596 }
597
598 if (mp->b_flag & SCTP_NOTIFICATION) {
599 msg->msg_flags |= MSG_NOTIFICATION;
600 }
601
602 if (!(mp->b_flag & SCTP_PARTIAL_DATA) &&
603 !(rval.r_val1 & MOREDATA)) {
604 msg->msg_flags |= MSG_EOR;
605 }
606 freemsg(mp);
607 }
608 done:
609 if (!(flags & MSG_PEEK))
610 readcnt = orig_resid - uiop->uio_resid;
611 /*
612 * Determine if we need to update SCTP about the buffer
613 * space. For performance reason, we cannot update SCTP
614 * every time a message is read. The socket buffer low
615 * watermark is used as the threshold.
616 */
617 if (ssa == NULL) {
618 mutex_enter(&so->so_lock);
619 count = so->so_rcvbuf - so->so_rcv_queued;
620
621 ASSERT(so->so_rcv_q_head != NULL ||
622 so->so_rcv_head != NULL ||
623 so->so_rcv_queued == 0);
624
625 so_unlock_read(so);
626
627 /*
628 * so_dequeue_msg() sets r_val2 to true if flow control was
629 * cleared and we need to update SCTP. so_flowctrld was
630 * cleared in so_dequeue_msg() via so_check_flow_control().
631 */
632 if (rval.r_val2) {
633 mutex_exit(&so->so_lock);
634 sctp_recvd((struct sctp_s *)so->so_proto_handle, count);
635 } else {
636 mutex_exit(&so->so_lock);
637 }
638 } else {
639 /*
640 * Each association keeps track of how much data it has
641 * queued; we need to update the value here. Note that this
642 * is slightly different from SOCK_STREAM type sockets, which
643 * does not need to update the byte count, as it is already
644 * done in so_dequeue_msg().
645 */
646 mutex_enter(&so->so_lock);
647 ssa->ssa_rcv_queued -= readcnt;
648 count = so->so_rcvbuf - ssa->ssa_rcv_queued;
649
650 so_unlock_read(so);
651
652 if (readcnt > 0 && ssa->ssa_flowctrld &&
653 ssa->ssa_rcv_queued < so->so_rcvlowat) {
654 /*
655 * Need to clear ssa_flowctrld, different from 1-1
656 * style.
657 */
658 ssa->ssa_flowctrld = B_FALSE;
659 mutex_exit(&so->so_lock);
660 sctp_recvd(ssa->ssa_conn, count);
661 mutex_enter(&so->so_lock);
662 }
663
664 /*
665 * MOREDATA flag is set if all data could not be copied
666 */
667 if (!(flags & MSG_PEEK) && !(rval.r_val1 & MOREDATA)) {
668 SSA_REFRELE(ss, ssa);
669 }
670 mutex_exit(&so->so_lock);
671 }
672
673 return (error);
674 }
675
676 int
677 sosctp_uiomove(mblk_t *hdr_mp, ssize_t count, ssize_t blk_size, int wroff,
678 struct uio *uiop, int flags)
679 {
680 ssize_t size;
681 int error;
682 mblk_t *mp;
683 dblk_t *dp;
684
685 if (blk_size == INFPSZ)
686 blk_size = count;
687
688 /*
689 * Loop until we have all data copied into mblk's.
690 */
691 while (count > 0) {
692 size = MIN(count, blk_size);
693
694 /*
695 * As a message can be splitted up and sent in different
696 * packets, each mblk will have the extra space before
697 * data to accommodate what SCTP wants to put in there.
698 */
699 while ((mp = allocb(size + wroff, BPRI_MED)) == NULL) {
700 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
701 (flags & MSG_DONTWAIT)) {
702 return (EAGAIN);
703 }
704 if ((error = strwaitbuf(size + wroff, BPRI_MED))) {
705 return (error);
706 }
707 }
708
709 dp = mp->b_datap;
710 dp->db_cpid = curproc->p_pid;
711 ASSERT(wroff <= dp->db_lim - mp->b_wptr);
712 mp->b_rptr += wroff;
713 error = uiomove(mp->b_rptr, size, UIO_WRITE, uiop);
714 if (error != 0) {
715 freeb(mp);
716 return (error);
717 }
718 mp->b_wptr = mp->b_rptr + size;
719 count -= size;
720 hdr_mp->b_cont = mp;
721 hdr_mp = mp;
722 }
723 return (0);
724 }
725
726 /*
727 * Send message.
728 */
729 static int
730 sosctp_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
731 struct cred *cr)
732 {
733 mblk_t *mctl;
734 struct cmsghdr *cmsg;
735 struct sctp_sndrcvinfo *sinfo;
736 int optlen, flags, fflag;
737 ssize_t count, msglen;
738 int error;
739
740 ASSERT(so->so_type == SOCK_STREAM);
741
742 flags = msg->msg_flags;
743 if (flags & MSG_OOB) {
744 /*
745 * No out-of-band data support.
746 */
747 return (EOPNOTSUPP);
748 }
749
750 if (msg->msg_controllen != 0) {
751 optlen = msg->msg_controllen;
752 cmsg = sosctp_find_cmsg(msg->msg_control, optlen, SCTP_SNDRCV);
753 if (cmsg != NULL) {
754 if (cmsg->cmsg_len <
755 (sizeof (*sinfo) + sizeof (*cmsg))) {
756 eprintsoline(so, EINVAL);
757 return (EINVAL);
758 }
759 sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1);
760
761 /* Both flags should not be set together. */
762 if ((sinfo->sinfo_flags & MSG_EOF) &&
763 (sinfo->sinfo_flags & MSG_ABORT)) {
764 eprintsoline(so, EINVAL);
765 return (EINVAL);
766 }
767
768 /* Initiate a graceful shutdown. */
769 if (sinfo->sinfo_flags & MSG_EOF) {
770 /* Can't include data in MSG_EOF message. */
771 if (uiop->uio_resid != 0) {
772 eprintsoline(so, EINVAL);
773 return (EINVAL);
774 }
775
776 /*
777 * This is the same sequence as done in
778 * shutdown(SHUT_WR).
779 */
780 mutex_enter(&so->so_lock);
781 so_lock_single(so);
782 socantsendmore(so);
783 cv_broadcast(&so->so_snd_cv);
784 so->so_state |= SS_ISDISCONNECTING;
785 mutex_exit(&so->so_lock);
786
787 pollwakeup(&so->so_poll_list, POLLOUT);
788 sctp_recvd((struct sctp_s *)so->so_proto_handle,
789 so->so_rcvbuf);
790 error = sctp_disconnect(
791 (struct sctp_s *)so->so_proto_handle);
792
793 mutex_enter(&so->so_lock);
794 so_unlock_single(so, SOLOCKED);
795 mutex_exit(&so->so_lock);
796 return (error);
797 }
798 }
799 } else {
800 optlen = 0;
801 }
802
803 mutex_enter(&so->so_lock);
804 for (;;) {
805 if (so->so_state & SS_CANTSENDMORE) {
806 mutex_exit(&so->so_lock);
807 return (EPIPE);
808 }
809
810 if (so->so_error != 0) {
811 error = sogeterr(so, B_TRUE);
812 mutex_exit(&so->so_lock);
813 return (error);
814 }
815
816 if (!so->so_snd_qfull)
817 break;
818
819 if (so->so_state & SS_CLOSING) {
820 mutex_exit(&so->so_lock);
821 return (EINTR);
822 }
823 /*
824 * Xmit window full in a blocking socket.
825 */
826 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
827 (flags & MSG_DONTWAIT)) {
828 mutex_exit(&so->so_lock);
829 return (EAGAIN);
830 } else {
831 /*
832 * Wait for space to become available and try again.
833 */
834 error = cv_wait_sig(&so->so_snd_cv, &so->so_lock);
835 if (!error) { /* signal */
836 mutex_exit(&so->so_lock);
837 return (EINTR);
838 }
839 }
840 }
841 msglen = count = uiop->uio_resid;
842
843 /* Don't allow sending a message larger than the send buffer size. */
844 /* XXX Transport module need to enforce this */
845 if (msglen > so->so_sndbuf) {
846 mutex_exit(&so->so_lock);
847 return (EMSGSIZE);
848 }
849
850 /*
851 * Allow piggybacking data on handshake messages (SS_ISCONNECTING).
852 */
853 if (!(so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED))) {
854 /*
855 * We need to check here for listener so that the
856 * same error will be returned as with a TCP socket.
857 * In this case, sosctp_connect() returns EOPNOTSUPP
858 * while a TCP socket returns ENOTCONN instead. Catch it
859 * here to have the same behavior as a TCP socket.
860 *
861 * We also need to make sure that the peer address is
862 * provided before we attempt to do the connect.
863 */
864 if ((so->so_state & SS_ACCEPTCONN) ||
865 msg->msg_name == NULL) {
866 mutex_exit(&so->so_lock);
867 error = ENOTCONN;
868 goto error_nofree;
869 }
870 mutex_exit(&so->so_lock);
871 fflag = uiop->uio_fmode;
872 if (flags & MSG_DONTWAIT) {
873 fflag |= FNDELAY;
874 }
875 error = sosctp_connect(so, msg->msg_name, msg->msg_namelen,
876 fflag, (so->so_version == SOV_XPG4_2) * _SOCONNECT_XPG4_2,
877 cr);
878 if (error) {
879 /*
880 * Check for non-fatal errors, socket connected
881 * while the lock had been lifted.
882 */
883 if (error != EISCONN && error != EALREADY) {
884 goto error_nofree;
885 }
886 error = 0;
887 }
888 } else {
889 mutex_exit(&so->so_lock);
890 }
891
892 mctl = sctp_alloc_hdr(msg->msg_name, msg->msg_namelen,
893 msg->msg_control, optlen, SCTP_CAN_BLOCK);
894 if (mctl == NULL) {
895 error = EINTR;
896 goto error_nofree;
897 }
898
899 /* Copy in the message. */
900 if ((error = sosctp_uiomove(mctl, count, so->so_proto_props.sopp_maxblk,
901 so->so_proto_props.sopp_wroff, uiop, flags)) != 0) {
902 goto error_ret;
903 }
904 error = sctp_sendmsg((struct sctp_s *)so->so_proto_handle, mctl, 0);
905 if (error == 0)
906 return (0);
907
908 error_ret:
909 freemsg(mctl);
910 error_nofree:
911 mutex_enter(&so->so_lock);
912 if ((error == EPIPE) && (so->so_state & SS_CANTSENDMORE)) {
913 /*
914 * We received shutdown between the time lock was
915 * lifted and call to sctp_sendmsg().
916 */
917 mutex_exit(&so->so_lock);
918 return (EPIPE);
919 }
920 mutex_exit(&so->so_lock);
921 return (error);
922 }
923
924 /*
925 * Send message on 1-N socket. Connects automatically if there is
926 * no association.
927 */
928 static int
929 sosctp_seq_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
930 struct cred *cr)
931 {
932 struct sctp_sonode *ss;
933 struct sctp_soassoc *ssa;
934 struct cmsghdr *cmsg;
935 struct sctp_sndrcvinfo *sinfo;
936 int aid = 0;
937 mblk_t *mctl;
938 int namelen, optlen, flags;
939 ssize_t count, msglen;
940 int error;
941 uint16_t s_flags = 0;
942
943 ASSERT(so->so_type == SOCK_SEQPACKET);
944
945 /*
946 * There shouldn't be problems with alignment, as the memory for
947 * msg_control was alloced with kmem_alloc.
948 */
949 cmsg = sosctp_find_cmsg(msg->msg_control, msg->msg_controllen,
950 SCTP_SNDRCV);
951 if (cmsg != NULL) {
952 if (cmsg->cmsg_len < (sizeof (*sinfo) + sizeof (*cmsg))) {
953 eprintsoline(so, EINVAL);
954 return (EINVAL);
955 }
956 sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1);
957 s_flags = sinfo->sinfo_flags;
958 aid = sinfo->sinfo_assoc_id;
959 }
960
961 ss = SOTOSSO(so);
962 namelen = msg->msg_namelen;
963
964 if (msg->msg_controllen > 0) {
965 optlen = msg->msg_controllen;
966 } else {
967 optlen = 0;
968 }
969
970 mutex_enter(&so->so_lock);
971
972 /*
973 * If there is no association id, connect to address specified
974 * in msg_name. Otherwise look up the association using the id.
975 */
976 if (aid == 0) {
977 /*
978 * Connect and shutdown cannot be done together, so check for
979 * MSG_EOF.
980 */
981 if (msg->msg_name == NULL || namelen == 0 ||
982 (s_flags & MSG_EOF)) {
983 error = EINVAL;
984 eprintsoline(so, error);
985 goto done;
986 }
987 flags = uiop->uio_fmode;
988 if (msg->msg_flags & MSG_DONTWAIT) {
989 flags |= FNDELAY;
990 }
991 so_lock_single(so);
992 error = sosctp_assoc_createconn(ss, msg->msg_name, namelen,
993 msg->msg_control, optlen, flags, cr, &ssa);
994 if (error) {
995 if ((so->so_version == SOV_XPG4_2) &&
996 (error == EHOSTUNREACH)) {
997 error = ENETUNREACH;
998 }
999 if (ssa == NULL) {
1000 /*
1001 * Fatal error during connect(). Bail out.
1002 * If ssa exists, it means that the handshake
1003 * is in progress.
1004 */
1005 eprintsoline(so, error);
1006 so_unlock_single(so, SOLOCKED);
1007 goto done;
1008 }
1009 /*
1010 * All the errors are non-fatal ones, don't return
1011 * e.g. EINPROGRESS from sendmsg().
1012 */
1013 error = 0;
1014 }
1015 so_unlock_single(so, SOLOCKED);
1016 } else {
1017 if ((error = sosctp_assoc(ss, aid, &ssa)) != 0) {
1018 eprintsoline(so, error);
1019 goto done;
1020 }
1021 }
1022
1023 /*
1024 * Now we have an association.
1025 */
1026 flags = msg->msg_flags;
1027
1028 /*
1029 * MSG_EOF initiates graceful shutdown.
1030 */
1031 if (s_flags & MSG_EOF) {
1032 if (uiop->uio_resid) {
1033 /*
1034 * Can't include data in MSG_EOF message.
1035 */
1036 error = EINVAL;
1037 } else {
1038 mutex_exit(&so->so_lock);
1039 ssa->ssa_state |= SS_ISDISCONNECTING;
1040 sctp_recvd(ssa->ssa_conn, so->so_rcvbuf);
1041 error = sctp_disconnect(ssa->ssa_conn);
1042 mutex_enter(&so->so_lock);
1043 }
1044 goto refrele;
1045 }
1046
1047 for (;;) {
1048 if (ssa->ssa_state & SS_CANTSENDMORE) {
1049 SSA_REFRELE(ss, ssa);
1050 mutex_exit(&so->so_lock);
1051 return (EPIPE);
1052 }
1053 if (ssa->ssa_error != 0) {
1054 error = ssa->ssa_error;
1055 ssa->ssa_error = 0;
1056 goto refrele;
1057 }
1058
1059 if (!ssa->ssa_snd_qfull)
1060 break;
1061
1062 if (so->so_state & SS_CLOSING) {
1063 error = EINTR;
1064 goto refrele;
1065 }
1066 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
1067 (flags & MSG_DONTWAIT)) {
1068 error = EAGAIN;
1069 goto refrele;
1070 } else {
1071 /*
1072 * Wait for space to become available and try again.
1073 */
1074 error = cv_wait_sig(&so->so_snd_cv, &so->so_lock);
1075 if (!error) { /* signal */
1076 error = EINTR;
1077 goto refrele;
1078 }
1079 }
1080 }
1081
1082 msglen = count = uiop->uio_resid;
1083
1084 /* Don't allow sending a message larger than the send buffer size. */
1085 if (msglen > so->so_sndbuf) {
1086 error = EMSGSIZE;
1087 goto refrele;
1088 }
1089
1090 /*
1091 * Update TX buffer usage here so that we can lift the socket lock.
1092 */
1093 mutex_exit(&so->so_lock);
1094
1095 mctl = sctp_alloc_hdr(msg->msg_name, namelen, msg->msg_control,
1096 optlen, SCTP_CAN_BLOCK);
1097 if (mctl == NULL) {
1098 error = EINTR;
1099 goto lock_rele;
1100 }
1101
1102 /* Copy in the message. */
1103 if ((error = sosctp_uiomove(mctl, count, ssa->ssa_wrsize,
1104 ssa->ssa_wroff, uiop, flags)) != 0) {
1105 goto lock_rele;
1106 }
1107 error = sctp_sendmsg((struct sctp_s *)ssa->ssa_conn, mctl, 0);
1108 lock_rele:
1109 mutex_enter(&so->so_lock);
1110 if (error != 0) {
1111 freemsg(mctl);
1112 if ((error == EPIPE) && (ssa->ssa_state & SS_CANTSENDMORE)) {
1113 /*
1114 * We received shutdown between the time lock was
1115 * lifted and call to sctp_sendmsg().
1116 */
1117 SSA_REFRELE(ss, ssa);
1118 mutex_exit(&so->so_lock);
1119 return (EPIPE);
1120 }
1121 }
1122
1123 refrele:
1124 SSA_REFRELE(ss, ssa);
1125 done:
1126 mutex_exit(&so->so_lock);
1127 return (error);
1128 }
1129
1130 /*
1131 * Get address of remote node.
1132 */
1133 /* ARGSUSED */
1134 static int
1135 sosctp_getpeername(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen,
1136 boolean_t accept, struct cred *cr)
1137 {
1138 return (sctp_getpeername((struct sctp_s *)so->so_proto_handle, addr,
1139 addrlen));
1140 }
1141
1142 /*
1143 * Get local address.
1144 */
1145 /* ARGSUSED */
1146 static int
1147 sosctp_getsockname(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen,
1148 struct cred *cr)
1149 {
1150 return (sctp_getsockname((struct sctp_s *)so->so_proto_handle, addr,
1151 addrlen));
1152 }
1153
1154 /*
1155 * Called from shutdown().
1156 */
1157 /* ARGSUSED */
1158 static int
1159 sosctp_shutdown(struct sonode *so, int how, struct cred *cr)
1160 {
1161 uint_t state_change;
1162 int wakesig = 0;
1163 int error = 0;
1164
1165 mutex_enter(&so->so_lock);
1166 /*
1167 * Record the current state and then perform any state changes.
1168 * Then use the difference between the old and new states to
1169 * determine which needs to be done.
1170 */
1171 state_change = so->so_state;
1172
1173 switch (how) {
1174 case SHUT_RD:
1175 socantrcvmore(so);
1176 break;
1177 case SHUT_WR:
1178 socantsendmore(so);
1179 break;
1180 case SHUT_RDWR:
1181 socantsendmore(so);
1182 socantrcvmore(so);
1183 break;
1184 default:
1185 mutex_exit(&so->so_lock);
1186 return (EINVAL);
1187 }
1188
1189 state_change = so->so_state & ~state_change;
1190
1191 if (state_change & SS_CANTRCVMORE) {
1192 if (so->so_rcv_q_head == NULL) {
1193 cv_signal(&so->so_rcv_cv);
1194 }
1195 wakesig = POLLIN|POLLRDNORM;
1196
1197 socket_sendsig(so, SOCKETSIG_READ);
1198 }
1199 if (state_change & SS_CANTSENDMORE) {
1200 cv_broadcast(&so->so_snd_cv);
1201 wakesig |= POLLOUT;
1202
1203 so->so_state |= SS_ISDISCONNECTING;
1204 }
1205 mutex_exit(&so->so_lock);
1206
1207 pollwakeup(&so->so_poll_list, wakesig);
1208
1209 if (state_change & SS_CANTSENDMORE) {
1210 sctp_recvd((struct sctp_s *)so->so_proto_handle, so->so_rcvbuf);
1211 error = sctp_disconnect((struct sctp_s *)so->so_proto_handle);
1212 }
1213
1214 /*
1215 * HACK: sctp_disconnect() may return EWOULDBLOCK. But this error is
1216 * not documented in standard socket API. Catch it here.
1217 */
1218 if (error == EWOULDBLOCK)
1219 error = 0;
1220 return (error);
1221 }
1222
1223 /*
1224 * Get socket options.
1225 */
1226 /*ARGSUSED5*/
1227 static int
1228 sosctp_getsockopt(struct sonode *so, int level, int option_name,
1229 void *optval, socklen_t *optlenp, int flags, struct cred *cr)
1230 {
1231 socklen_t maxlen = *optlenp;
1232 socklen_t len;
1233 socklen_t optlen;
1234 uint8_t buffer[4];
1235 void *optbuf = &buffer;
1236 int error = 0;
1237
1238 if (level == SOL_SOCKET) {
1239 switch (option_name) {
1240 /* Not supported options */
1241 case SO_SNDTIMEO:
1242 case SO_RCVTIMEO:
1243 case SO_EXCLBIND:
1244 eprintsoline(so, ENOPROTOOPT);
1245 return (ENOPROTOOPT);
1246 default:
1247 error = socket_getopt_common(so, level, option_name,
1248 optval, optlenp, flags);
1249 if (error >= 0)
1250 return (error);
1251 /* Pass the request to the protocol */
1252 break;
1253 }
1254 }
1255
1256 if (level == IPPROTO_SCTP) {
1257 /*
1258 * Should go through ioctl().
1259 */
1260 return (EINVAL);
1261 }
1262
1263 if (maxlen > sizeof (buffer)) {
1264 optbuf = kmem_alloc(maxlen, KM_SLEEP);
1265 }
1266 optlen = maxlen;
1267
1268 /*
1269 * If the resulting optlen is greater than the provided maxlen, then
1270 * we sliently trucate.
1271 */
1272 error = sctp_get_opt((struct sctp_s *)so->so_proto_handle, level,
1273 option_name, optbuf, &optlen);
1274
1275 if (error != 0) {
1276 eprintsoline(so, error);
1277 goto free;
1278 }
1279 len = optlen;
1280
1281 copyout:
1282
1283 len = MIN(len, maxlen);
1284 bcopy(optbuf, optval, len);
1285 *optlenp = optlen;
1286 free:
1287 if (optbuf != &buffer) {
1288 kmem_free(optbuf, maxlen);
1289 }
1290
1291 return (error);
1292 }
1293
1294 /*
1295 * Set socket options
1296 */
1297 /* ARGSUSED */
1298 static int
1299 sosctp_setsockopt(struct sonode *so, int level, int option_name,
1300 const void *optval, t_uscalar_t optlen, struct cred *cr)
1301 {
1302 struct sctp_sonode *ss = SOTOSSO(so);
1303 struct sctp_soassoc *ssa = NULL;
1304 sctp_assoc_t id;
1305 int error, rc;
1306 void *conn = NULL;
1307
1308 mutex_enter(&so->so_lock);
1309
1310 /*
1311 * For some SCTP level options, one can select the association this
1312 * applies to.
1313 */
1314 if (so->so_type == SOCK_STREAM) {
1315 conn = so->so_proto_handle;
1316 } else {
1317 /*
1318 * SOCK_SEQPACKET only
1319 */
1320 id = 0;
1321 if (level == IPPROTO_SCTP) {
1322 switch (option_name) {
1323 case SCTP_RTOINFO:
1324 case SCTP_ASSOCINFO:
1325 case SCTP_SET_PEER_PRIMARY_ADDR:
1326 case SCTP_PRIMARY_ADDR:
1327 case SCTP_PEER_ADDR_PARAMS:
1328 /*
1329 * Association ID is the first element
1330 * params struct
1331 */
1332 if (optlen < sizeof (sctp_assoc_t)) {
1333 error = EINVAL;
1334 eprintsoline(so, error);
1335 goto done;
1336 }
1337 id = *(sctp_assoc_t *)optval;
1338 break;
1339 case SCTP_DEFAULT_SEND_PARAM:
1340 if (optlen != sizeof (struct sctp_sndrcvinfo)) {
1341 error = EINVAL;
1342 eprintsoline(so, error);
1343 goto done;
1344 }
1345 id = ((struct sctp_sndrcvinfo *)
1346 optval)->sinfo_assoc_id;
1347 break;
1348 case SCTP_INITMSG:
1349 /*
1350 * Only applies to future associations
1351 */
1352 conn = so->so_proto_handle;
1353 break;
1354 default:
1355 break;
1356 }
1357 } else if (level == SOL_SOCKET) {
1358 if (option_name == SO_LINGER) {
1359 error = EOPNOTSUPP;
1360 eprintsoline(so, error);
1361 goto done;
1362 }
1363 /*
1364 * These 2 options are applied to all associations.
1365 * The other socket level options are only applied
1366 * to the socket (not associations).
1367 */
1368 if ((option_name != SO_RCVBUF) &&
1369 (option_name != SO_SNDBUF)) {
1370 conn = so->so_proto_handle;
1371 }
1372 } else {
1373 conn = NULL;
1374 }
1375
1376 /*
1377 * If association ID was specified, do op on that assoc.
1378 * Otherwise set the default setting of a socket.
1379 */
1380 if (id != 0) {
1381 if ((error = sosctp_assoc(ss, id, &ssa)) != 0) {
1382 eprintsoline(so, error);
1383 goto done;
1384 }
1385 conn = ssa->ssa_conn;
1386 }
1387 }
1388 dprint(2, ("sosctp_setsockopt %p (%d) - conn %p %d %d id:%d\n",
1389 (void *)ss, so->so_type, (void *)conn, level, option_name, id));
1390
1391 ASSERT(ssa == NULL || (ssa != NULL && conn != NULL));
1392 if (conn != NULL) {
1393 mutex_exit(&so->so_lock);
1394 error = sctp_set_opt((struct sctp_s *)conn, level, option_name,
1395 optval, optlen);
1396 mutex_enter(&so->so_lock);
1397 if (ssa != NULL)
1398 SSA_REFRELE(ss, ssa);
1399 } else {
1400 /*
1401 * 1-N socket, and we have to apply the operation to ALL
1402 * associations. Like with anything of this sort, the
1403 * problem is what to do if the operation fails.
1404 * Just try to apply the setting to everyone, but store
1405 * error number if someone returns such. And since we are
1406 * looping through all possible aids, some of them can be
1407 * invalid. We just ignore this kind (sosctp_assoc()) of
1408 * errors.
1409 */
1410 sctp_assoc_t aid;
1411
1412 mutex_exit(&so->so_lock);
1413 error = sctp_set_opt((struct sctp_s *)so->so_proto_handle,
1414 level, option_name, optval, optlen);
1415 mutex_enter(&so->so_lock);
1416 for (aid = 1; aid < ss->ss_maxassoc; aid++) {
1417 if (sosctp_assoc(ss, aid, &ssa) != 0)
1418 continue;
1419 mutex_exit(&so->so_lock);
1420 rc = sctp_set_opt((struct sctp_s *)ssa->ssa_conn, level,
1421 option_name, optval, optlen);
1422 mutex_enter(&so->so_lock);
1423 SSA_REFRELE(ss, ssa);
1424 if (error == 0) {
1425 error = rc;
1426 }
1427 }
1428 }
1429 done:
1430 mutex_exit(&so->so_lock);
1431 return (error);
1432 }
1433
1434 /*ARGSUSED*/
1435 static int
1436 sosctp_ioctl(struct sonode *so, int cmd, intptr_t arg, int mode,
1437 struct cred *cr, int32_t *rvalp)
1438 {
1439 struct sctp_sonode *ss;
1440 int32_t value;
1441 int error;
1442 int intval;
1443 pid_t pid;
1444 struct sctp_soassoc *ssa;
1445 void *conn;
1446 void *buf;
1447 STRUCT_DECL(sctpopt, opt);
1448 uint32_t optlen;
1449 int buflen;
1450
1451 ss = SOTOSSO(so);
1452
1453 /* handle socket specific ioctls */
1454 switch (cmd) {
1455 case FIONBIO:
1456 if (so_copyin((void *)arg, &value, sizeof (int32_t),
1457 (mode & (int)FKIOCTL))) {
1458 return (EFAULT);
1459 }
1460 mutex_enter(&so->so_lock);
1461 if (value) {
1462 so->so_state |= SS_NDELAY;
1463 } else {
1464 so->so_state &= ~SS_NDELAY;
1465 }
1466 mutex_exit(&so->so_lock);
1467 return (0);
1468
1469 case FIOASYNC:
1470 if (so_copyin((void *)arg, &value, sizeof (int32_t),
1471 (mode & (int)FKIOCTL))) {
1472 return (EFAULT);
1473 }
1474 mutex_enter(&so->so_lock);
1475
1476 if (value) {
1477 /* Turn on SIGIO */
1478 so->so_state |= SS_ASYNC;
1479 } else {
1480 /* Turn off SIGIO */
1481 so->so_state &= ~SS_ASYNC;
1482 }
1483 mutex_exit(&so->so_lock);
1484 return (0);
1485
1486 case SIOCSPGRP:
1487 case FIOSETOWN:
1488 if (so_copyin((void *)arg, &pid, sizeof (pid_t),
1489 (mode & (int)FKIOCTL))) {
1490 return (EFAULT);
1491 }
1492 mutex_enter(&so->so_lock);
1493
1494 error = (pid != so->so_pgrp) ? socket_chgpgrp(so, pid) : 0;
1495 mutex_exit(&so->so_lock);
1496 return (error);
1497
1498 case SIOCGPGRP:
1499 case FIOGETOWN:
1500 if (so_copyout(&so->so_pgrp, (void *)arg,
1501 sizeof (pid_t), (mode & (int)FKIOCTL)))
1502 return (EFAULT);
1503 return (0);
1504
1505 case FIONREAD:
1506 /* XXX: Cannot be used unless standard buffer is used */
1507 /*
1508 * Return number of bytes of data in all data messages
1509 * in queue in "arg".
1510 * For stream socket, amount of available data.
1511 * For sock_dgram, # of available bytes + addresses.
1512 */
1513 intval = (so->so_state & SS_ACCEPTCONN) ? 0 :
1514 MIN(so->so_rcv_queued, INT_MAX);
1515 if (so_copyout(&intval, (void *)arg, sizeof (intval),
1516 (mode & (int)FKIOCTL)))
1517 return (EFAULT);
1518 return (0);
1519 case SIOCATMARK:
1520 /*
1521 * No support for urgent data.
1522 */
1523 intval = 0;
1524
1525 if (so_copyout(&intval, (void *)arg, sizeof (int),
1526 (mode & (int)FKIOCTL)))
1527 return (EFAULT);
1528 return (0);
1529 case _I_GETPEERCRED: {
1530 int error = 0;
1531
1532 if ((mode & FKIOCTL) == 0)
1533 return (EINVAL);
1534
1535 mutex_enter(&so->so_lock);
1536 if ((so->so_mode & SM_CONNREQUIRED) == 0) {
1537 error = ENOTSUP;
1538 } else if ((so->so_state & SS_ISCONNECTED) == 0) {
1539 error = ENOTCONN;
1540 } else if (so->so_peercred != NULL) {
1541 k_peercred_t *kp = (k_peercred_t *)arg;
1542 kp->pc_cr = so->so_peercred;
1543 kp->pc_cpid = so->so_cpid;
1544 crhold(so->so_peercred);
1545 } else {
1546 error = EINVAL;
1547 }
1548 mutex_exit(&so->so_lock);
1549 return (error);
1550 }
1551 case SIOCSCTPGOPT:
1552 STRUCT_INIT(opt, mode);
1553
1554 if (so_copyin((void *)arg, STRUCT_BUF(opt), STRUCT_SIZE(opt),
1555 (mode & (int)FKIOCTL))) {
1556 return (EFAULT);
1557 }
1558 if ((optlen = STRUCT_FGET(opt, sopt_len)) > SO_MAXARGSIZE)
1559 return (EINVAL);
1560
1561 /*
1562 * Find the correct sctp_t based on whether it is 1-N socket
1563 * or not.
1564 */
1565 intval = STRUCT_FGET(opt, sopt_aid);
1566 mutex_enter(&so->so_lock);
1567 if ((so->so_type == SOCK_SEQPACKET) && intval) {
1568 if ((error = sosctp_assoc(ss, intval, &ssa)) != 0) {
1569 mutex_exit(&so->so_lock);
1570 return (error);
1571 }
1572 conn = ssa->ssa_conn;
1573 ASSERT(conn != NULL);
1574 } else {
1575 conn = so->so_proto_handle;
1576 ssa = NULL;
1577 }
1578 mutex_exit(&so->so_lock);
1579
1580 /* Copyin the option buffer and then call sctp_get_opt(). */
1581 buflen = optlen;
1582 /* Let's allocate a buffer enough to hold an int */
1583 if (buflen < sizeof (uint32_t))
1584 buflen = sizeof (uint32_t);
1585 buf = kmem_alloc(buflen, KM_SLEEP);
1586 if (so_copyin(STRUCT_FGETP(opt, sopt_val), buf, optlen,
1587 (mode & (int)FKIOCTL))) {
1588 if (ssa != NULL) {
1589 mutex_enter(&so->so_lock);
1590 SSA_REFRELE(ss, ssa);
1591 mutex_exit(&so->so_lock);
1592 }
1593 kmem_free(buf, buflen);
1594 return (EFAULT);
1595 }
1596 /* The option level has to be IPPROTO_SCTP */
1597 error = sctp_get_opt((struct sctp_s *)conn, IPPROTO_SCTP,
1598 STRUCT_FGET(opt, sopt_name), buf, &optlen);
1599 if (ssa != NULL) {
1600 mutex_enter(&so->so_lock);
1601 SSA_REFRELE(ss, ssa);
1602 mutex_exit(&so->so_lock);
1603 }
1604 optlen = MIN(buflen, optlen);
1605 /* No error, copyout the result with the correct buf len. */
1606 if (error == 0) {
1607 STRUCT_FSET(opt, sopt_len, optlen);
1608 if (so_copyout(STRUCT_BUF(opt), (void *)arg,
1609 STRUCT_SIZE(opt), (mode & (int)FKIOCTL))) {
1610 error = EFAULT;
1611 } else if (so_copyout(buf, STRUCT_FGETP(opt, sopt_val),
1612 optlen, (mode & (int)FKIOCTL))) {
1613 error = EFAULT;
1614 }
1615 }
1616 kmem_free(buf, buflen);
1617 return (error);
1618
1619 case SIOCSCTPSOPT:
1620 STRUCT_INIT(opt, mode);
1621
1622 if (so_copyin((void *)arg, STRUCT_BUF(opt), STRUCT_SIZE(opt),
1623 (mode & (int)FKIOCTL))) {
1624 return (EFAULT);
1625 }
1626 if ((optlen = STRUCT_FGET(opt, sopt_len)) > SO_MAXARGSIZE)
1627 return (EINVAL);
1628
1629 /*
1630 * Find the correct sctp_t based on whether it is 1-N socket
1631 * or not.
1632 */
1633 intval = STRUCT_FGET(opt, sopt_aid);
1634 mutex_enter(&so->so_lock);
1635 if (intval != 0) {
1636 if ((error = sosctp_assoc(ss, intval, &ssa)) != 0) {
1637 mutex_exit(&so->so_lock);
1638 return (error);
1639 }
1640 conn = ssa->ssa_conn;
1641 ASSERT(conn != NULL);
1642 } else {
1643 conn = so->so_proto_handle;
1644 ssa = NULL;
1645 }
1646 mutex_exit(&so->so_lock);
1647
1648 /* Copyin the option buffer and then call sctp_set_opt(). */
1649 buf = kmem_alloc(optlen, KM_SLEEP);
1650 if (so_copyin(STRUCT_FGETP(opt, sopt_val), buf, optlen,
1651 (mode & (int)FKIOCTL))) {
1652 if (ssa != NULL) {
1653 mutex_enter(&so->so_lock);
1654 SSA_REFRELE(ss, ssa);
1655 mutex_exit(&so->so_lock);
1656 }
1657 kmem_free(buf, intval);
1658 return (EFAULT);
1659 }
1660 /* The option level has to be IPPROTO_SCTP */
1661 error = sctp_set_opt((struct sctp_s *)conn, IPPROTO_SCTP,
1662 STRUCT_FGET(opt, sopt_name), buf, optlen);
1663 if (ssa) {
1664 mutex_enter(&so->so_lock);
1665 SSA_REFRELE(ss, ssa);
1666 mutex_exit(&so->so_lock);
1667 }
1668 kmem_free(buf, optlen);
1669 return (error);
1670
1671 case SIOCSCTPPEELOFF: {
1672 struct sonode *nso;
1673 struct sctp_uc_swap us;
1674 int nfd;
1675 struct file *nfp;
1676 struct vnode *nvp = NULL;
1677 struct sockparams *sp;
1678
1679 dprint(2, ("sctppeeloff %p\n", (void *)ss));
1680
1681 if (so->so_type != SOCK_SEQPACKET) {
1682 return (EOPNOTSUPP);
1683 }
1684 if (so_copyin((void *)arg, &intval, sizeof (intval),
1685 (mode & (int)FKIOCTL))) {
1686 return (EFAULT);
1687 }
1688 if (intval == 0) {
1689 return (EINVAL);
1690 }
1691
1692 /*
1693 * Find sockparams. This is different from parent's entry,
1694 * as the socket type is different.
1695 */
1696 error = solookup(so->so_family, SOCK_STREAM, so->so_protocol,
1697 &sp);
1698 if (error != 0)
1699 return (error);
1700
1701 /*
1702 * Allocate the user fd.
1703 */
1704 if ((nfd = ufalloc(0)) == -1) {
1705 eprintsoline(so, EMFILE);
1706 SOCKPARAMS_DEC_REF(sp);
1707 return (EMFILE);
1708 }
1709
1710 /*
1711 * Copy the fd out.
1712 */
1713 if (so_copyout(&nfd, (void *)arg, sizeof (nfd),
1714 (mode & (int)FKIOCTL))) {
1715 error = EFAULT;
1716 goto err;
1717 }
1718 mutex_enter(&so->so_lock);
1719
1720 /*
1721 * Don't use sosctp_assoc() in order to peel off disconnected
1722 * associations.
1723 */
1724 ssa = ((uint32_t)intval >= ss->ss_maxassoc) ? NULL :
1725 ss->ss_assocs[intval].ssi_assoc;
1726 if (ssa == NULL) {
1727 mutex_exit(&so->so_lock);
1728 error = EINVAL;
1729 goto err;
1730 }
1731 SSA_REFHOLD(ssa);
1732
1733 nso = socksctp_create(sp, so->so_family, SOCK_STREAM,
1734 so->so_protocol, so->so_version, SOCKET_NOSLEEP,
1735 &error, cr);
1736 if (nso == NULL) {
1737 SSA_REFRELE(ss, ssa);
1738 mutex_exit(&so->so_lock);
1739 goto err;
1740 }
1741 nvp = SOTOV(nso);
1742 so_lock_single(so);
1743 mutex_exit(&so->so_lock);
1744
1745 /* cannot fail, only inheriting properties */
1746 (void) sosctp_init(nso, so, CRED(), 0);
1747
1748 /*
1749 * We have a single ref on the new socket. This is normally
1750 * handled by socket_{create,newconn}, but since they are not
1751 * used we have to do it here.
1752 */
1753 nso->so_count = 1;
1754
1755 us.sus_handle = nso;
1756 us.sus_upcalls = &sosctp_sock_upcalls;
1757
1758 /*
1759 * Upcalls to new socket are blocked for the duration of
1760 * downcall.
1761 */
1762 mutex_enter(&nso->so_lock);
1763
1764 error = sctp_set_opt((struct sctp_s *)ssa->ssa_conn,
1765 IPPROTO_SCTP, SCTP_UC_SWAP, &us, sizeof (us));
1766 if (error) {
1767 goto peelerr;
1768 }
1769 error = falloc(nvp, FWRITE|FREAD, &nfp, NULL);
1770 if (error) {
1771 goto peelerr;
1772 }
1773
1774 /*
1775 * fill in the entries that falloc reserved
1776 */
1777 nfp->f_vnode = nvp;
1778 mutex_exit(&nfp->f_tlock);
1779 setf(nfd, nfp);
1780
1781 /* Add pid to the list associated with that socket. */
1782 if (nfp->f_vnode != NULL) {
1783 (void) VOP_IOCTL(nfp->f_vnode, F_ASSOCI_PID,
1784 (intptr_t)curproc->p_pidp->pid_id, FKIOCTL, kcred,
1785 NULL, NULL);
1786 }
1787
1788 mutex_enter(&so->so_lock);
1789
1790 sosctp_assoc_move(ss, SOTOSSO(nso), ssa);
1791
1792 mutex_exit(&nso->so_lock);
1793
1794 ssa->ssa_conn = NULL;
1795 sosctp_assoc_free(ss, ssa);
1796
1797 so_unlock_single(so, SOLOCKED);
1798 mutex_exit(&so->so_lock);
1799
1800 return (0);
1801
1802 err:
1803 SOCKPARAMS_DEC_REF(sp);
1804 setf(nfd, NULL);
1805 eprintsoline(so, error);
1806 return (error);
1807
1808 peelerr:
1809 mutex_exit(&nso->so_lock);
1810 mutex_enter(&so->so_lock);
1811 ASSERT(nso->so_count == 1);
1812 nso->so_count = 0;
1813 so_unlock_single(so, SOLOCKED);
1814 SSA_REFRELE(ss, ssa);
1815 mutex_exit(&so->so_lock);
1816
1817 setf(nfd, NULL);
1818 ASSERT(nvp->v_count == 1);
1819 socket_destroy(nso);
1820 eprintsoline(so, error);
1821 return (error);
1822 }
1823 default:
1824 return (EINVAL);
1825 }
1826 }
1827
1828 /*ARGSUSED*/
1829 static int
1830 sosctp_close(struct sonode *so, int flag, struct cred *cr)
1831 {
1832 struct sctp_sonode *ss;
1833 struct sctp_sa_id *ssi;
1834 struct sctp_soassoc *ssa;
1835 int32_t i;
1836
1837 ss = SOTOSSO(so);
1838
1839 /*
1840 * Initiate connection shutdown. Tell SCTP if there is any data
1841 * left unread.
1842 */
1843 sctp_recvd((struct sctp_s *)so->so_proto_handle,
1844 so->so_rcvbuf - so->so_rcv_queued);
1845 (void) sctp_disconnect((struct sctp_s *)so->so_proto_handle);
1846
1847 /*
1848 * New associations can't come in, but old ones might get
1849 * closed in upcall. Protect against that by taking a reference
1850 * on the association.
1851 */
1852 mutex_enter(&so->so_lock);
1853 ssi = ss->ss_assocs;
1854 for (i = 0; i < ss->ss_maxassoc; i++, ssi++) {
1855 if ((ssa = ssi->ssi_assoc) != NULL) {
1856 SSA_REFHOLD(ssa);
1857 sosctp_assoc_isdisconnected(ssa, 0);
1858 mutex_exit(&so->so_lock);
1859
1860 sctp_recvd(ssa->ssa_conn, so->so_rcvbuf -
1861 ssa->ssa_rcv_queued);
1862 (void) sctp_disconnect(ssa->ssa_conn);
1863
1864 mutex_enter(&so->so_lock);
1865 SSA_REFRELE(ss, ssa);
1866 }
1867 }
1868 mutex_exit(&so->so_lock);
1869
1870 return (0);
1871 }
1872
1873 /*
1874 * Closes incoming connections which were never accepted, frees
1875 * resources.
1876 */
1877 /* ARGSUSED */
1878 void
1879 sosctp_fini(struct sonode *so, struct cred *cr)
1880 {
1881 struct sctp_sonode *ss;
1882 struct sctp_sa_id *ssi;
1883 struct sctp_soassoc *ssa;
1884 int32_t i;
1885
1886 ss = SOTOSSO(so);
1887
1888 ASSERT(so->so_ops == &sosctp_sonodeops ||
1889 so->so_ops == &sosctp_seq_sonodeops);
1890
1891 /* We are the sole owner of so now */
1892 mutex_enter(&so->so_lock);
1893
1894 /* Free all pending connections */
1895 so_acceptq_flush(so, B_TRUE);
1896
1897 ssi = ss->ss_assocs;
1898 for (i = 0; i < ss->ss_maxassoc; i++, ssi++) {
1899 if ((ssa = ssi->ssi_assoc) != NULL) {
1900 SSA_REFHOLD(ssa);
1901 mutex_exit(&so->so_lock);
1902
1903 sctp_close((struct sctp_s *)ssa->ssa_conn);
1904
1905 mutex_enter(&so->so_lock);
1906 ssa->ssa_conn = NULL;
1907 sosctp_assoc_free(ss, ssa);
1908 }
1909 }
1910 if (ss->ss_assocs != NULL) {
1911 ASSERT(ss->ss_assoccnt == 0);
1912 kmem_free(ss->ss_assocs,
1913 ss->ss_maxassoc * sizeof (struct sctp_sa_id));
1914 }
1915 mutex_exit(&so->so_lock);
1916
1917 if (so->so_proto_handle)
1918 sctp_close((struct sctp_s *)so->so_proto_handle);
1919 so->so_proto_handle = NULL;
1920
1921 /*
1922 * Note until sctp_close() is called, SCTP can still send up
1923 * messages, such as event notifications. So we should flush
1924 * the recevie buffer after calling sctp_close().
1925 */
1926 mutex_enter(&so->so_lock);
1927 so_rcv_flush(so);
1928 mutex_exit(&so->so_lock);
1929
1930 sonode_fini(so);
1931 }
1932
1933 /*
1934 * Upcalls from SCTP
1935 */
1936
1937 /*
1938 * This is the upcall function for 1-N (SOCK_SEQPACKET) socket when a new
1939 * association is created. Note that the first argument (handle) is of type
1940 * sctp_sonode *, which is the one changed to a listener for new
1941 * associations. All the other upcalls for 1-N socket take sctp_soassoc *
1942 * as handle. The only exception is the su_properties upcall, which
1943 * can take both types as handle.
1944 */
1945 /* ARGSUSED */
1946 sock_upper_handle_t
1947 sctp_assoc_newconn(sock_upper_handle_t parenthandle,
1948 sock_lower_handle_t connind, sock_downcalls_t *dc,
1949 struct cred *peer_cred, pid_t peer_cpid, sock_upcalls_t **ucp)
1950 {
1951 struct sctp_sonode *lss = (struct sctp_sonode *)parenthandle;
1952 struct sonode *lso = &lss->ss_so;
1953 struct sctp_soassoc *ssa;
1954 sctp_assoc_t id;
1955
1956 ASSERT(lss->ss_type == SOSCTP_SOCKET);
1957 ASSERT(lso->so_state & SS_ACCEPTCONN);
1958 ASSERT(lso->so_proto_handle != NULL); /* closed conn */
1959 ASSERT(lso->so_type == SOCK_SEQPACKET);
1960
1961 mutex_enter(&lso->so_lock);
1962
1963 if ((id = sosctp_aid_get(lss)) == -1) {
1964 /*
1965 * Array not large enough; increase size.
1966 */
1967 if (sosctp_aid_grow(lss, lss->ss_maxassoc, KM_NOSLEEP) < 0) {
1968 mutex_exit(&lso->so_lock);
1969 return (NULL);
1970 }
1971 id = sosctp_aid_get(lss);
1972 ASSERT(id != -1);
1973 }
1974
1975 /*
1976 * Create soassoc for this connection
1977 */
1978 ssa = sosctp_assoc_create(lss, KM_NOSLEEP);
1979 if (ssa == NULL) {
1980 mutex_exit(&lso->so_lock);
1981 return (NULL);
1982 }
1983 sosctp_aid_reserve(lss, id, 1);
1984 lss->ss_assocs[id].ssi_assoc = ssa;
1985 ++lss->ss_assoccnt;
1986 ssa->ssa_id = id;
1987 ssa->ssa_conn = (struct sctp_s *)connind;
1988 ssa->ssa_state = (SS_ISBOUND | SS_ISCONNECTED);
1989 ssa->ssa_wroff = lss->ss_wroff;
1990 ssa->ssa_wrsize = lss->ss_wrsize;
1991
1992 mutex_exit(&lso->so_lock);
1993
1994 *ucp = &sosctp_assoc_upcalls;
1995
1996 return ((sock_upper_handle_t)ssa);
1997 }
1998
1999 /* ARGSUSED */
2000 static void
2001 sctp_assoc_connected(sock_upper_handle_t handle, sock_connid_t id,
2002 struct cred *peer_cred, pid_t peer_cpid)
2003 {
2004 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2005 struct sonode *so = &ssa->ssa_sonode->ss_so;
2006
2007 ASSERT(so->so_type == SOCK_SEQPACKET);
2008 ASSERT(ssa->ssa_conn);
2009
2010 mutex_enter(&so->so_lock);
2011 sosctp_assoc_isconnected(ssa);
2012 mutex_exit(&so->so_lock);
2013 }
2014
2015 /* ARGSUSED */
2016 static int
2017 sctp_assoc_disconnected(sock_upper_handle_t handle, sock_connid_t id, int error)
2018 {
2019 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2020 struct sonode *so = &ssa->ssa_sonode->ss_so;
2021 int ret;
2022
2023 ASSERT(so->so_type == SOCK_SEQPACKET);
2024 ASSERT(ssa->ssa_conn != NULL);
2025
2026 mutex_enter(&so->so_lock);
2027 sosctp_assoc_isdisconnected(ssa, error);
2028 if (ssa->ssa_refcnt == 1) {
2029 ret = 1;
2030 ssa->ssa_conn = NULL;
2031 } else {
2032 ret = 0;
2033 }
2034 SSA_REFRELE(SOTOSSO(so), ssa);
2035
2036 cv_broadcast(&so->so_snd_cv);
2037
2038 mutex_exit(&so->so_lock);
2039
2040 return (ret);
2041 }
2042
2043 /* ARGSUSED */
2044 static void
2045 sctp_assoc_disconnecting(sock_upper_handle_t handle, sock_opctl_action_t action,
2046 uintptr_t arg)
2047 {
2048 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2049 struct sonode *so = &ssa->ssa_sonode->ss_so;
2050
2051 ASSERT(so->so_type == SOCK_SEQPACKET);
2052 ASSERT(ssa->ssa_conn != NULL);
2053 ASSERT(action == SOCK_OPCTL_SHUT_SEND);
2054
2055 mutex_enter(&so->so_lock);
2056 sosctp_assoc_isdisconnecting(ssa);
2057 mutex_exit(&so->so_lock);
2058 }
2059
2060 /* ARGSUSED */
2061 static ssize_t
2062 sctp_assoc_recv(sock_upper_handle_t handle, mblk_t *mp, size_t len, int flags,
2063 int *errorp, boolean_t *forcepush)
2064 {
2065 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2066 struct sctp_sonode *ss = ssa->ssa_sonode;
2067 struct sonode *so = &ss->ss_so;
2068 struct T_unitdata_ind *tind;
2069 mblk_t *mp2;
2070 union sctp_notification *sn;
2071 struct sctp_sndrcvinfo *sinfo;
2072 ssize_t space_available;
2073
2074 ASSERT(ssa->ssa_type == SOSCTP_ASSOC);
2075 ASSERT(so->so_type == SOCK_SEQPACKET);
2076 ASSERT(ssa->ssa_conn != NULL); /* closed conn */
2077 ASSERT(mp != NULL);
2078
2079 ASSERT(errorp != NULL);
2080 *errorp = 0;
2081
2082 /*
2083 * Should be getting T_unitdata_req's only.
2084 * Must have address as part of packet.
2085 */
2086 tind = (struct T_unitdata_ind *)mp->b_rptr;
2087 ASSERT((DB_TYPE(mp) == M_PROTO) &&
2088 (tind->PRIM_type == T_UNITDATA_IND));
2089 ASSERT(tind->SRC_length);
2090
2091 mutex_enter(&so->so_lock);
2092
2093 /*
2094 * For notify messages, need to fill in association id.
2095 * For data messages, sndrcvinfo could be in ancillary data.
2096 */
2097 if (mp->b_flag & SCTP_NOTIFICATION) {
2098 mp2 = mp->b_cont;
2099 sn = (union sctp_notification *)mp2->b_rptr;
2100 switch (sn->sn_header.sn_type) {
2101 case SCTP_ASSOC_CHANGE:
2102 sn->sn_assoc_change.sac_assoc_id = ssa->ssa_id;
2103 break;
2104 case SCTP_PEER_ADDR_CHANGE:
2105 sn->sn_paddr_change.spc_assoc_id = ssa->ssa_id;
2106 break;
2107 case SCTP_REMOTE_ERROR:
2108 sn->sn_remote_error.sre_assoc_id = ssa->ssa_id;
2109 break;
2110 case SCTP_SEND_FAILED:
2111 sn->sn_send_failed.ssf_assoc_id = ssa->ssa_id;
2112 break;
2113 case SCTP_SHUTDOWN_EVENT:
2114 sn->sn_shutdown_event.sse_assoc_id = ssa->ssa_id;
2115 break;
2116 case SCTP_ADAPTATION_INDICATION:
2117 sn->sn_adaptation_event.sai_assoc_id = ssa->ssa_id;
2118 break;
2119 case SCTP_PARTIAL_DELIVERY_EVENT:
2120 sn->sn_pdapi_event.pdapi_assoc_id = ssa->ssa_id;
2121 break;
2122 default:
2123 ASSERT(0);
2124 break;
2125 }
2126 } else {
2127 if (tind->OPT_length > 0) {
2128 struct cmsghdr *cmsg;
2129 char *cend;
2130
2131 cmsg = (struct cmsghdr *)
2132 ((uchar_t *)mp->b_rptr + tind->OPT_offset);
2133 cend = (char *)cmsg + tind->OPT_length;
2134 for (;;) {
2135 if ((char *)(cmsg + 1) > cend ||
2136 ((char *)cmsg + cmsg->cmsg_len) > cend) {
2137 break;
2138 }
2139 if ((cmsg->cmsg_level == IPPROTO_SCTP) &&
2140 (cmsg->cmsg_type == SCTP_SNDRCV)) {
2141 sinfo = (struct sctp_sndrcvinfo *)
2142 (cmsg + 1);
2143 sinfo->sinfo_assoc_id = ssa->ssa_id;
2144 break;
2145 }
2146 if (cmsg->cmsg_len > 0) {
2147 cmsg = (struct cmsghdr *)
2148 ((uchar_t *)cmsg + cmsg->cmsg_len);
2149 } else {
2150 break;
2151 }
2152 }
2153 }
2154 }
2155
2156 /*
2157 * SCTP has reserved space in the header for storing a pointer.
2158 * Put the pointer to assocation there, and queue the data.
2159 */
2160 SSA_REFHOLD(ssa);
2161 ASSERT((mp->b_rptr - DB_BASE(mp)) >= sizeof (ssa));
2162 *(struct sctp_soassoc **)DB_BASE(mp) = ssa;
2163
2164 ssa->ssa_rcv_queued += len;
2165 space_available = so->so_rcvbuf - ssa->ssa_rcv_queued;
2166 if (space_available <= 0)
2167 ssa->ssa_flowctrld = B_TRUE;
2168
2169 so_enqueue_msg(so, mp, len);
2170
2171 /* so_notify_data drops so_lock */
2172 so_notify_data(so, len);
2173
2174 return (space_available);
2175 }
2176
2177 static void
2178 sctp_assoc_xmitted(sock_upper_handle_t handle, boolean_t qfull)
2179 {
2180 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2181 struct sctp_sonode *ss = ssa->ssa_sonode;
2182
2183 ASSERT(ssa->ssa_type == SOSCTP_ASSOC);
2184 ASSERT(ss->ss_so.so_type == SOCK_SEQPACKET);
2185 ASSERT(ssa->ssa_conn != NULL);
2186
2187 mutex_enter(&ss->ss_so.so_lock);
2188
2189 ssa->ssa_snd_qfull = qfull;
2190
2191 /*
2192 * Wake blocked writers.
2193 */
2194 cv_broadcast(&ss->ss_so.so_snd_cv);
2195
2196 mutex_exit(&ss->ss_so.so_lock);
2197 }
2198
2199 static void
2200 sctp_assoc_properties(sock_upper_handle_t handle,
2201 struct sock_proto_props *soppp)
2202 {
2203 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2204 struct sonode *so;
2205
2206 if (ssa->ssa_type == SOSCTP_ASSOC) {
2207 so = &ssa->ssa_sonode->ss_so;
2208
2209 mutex_enter(&so->so_lock);
2210
2211 /* Per assoc_id properties. */
2212 if (soppp->sopp_flags & SOCKOPT_WROFF)
2213 ssa->ssa_wroff = soppp->sopp_wroff;
2214 if (soppp->sopp_flags & SOCKOPT_MAXBLK)
2215 ssa->ssa_wrsize = soppp->sopp_maxblk;
2216 } else {
2217 so = &((struct sctp_sonode *)handle)->ss_so;
2218 mutex_enter(&so->so_lock);
2219
2220 if (soppp->sopp_flags & SOCKOPT_WROFF)
2221 so->so_proto_props.sopp_wroff = soppp->sopp_wroff;
2222 if (soppp->sopp_flags & SOCKOPT_MAXBLK)
2223 so->so_proto_props.sopp_maxblk = soppp->sopp_maxblk;
2224 if (soppp->sopp_flags & SOCKOPT_RCVHIWAT) {
2225 ssize_t lowat;
2226
2227 so->so_rcvbuf = soppp->sopp_rxhiwat;
2228 /*
2229 * The low water mark should be adjusted properly
2230 * if the high water mark is changed. It should
2231 * not be bigger than 1/4 of high water mark.
2232 */
2233 lowat = soppp->sopp_rxhiwat >> 2;
2234 if (so->so_rcvlowat > lowat) {
2235 /* Sanity check... */
2236 if (lowat == 0)
2237 so->so_rcvlowat = soppp->sopp_rxhiwat;
2238 else
2239 so->so_rcvlowat = lowat;
2240 }
2241 }
2242 }
2243 mutex_exit(&so->so_lock);
2244 }
2245
2246 static mblk_t *
2247 sctp_get_sock_pid_mblk(sock_upper_handle_t handle)
2248 {
2249 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2250 struct sonode *so;
2251
2252 if (ssa->ssa_type == SOSCTP_ASSOC)
2253 so = &ssa->ssa_sonode->ss_so;
2254 else
2255 so = &((struct sctp_sonode *)handle)->ss_so;
2256
2257 return (so_get_sock_pid_mblk((sock_upper_handle_t)so));
2258 }