6881841 MSG_NOTIFICATION is not being set for SCTP assoc sockets
[unleashed.git] / usr / src / uts / common / inet / sockmods / socksctp.c
blob718567627d822fbaef9c8f51fc644c80b530e623
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
28 #include <sys/t_lock.h>
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/buf.h>
32 #include <sys/vfs.h>
33 #include <sys/vnode.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>
41 #include <sys/project.h>
42 #include <sys/tihdr.h>
43 #include <sys/strsubr.h>
44 #include <sys/esunddi.h>
45 #include <sys/ddi.h>
47 #include <sys/sockio.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <sys/strsun.h>
52 #include <netinet/sctp.h>
53 #include <inet/sctp_itf.h>
54 #include <fs/sockfs/sockcommon.h>
55 #include "socksctp.h"
58 * SCTP sockfs sonode operations, 1-1 socket
60 static int sosctp_init(struct sonode *, struct sonode *, struct cred *, int);
61 static int sosctp_accept(struct sonode *, int, struct cred *, struct sonode **);
62 static int sosctp_bind(struct sonode *, struct sockaddr *, socklen_t, int,
63 struct cred *);
64 static int sosctp_listen(struct sonode *, int, struct cred *);
65 static int sosctp_connect(struct sonode *, const struct sockaddr *, socklen_t,
66 int, int, struct cred *);
67 static int sosctp_recvmsg(struct sonode *, struct nmsghdr *, struct uio *,
68 struct cred *);
69 static int sosctp_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
70 struct cred *);
71 static int sosctp_getpeername(struct sonode *, struct sockaddr *, socklen_t *,
72 boolean_t, struct cred *);
73 static int sosctp_getsockname(struct sonode *, struct sockaddr *, socklen_t *,
74 struct cred *);
75 static int sosctp_shutdown(struct sonode *, int, struct cred *);
76 static int sosctp_getsockopt(struct sonode *, int, int, void *, socklen_t *,
77 int, struct cred *);
78 static int sosctp_setsockopt(struct sonode *, int, int, const void *,
79 socklen_t, struct cred *);
80 static int sosctp_ioctl(struct sonode *, int, intptr_t, int, struct cred *,
81 int32_t *);
82 static int sosctp_close(struct sonode *, int, struct cred *);
83 void sosctp_fini(struct sonode *, struct cred *);
86 * SCTP sockfs sonode operations, 1-N socket
88 static int sosctp_seq_connect(struct sonode *, const struct sockaddr *,
89 socklen_t, int, int, struct cred *);
90 static int sosctp_seq_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
91 struct cred *);
94 * Socket association upcalls, 1-N socket connection
96 sock_upper_handle_t sctp_assoc_newconn(sock_upper_handle_t,
97 sock_lower_handle_t, sock_downcalls_t *, struct cred *, pid_t,
98 sock_upcalls_t **);
99 static void sctp_assoc_connected(sock_upper_handle_t, sock_connid_t,
100 struct cred *, pid_t);
101 static int sctp_assoc_disconnected(sock_upper_handle_t, sock_connid_t, int);
102 static void sctp_assoc_disconnecting(sock_upper_handle_t, sock_opctl_action_t,
103 uintptr_t arg);
104 static ssize_t sctp_assoc_recv(sock_upper_handle_t, mblk_t *, size_t, int,
105 int *, boolean_t *);
106 static void sctp_assoc_xmitted(sock_upper_handle_t, boolean_t);
107 static void sctp_assoc_properties(sock_upper_handle_t,
108 struct sock_proto_props *);
110 sonodeops_t sosctp_sonodeops = {
111 sosctp_init, /* sop_init */
112 sosctp_accept, /* sop_accept */
113 sosctp_bind, /* sop_bind */
114 sosctp_listen, /* sop_listen */
115 sosctp_connect, /* sop_connect */
116 sosctp_recvmsg, /* sop_recvmsg */
117 sosctp_sendmsg, /* sop_sendmsg */
118 so_sendmblk_notsupp, /* sop_sendmblk */
119 sosctp_getpeername, /* sop_getpeername */
120 sosctp_getsockname, /* sop_getsockname */
121 sosctp_shutdown, /* sop_shutdown */
122 sosctp_getsockopt, /* sop_getsockopt */
123 sosctp_setsockopt, /* sop_setsockopt */
124 sosctp_ioctl, /* sop_ioctl */
125 so_poll, /* sop_poll */
126 sosctp_close, /* sop_close */
129 sonodeops_t sosctp_seq_sonodeops = {
130 sosctp_init, /* sop_init */
131 so_accept_notsupp, /* sop_accept */
132 sosctp_bind, /* sop_bind */
133 sosctp_listen, /* sop_listen */
134 sosctp_seq_connect, /* sop_connect */
135 sosctp_recvmsg, /* sop_recvmsg */
136 sosctp_seq_sendmsg, /* sop_sendmsg */
137 so_sendmblk_notsupp, /* sop_sendmblk */
138 so_getpeername_notsupp, /* sop_getpeername */
139 sosctp_getsockname, /* sop_getsockname */
140 so_shutdown_notsupp, /* sop_shutdown */
141 sosctp_getsockopt, /* sop_getsockopt */
142 sosctp_setsockopt, /* sop_setsockopt */
143 sosctp_ioctl, /* sop_ioctl */
144 so_poll, /* sop_poll */
145 sosctp_close, /* sop_close */
148 sock_upcalls_t sosctp_sock_upcalls = {
149 so_newconn,
150 so_connected,
151 so_disconnected,
152 so_opctl,
153 so_queue_msg,
154 so_set_prop,
155 so_txq_full,
156 NULL, /* su_signal_oob */
159 sock_upcalls_t sosctp_assoc_upcalls = {
160 sctp_assoc_newconn,
161 sctp_assoc_connected,
162 sctp_assoc_disconnected,
163 sctp_assoc_disconnecting,
164 sctp_assoc_recv,
165 sctp_assoc_properties,
166 sctp_assoc_xmitted,
167 NULL, /* su_recv_space */
168 NULL, /* su_signal_oob */
171 /* ARGSUSED */
172 static int
173 sosctp_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
175 struct sctp_sonode *ss;
176 struct sctp_sonode *pss;
177 sctp_sockbuf_limits_t sbl;
178 sock_upcalls_t *upcalls;
180 ss = SOTOSSO(so);
182 if (pso != NULL) {
184 * Passive open, just inherit settings from parent. We should
185 * not end up here for SOCK_SEQPACKET type sockets, since no
186 * new sonode is created in that case.
188 ASSERT(so->so_type == SOCK_STREAM);
189 pss = SOTOSSO(pso);
191 mutex_enter(&pso->so_lock);
192 so->so_state |= (SS_ISBOUND | SS_ISCONNECTED |
193 (pso->so_state & SS_ASYNC));
194 sosctp_so_inherit(pss, ss);
195 so->so_proto_props = pso->so_proto_props;
196 so->so_mode = pso->so_mode;
197 mutex_exit(&pso->so_lock);
199 return (0);
202 if (so->so_type == SOCK_STREAM) {
203 upcalls = &sosctp_sock_upcalls;
204 so->so_mode = SM_CONNREQUIRED;
205 } else {
206 ASSERT(so->so_type == SOCK_SEQPACKET);
207 upcalls = &sosctp_assoc_upcalls;
209 so->so_proto_handle = (sock_lower_handle_t)sctp_create(so, NULL,
210 so->so_family, SCTP_CAN_BLOCK, upcalls, &sbl, cr);
211 if (so->so_proto_handle == NULL)
212 return (ENOMEM);
214 so->so_rcvbuf = sbl.sbl_rxbuf;
215 so->so_rcvlowat = sbl.sbl_rxlowat;
216 so->so_sndbuf = sbl.sbl_txbuf;
217 so->so_sndlowat = sbl.sbl_txlowat;
219 return (0);
223 * Accept incoming connection.
225 /*ARGSUSED*/
226 static int
227 sosctp_accept(struct sonode *so, int fflag, struct cred *cr,
228 struct sonode **nsop)
230 int error = 0;
232 if ((so->so_state & SS_ACCEPTCONN) == 0)
233 return (EINVAL);
235 error = so_acceptq_dequeue(so, (fflag & (FNONBLOCK|FNDELAY)), nsop);
237 return (error);
241 * Bind local endpoint.
243 /*ARGSUSED*/
244 static int
245 sosctp_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen,
246 int flags, struct cred *cr)
248 int error;
250 if (!(flags & _SOBIND_LOCK_HELD)) {
251 mutex_enter(&so->so_lock);
252 so_lock_single(so); /* Set SOLOCKED */
253 } else {
254 ASSERT(MUTEX_HELD(&so->so_lock));
258 * X/Open requires this check
260 if (so->so_state & SS_CANTSENDMORE) {
261 error = EINVAL;
262 goto done;
267 * Protocol module does address family checks.
269 mutex_exit(&so->so_lock);
271 error = sctp_bind((struct sctp_s *)so->so_proto_handle, name, namelen);
273 mutex_enter(&so->so_lock);
274 if (error == 0) {
275 so->so_state |= SS_ISBOUND;
276 } else {
277 eprintsoline(so, error);
279 done:
280 if (!(flags & _SOBIND_LOCK_HELD)) {
281 so_unlock_single(so, SOLOCKED);
282 mutex_exit(&so->so_lock);
283 } else {
284 /* If the caller held the lock don't release it here */
285 ASSERT(MUTEX_HELD(&so->so_lock));
286 ASSERT(so->so_flag & SOLOCKED);
289 return (error);
293 * Turn socket into a listen socket.
295 /* ARGSUSED */
296 static int
297 sosctp_listen(struct sonode *so, int backlog, struct cred *cr)
299 int error = 0;
301 mutex_enter(&so->so_lock);
302 so_lock_single(so);
305 * If this socket is trying to do connect, or if it has
306 * been connected, disallow.
308 if (so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED |
309 SS_ISDISCONNECTING | SS_CANTRCVMORE | SS_CANTSENDMORE)) {
310 error = EINVAL;
311 eprintsoline(so, error);
312 goto done;
315 if (backlog < 0) {
316 backlog = 0;
320 * If listen() is only called to change backlog, we don't
321 * need to notify protocol module.
323 if (so->so_state & SS_ACCEPTCONN) {
324 so->so_backlog = backlog;
325 goto done;
328 mutex_exit(&so->so_lock);
329 error = sctp_listen((struct sctp_s *)so->so_proto_handle);
330 mutex_enter(&so->so_lock);
331 if (error == 0) {
332 so->so_state |= (SS_ACCEPTCONN|SS_ISBOUND);
333 so->so_backlog = backlog;
334 } else {
335 eprintsoline(so, error);
337 done:
338 so_unlock_single(so, SOLOCKED);
339 mutex_exit(&so->so_lock);
341 return (error);
345 * Active open.
347 /*ARGSUSED*/
348 static int
349 sosctp_connect(struct sonode *so, const struct sockaddr *name,
350 socklen_t namelen, int fflag, int flags, struct cred *cr)
352 int error = 0;
354 ASSERT(so->so_type == SOCK_STREAM);
356 mutex_enter(&so->so_lock);
357 so_lock_single(so);
360 * Can't connect() after listen(), or if the socket is already
361 * connected.
363 if (so->so_state & (SS_ACCEPTCONN|SS_ISCONNECTED|SS_ISCONNECTING)) {
364 if (so->so_state & SS_ISCONNECTED) {
365 error = EISCONN;
366 } else if (so->so_state & SS_ISCONNECTING) {
367 error = EALREADY;
368 } else {
369 error = EOPNOTSUPP;
371 eprintsoline(so, error);
372 goto done;
376 * Check for failure of an earlier call
378 if (so->so_error != 0) {
379 error = sogeterr(so, B_TRUE);
380 eprintsoline(so, error);
381 goto done;
385 * Connection is closing, or closed, don't allow reconnect.
386 * TCP allows this to proceed, but the socket remains unwriteable.
387 * BSD returns EINVAL.
389 if (so->so_state & (SS_ISDISCONNECTING|SS_CANTRCVMORE|
390 SS_CANTSENDMORE)) {
391 error = EINVAL;
392 eprintsoline(so, error);
393 goto done;
396 if (name == NULL || namelen == 0) {
397 mutex_exit(&so->so_lock);
398 error = EINVAL;
399 eprintsoline(so, error);
400 goto done;
403 soisconnecting(so);
404 mutex_exit(&so->so_lock);
406 error = sctp_connect((struct sctp_s *)so->so_proto_handle,
407 name, namelen);
409 mutex_enter(&so->so_lock);
410 if (error == 0) {
412 * Allow other threads to access the socket
414 error = sowaitconnected(so, fflag, 0);
416 done:
417 so_unlock_single(so, SOLOCKED);
418 mutex_exit(&so->so_lock);
419 return (error);
423 * Active open for 1-N sockets, create a new association and
424 * call connect on that.
425 * If there parent hasn't been bound yet (this is the first association),
426 * make it so.
428 static int
429 sosctp_seq_connect(struct sonode *so, const struct sockaddr *name,
430 socklen_t namelen, int fflag, int flags, struct cred *cr)
432 struct sctp_soassoc *ssa;
433 struct sctp_sonode *ss;
434 int error;
436 ASSERT(so->so_type == SOCK_SEQPACKET);
438 mutex_enter(&so->so_lock);
439 so_lock_single(so);
441 if (name == NULL || namelen == 0) {
442 error = EINVAL;
443 eprintsoline(so, error);
444 goto done;
447 ss = SOTOSSO(so);
449 error = sosctp_assoc_createconn(ss, name, namelen, NULL, 0, fflag,
450 cr, &ssa);
451 if (error != 0) {
452 if ((error == EHOSTUNREACH) && (flags & _SOCONNECT_XPG4_2)) {
453 error = ENETUNREACH;
456 if (ssa != NULL) {
457 SSA_REFRELE(ss, ssa);
460 done:
461 so_unlock_single(so, SOLOCKED);
462 mutex_exit(&so->so_lock);
463 return (error);
467 * Receive data.
469 /* ARGSUSED */
470 static int
471 sosctp_recvmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
472 struct cred *cr)
474 struct sctp_sonode *ss = SOTOSSO(so);
475 struct sctp_soassoc *ssa = NULL;
476 int flags, error = 0;
477 struct T_unitdata_ind *tind;
478 ssize_t orig_resid = uiop->uio_resid;
479 int len, count, readcnt = 0, rxqueued;
480 socklen_t controllen, namelen;
481 void *opt;
482 mblk_t *mp;
483 rval_t rval;
485 controllen = msg->msg_controllen;
486 namelen = msg->msg_namelen;
487 flags = msg->msg_flags;
488 msg->msg_flags = 0;
489 msg->msg_controllen = 0;
490 msg->msg_namelen = 0;
492 if (so->so_type == SOCK_STREAM) {
493 if (!(so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING|
494 SS_CANTRCVMORE))) {
495 return (ENOTCONN);
497 } else {
498 /* NOTE: Will come here from vop_read() as well */
499 /* For 1-N socket, recv() cannot be used. */
500 if (namelen == 0)
501 return (EOPNOTSUPP);
503 * If there are no associations, and no new connections are
504 * coming in, there's not going to be new messages coming
505 * in either.
507 if (so->so_rcv_q_head == NULL && so->so_rcv_head == NULL &&
508 ss->ss_assoccnt == 0 && !(so->so_state & SS_ACCEPTCONN)) {
509 return (ENOTCONN);
514 * out-of-band data not supported.
516 if (flags & MSG_OOB) {
517 return (EOPNOTSUPP);
521 * flag possibilities:
523 * MSG_PEEK Don't consume data
524 * MSG_WAITALL Wait for full quantity of data (ignored if MSG_PEEK)
525 * MSG_DONTWAIT Non-blocking (same as FNDELAY | FNONBLOCK)
527 * MSG_WAITALL can return less than the full buffer if either
529 * 1. we would block and we are non-blocking
530 * 2. a full message cannot be delivered
532 * Given that we always get a full message from proto below,
533 * MSG_WAITALL is not meaningful.
536 mutex_enter(&so->so_lock);
539 * Allow just one reader at a time.
541 error = so_lock_read_intr(so,
542 uiop->uio_fmode | ((flags & MSG_DONTWAIT) ? FNONBLOCK : 0));
543 if (error) {
544 mutex_exit(&so->so_lock);
545 return (error);
547 mutex_exit(&so->so_lock);
548 again:
549 error = so_dequeue_msg(so, &mp, uiop, &rval, flags | MSG_DUPCTRL);
550 if (mp != NULL) {
551 if (so->so_type == SOCK_SEQPACKET) {
552 ssa = *(struct sctp_soassoc **)DB_BASE(mp);
555 tind = (struct T_unitdata_ind *)mp->b_rptr;
557 len = tind->SRC_length;
559 if (namelen > 0 && len > 0) {
561 opt = sogetoff(mp, tind->SRC_offset, len, 1);
563 ASSERT(opt != NULL);
565 msg->msg_name = kmem_alloc(len, KM_SLEEP);
566 msg->msg_namelen = len;
568 bcopy(opt, msg->msg_name, len);
571 len = tind->OPT_length;
572 if (controllen == 0) {
573 if (len > 0) {
574 msg->msg_flags |= MSG_CTRUNC;
576 } else if (len > 0) {
577 opt = sogetoff(mp, tind->OPT_offset, len,
578 __TPI_ALIGN_SIZE);
580 ASSERT(opt != NULL);
581 sosctp_pack_cmsg(opt, msg, len);
584 if (mp->b_flag & SCTP_NOTIFICATION) {
585 msg->msg_flags |= MSG_NOTIFICATION;
588 if (!(mp->b_flag & SCTP_PARTIAL_DATA))
589 msg->msg_flags |= MSG_EOR;
590 freemsg(mp);
592 done:
593 if (!(flags & MSG_PEEK))
594 readcnt = orig_resid - uiop->uio_resid;
596 * Determine if we need to update SCTP about the buffer
597 * space. For performance reason, we cannot update SCTP
598 * every time a message is read. The socket buffer low
599 * watermark is used as the threshold.
601 if (ssa == NULL) {
602 mutex_enter(&so->so_lock);
603 rxqueued = so->so_rcv_queued;
604 count = so->so_rcvbuf - so->so_rcv_queued;
606 ASSERT(so->so_rcv_q_head != NULL ||
607 so->so_rcv_head != NULL ||
608 so->so_rcv_queued == 0);
610 so_unlock_read(so);
611 mutex_exit(&so->so_lock);
613 if (readcnt > 0 && (((count > 0) &&
614 ((rxqueued + readcnt) >= so->so_rcvlowat)) ||
615 (rxqueued == 0))) {
617 * If amount of queued data is higher than watermark,
618 * updata SCTP's idea of available buffer space.
620 sctp_recvd((struct sctp_s *)so->so_proto_handle, count);
622 } else {
624 * Each association keeps track of how much data it has
625 * queued; we need to update the value here. Note that this
626 * is slightly different from SOCK_STREAM type sockets, which
627 * does not need to update the byte count, as it is already
628 * done in so_dequeue_msg().
630 mutex_enter(&so->so_lock);
631 rxqueued = ssa->ssa_rcv_queued;
633 ssa->ssa_rcv_queued = rxqueued - readcnt;
634 count = so->so_rcvbuf - ssa->ssa_rcv_queued;
636 so_unlock_read(so);
638 if (readcnt > 0 &&
639 (((count > 0) && (rxqueued >= so->so_rcvlowat)) ||
640 (ssa->ssa_rcv_queued == 0))) {
642 * If amount of queued data is higher than watermark,
643 * updata SCTP's idea of available buffer space.
645 mutex_exit(&so->so_lock);
647 sctp_recvd((struct sctp_s *)ssa->ssa_conn, count);
649 mutex_enter(&so->so_lock);
652 * MOREDATA flag is set if all data could not be copied
654 if (!(flags & MSG_PEEK) && !(rval.r_val1 & MOREDATA)) {
655 SSA_REFRELE(ss, ssa);
657 mutex_exit(&so->so_lock);
660 return (error);
664 sosctp_uiomove(mblk_t *hdr_mp, ssize_t count, ssize_t blk_size, int wroff,
665 struct uio *uiop, int flags, cred_t *cr)
667 ssize_t size;
668 int error;
669 mblk_t *mp;
670 dblk_t *dp;
672 if (blk_size == INFPSZ)
673 blk_size = count;
676 * Loop until we have all data copied into mblk's.
678 while (count > 0) {
679 size = MIN(count, blk_size);
682 * As a message can be splitted up and sent in different
683 * packets, each mblk will have the extra space before
684 * data to accommodate what SCTP wants to put in there.
686 while ((mp = allocb_cred(size + wroff, cr,
687 curproc->p_pid)) == NULL) {
688 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
689 (flags & MSG_DONTWAIT)) {
690 return (EAGAIN);
692 if ((error = strwaitbuf(size + wroff, BPRI_MED))) {
693 return (error);
697 dp = mp->b_datap;
698 dp->db_cpid = curproc->p_pid;
699 ASSERT(wroff <= dp->db_lim - mp->b_wptr);
700 mp->b_rptr += wroff;
701 error = uiomove(mp->b_rptr, size, UIO_WRITE, uiop);
702 if (error != 0) {
703 freeb(mp);
704 return (error);
706 mp->b_wptr = mp->b_rptr + size;
707 count -= size;
708 hdr_mp->b_cont = mp;
709 hdr_mp = mp;
711 return (0);
715 * Send message.
717 static int
718 sosctp_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
719 struct cred *cr)
721 struct sctp_sonode *ss = SOTOSSO(so);
722 mblk_t *mctl;
723 struct cmsghdr *cmsg;
724 struct sctp_sndrcvinfo *sinfo;
725 int optlen, flags, fflag;
726 ssize_t count, msglen;
727 int error;
729 ASSERT(so->so_type == SOCK_STREAM);
731 flags = msg->msg_flags;
732 if (flags & MSG_OOB) {
734 * No out-of-band data support.
736 return (EOPNOTSUPP);
739 if (msg->msg_controllen != 0) {
740 optlen = msg->msg_controllen;
741 cmsg = sosctp_find_cmsg(msg->msg_control, optlen, SCTP_SNDRCV);
742 if (cmsg != NULL) {
743 if (cmsg->cmsg_len <
744 (sizeof (*sinfo) + sizeof (*cmsg))) {
745 eprintsoline(so, EINVAL);
746 return (EINVAL);
748 sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1);
750 /* Both flags should not be set together. */
751 if ((sinfo->sinfo_flags & MSG_EOF) &&
752 (sinfo->sinfo_flags & MSG_ABORT)) {
753 eprintsoline(so, EINVAL);
754 return (EINVAL);
757 /* Initiate a graceful shutdown. */
758 if (sinfo->sinfo_flags & MSG_EOF) {
759 /* Can't include data in MSG_EOF message. */
760 if (uiop->uio_resid != 0) {
761 eprintsoline(so, EINVAL);
762 return (EINVAL);
766 * This is the same sequence as done in
767 * shutdown(SHUT_WR).
769 mutex_enter(&so->so_lock);
770 so_lock_single(so);
771 socantsendmore(so);
772 cv_broadcast(&so->so_snd_cv);
773 so->so_state |= SS_ISDISCONNECTING;
774 mutex_exit(&so->so_lock);
776 pollwakeup(&so->so_poll_list, POLLOUT);
777 sctp_recvd((struct sctp_s *)so->so_proto_handle,
778 so->so_rcvbuf);
779 error = sctp_disconnect(
780 (struct sctp_s *)so->so_proto_handle);
782 mutex_enter(&so->so_lock);
783 so_unlock_single(so, SOLOCKED);
784 mutex_exit(&so->so_lock);
785 return (error);
788 } else {
789 optlen = 0;
792 mutex_enter(&so->so_lock);
793 for (;;) {
794 if (so->so_state & SS_CANTSENDMORE) {
795 mutex_exit(&so->so_lock);
796 return (EPIPE);
799 if (so->so_error != 0) {
800 error = sogeterr(so, B_TRUE);
801 mutex_exit(&so->so_lock);
802 return (error);
805 if (!so->so_snd_qfull)
806 break;
808 if (so->so_state & SS_CLOSING) {
809 mutex_exit(&so->so_lock);
810 return (EINTR);
813 * Xmit window full in a blocking socket.
815 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
816 (flags & MSG_DONTWAIT)) {
817 mutex_exit(&so->so_lock);
818 return (EAGAIN);
819 } else {
821 * Wait for space to become available and try again.
823 error = cv_wait_sig(&so->so_snd_cv, &so->so_lock);
824 if (!error) { /* signal */
825 mutex_exit(&so->so_lock);
826 return (EINTR);
830 msglen = count = uiop->uio_resid;
832 /* Don't allow sending a message larger than the send buffer size. */
833 /* XXX Transport module need to enforce this */
834 if (msglen > so->so_sndbuf) {
835 mutex_exit(&so->so_lock);
836 return (EMSGSIZE);
840 * Allow piggybacking data on handshake messages (SS_ISCONNECTING).
842 if (!(so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED))) {
844 * We need to check here for listener so that the
845 * same error will be returned as with a TCP socket.
846 * In this case, sosctp_connect() returns EOPNOTSUPP
847 * while a TCP socket returns ENOTCONN instead. Catch it
848 * here to have the same behavior as a TCP socket.
850 * We also need to make sure that the peer address is
851 * provided before we attempt to do the connect.
853 if ((so->so_state & SS_ACCEPTCONN) ||
854 msg->msg_name == NULL) {
855 mutex_exit(&so->so_lock);
856 error = ENOTCONN;
857 goto error_nofree;
859 mutex_exit(&so->so_lock);
860 fflag = uiop->uio_fmode;
861 if (flags & MSG_DONTWAIT) {
862 fflag |= FNDELAY;
864 error = sosctp_connect(so, msg->msg_name, msg->msg_namelen,
865 fflag, (so->so_version == SOV_XPG4_2) * _SOCONNECT_XPG4_2,
866 cr);
867 if (error) {
869 * Check for non-fatal errors, socket connected
870 * while the lock had been lifted.
872 if (error != EISCONN && error != EALREADY) {
873 goto error_nofree;
875 error = 0;
877 } else {
878 mutex_exit(&so->so_lock);
881 mctl = sctp_alloc_hdr(msg->msg_name, msg->msg_namelen,
882 msg->msg_control, optlen, SCTP_CAN_BLOCK);
883 if (mctl == NULL) {
884 error = EINTR;
885 goto error_nofree;
888 /* Copy in the message. */
889 if ((error = sosctp_uiomove(mctl, count, ss->ss_wrsize, ss->ss_wroff,
890 uiop, flags, cr)) != 0) {
891 goto error_ret;
893 error = sctp_sendmsg((struct sctp_s *)so->so_proto_handle, mctl, 0);
894 if (error == 0)
895 return (0);
897 error_ret:
898 freemsg(mctl);
899 error_nofree:
900 mutex_enter(&so->so_lock);
901 if ((error == EPIPE) && (so->so_state & SS_CANTSENDMORE)) {
903 * We received shutdown between the time lock was
904 * lifted and call to sctp_sendmsg().
906 mutex_exit(&so->so_lock);
907 return (EPIPE);
909 mutex_exit(&so->so_lock);
910 return (error);
914 * Send message on 1-N socket. Connects automatically if there is
915 * no association.
917 static int
918 sosctp_seq_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
919 struct cred *cr)
921 struct sctp_sonode *ss;
922 struct sctp_soassoc *ssa;
923 struct cmsghdr *cmsg;
924 struct sctp_sndrcvinfo *sinfo;
925 int aid = 0;
926 mblk_t *mctl;
927 int namelen, optlen, flags;
928 ssize_t count, msglen;
929 int error;
930 uint16_t s_flags = 0;
932 ASSERT(so->so_type == SOCK_SEQPACKET);
935 * There shouldn't be problems with alignment, as the memory for
936 * msg_control was alloced with kmem_alloc.
938 cmsg = sosctp_find_cmsg(msg->msg_control, msg->msg_controllen,
939 SCTP_SNDRCV);
940 if (cmsg != NULL) {
941 if (cmsg->cmsg_len < (sizeof (*sinfo) + sizeof (*cmsg))) {
942 eprintsoline(so, EINVAL);
943 return (EINVAL);
945 sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1);
946 s_flags = sinfo->sinfo_flags;
947 aid = sinfo->sinfo_assoc_id;
950 ss = SOTOSSO(so);
951 namelen = msg->msg_namelen;
953 if (msg->msg_controllen > 0) {
954 optlen = msg->msg_controllen;
955 } else {
956 optlen = 0;
959 mutex_enter(&so->so_lock);
962 * If there is no association id, connect to address specified
963 * in msg_name. Otherwise look up the association using the id.
965 if (aid == 0) {
967 * Connect and shutdown cannot be done together, so check for
968 * MSG_EOF.
970 if (msg->msg_name == NULL || namelen == 0 ||
971 (s_flags & MSG_EOF)) {
972 error = EINVAL;
973 eprintsoline(so, error);
974 goto done;
976 flags = uiop->uio_fmode;
977 if (msg->msg_flags & MSG_DONTWAIT) {
978 flags |= FNDELAY;
980 so_lock_single(so);
981 error = sosctp_assoc_createconn(ss, msg->msg_name, namelen,
982 msg->msg_control, optlen, flags, cr, &ssa);
983 if (error) {
984 if ((so->so_version == SOV_XPG4_2) &&
985 (error == EHOSTUNREACH)) {
986 error = ENETUNREACH;
988 if (ssa == NULL) {
990 * Fatal error during connect(). Bail out.
991 * If ssa exists, it means that the handshake
992 * is in progress.
994 eprintsoline(so, error);
995 so_unlock_single(so, SOLOCKED);
996 goto done;
999 * All the errors are non-fatal ones, don't return
1000 * e.g. EINPROGRESS from sendmsg().
1002 error = 0;
1004 so_unlock_single(so, SOLOCKED);
1005 } else {
1006 if ((error = sosctp_assoc(ss, aid, &ssa)) != 0) {
1007 eprintsoline(so, error);
1008 goto done;
1013 * Now we have an association.
1015 flags = msg->msg_flags;
1018 * MSG_EOF initiates graceful shutdown.
1020 if (s_flags & MSG_EOF) {
1021 if (uiop->uio_resid) {
1023 * Can't include data in MSG_EOF message.
1025 error = EINVAL;
1026 } else {
1027 mutex_exit(&so->so_lock);
1028 ssa->ssa_state |= SS_ISDISCONNECTING;
1029 sctp_recvd((struct sctp_s *)ssa->ssa_conn,
1030 so->so_rcvbuf);
1031 error = sctp_disconnect((struct sctp_s *)ssa->ssa_conn);
1032 mutex_enter(&so->so_lock);
1034 goto refrele;
1037 for (;;) {
1038 if (ssa->ssa_state & SS_CANTSENDMORE) {
1039 SSA_REFRELE(ss, ssa);
1040 mutex_exit(&so->so_lock);
1041 return (EPIPE);
1043 if (ssa->ssa_error != 0) {
1044 error = ssa->ssa_error;
1045 ssa->ssa_error = 0;
1046 goto refrele;
1049 if (!ssa->ssa_snd_qfull)
1050 break;
1052 if (so->so_state & SS_CLOSING) {
1053 error = EINTR;
1054 goto refrele;
1056 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
1057 (flags & MSG_DONTWAIT)) {
1058 error = EAGAIN;
1059 goto refrele;
1060 } else {
1062 * Wait for space to become available and try again.
1064 error = cv_wait_sig(&so->so_snd_cv, &so->so_lock);
1065 if (!error) { /* signal */
1066 error = EINTR;
1067 goto refrele;
1072 msglen = count = uiop->uio_resid;
1074 /* Don't allow sending a message larger than the send buffer size. */
1075 if (msglen > so->so_sndbuf) {
1076 error = EMSGSIZE;
1077 goto refrele;
1081 * Update TX buffer usage here so that we can lift the socket lock.
1083 mutex_exit(&so->so_lock);
1085 mctl = sctp_alloc_hdr(msg->msg_name, namelen, msg->msg_control,
1086 optlen, SCTP_CAN_BLOCK);
1087 if (mctl == NULL) {
1088 error = EINTR;
1089 goto lock_rele;
1092 /* Copy in the message. */
1093 if ((error = sosctp_uiomove(mctl, count, ssa->ssa_wrsize,
1094 ssa->ssa_wroff, uiop, flags, cr)) != 0) {
1095 goto lock_rele;
1097 error = sctp_sendmsg((struct sctp_s *)ssa->ssa_conn, mctl, 0);
1098 lock_rele:
1099 mutex_enter(&so->so_lock);
1100 if (error != 0) {
1101 freemsg(mctl);
1102 if ((error == EPIPE) && (ssa->ssa_state & SS_CANTSENDMORE)) {
1104 * We received shutdown between the time lock was
1105 * lifted and call to sctp_sendmsg().
1107 SSA_REFRELE(ss, ssa);
1108 mutex_exit(&so->so_lock);
1109 return (EPIPE);
1113 refrele:
1114 SSA_REFRELE(ss, ssa);
1115 done:
1116 mutex_exit(&so->so_lock);
1117 return (error);
1121 * Get address of remote node.
1123 /* ARGSUSED */
1124 static int
1125 sosctp_getpeername(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen,
1126 boolean_t accept, struct cred *cr)
1128 return (sctp_getpeername((struct sctp_s *)so->so_proto_handle, addr,
1129 addrlen));
1133 * Get local address.
1135 /* ARGSUSED */
1136 static int
1137 sosctp_getsockname(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen,
1138 struct cred *cr)
1140 return (sctp_getsockname((struct sctp_s *)so->so_proto_handle, addr,
1141 addrlen));
1145 * Called from shutdown().
1147 /* ARGSUSED */
1148 static int
1149 sosctp_shutdown(struct sonode *so, int how, struct cred *cr)
1151 uint_t state_change;
1152 int wakesig = 0;
1153 int error = 0;
1155 mutex_enter(&so->so_lock);
1157 * Record the current state and then perform any state changes.
1158 * Then use the difference between the old and new states to
1159 * determine which needs to be done.
1161 state_change = so->so_state;
1163 switch (how) {
1164 case SHUT_RD:
1165 socantrcvmore(so);
1166 break;
1167 case SHUT_WR:
1168 socantsendmore(so);
1169 break;
1170 case SHUT_RDWR:
1171 socantsendmore(so);
1172 socantrcvmore(so);
1173 break;
1174 default:
1175 mutex_exit(&so->so_lock);
1176 return (EINVAL);
1179 state_change = so->so_state & ~state_change;
1181 if (state_change & SS_CANTRCVMORE) {
1182 if (so->so_rcv_q_head == NULL) {
1183 cv_signal(&so->so_rcv_cv);
1185 wakesig = POLLIN|POLLRDNORM;
1187 socket_sendsig(so, SOCKETSIG_READ);
1189 if (state_change & SS_CANTSENDMORE) {
1190 cv_broadcast(&so->so_snd_cv);
1191 wakesig |= POLLOUT;
1193 so->so_state |= SS_ISDISCONNECTING;
1195 mutex_exit(&so->so_lock);
1197 pollwakeup(&so->so_poll_list, wakesig);
1199 if (state_change & SS_CANTSENDMORE) {
1200 sctp_recvd((struct sctp_s *)so->so_proto_handle, so->so_rcvbuf);
1201 error = sctp_disconnect((struct sctp_s *)so->so_proto_handle);
1205 * HACK: sctp_disconnect() may return EWOULDBLOCK. But this error is
1206 * not documented in standard socket API. Catch it here.
1208 if (error == EWOULDBLOCK)
1209 error = 0;
1210 return (error);
1214 * Get socket options.
1216 /*ARGSUSED5*/
1217 static int
1218 sosctp_getsockopt(struct sonode *so, int level, int option_name,
1219 void *optval, socklen_t *optlenp, int flags, struct cred *cr)
1221 socklen_t maxlen = *optlenp;
1222 socklen_t len;
1223 socklen_t optlen;
1224 uint8_t buffer[4];
1225 void *optbuf = &buffer;
1226 int error = 0;
1229 if (level == SOL_SOCKET) {
1230 switch (option_name) {
1231 /* Not supported options */
1232 case SO_SNDTIMEO:
1233 case SO_RCVTIMEO:
1234 case SO_EXCLBIND:
1235 error = ENOPROTOOPT;
1236 eprintsoline(so, error);
1237 goto done;
1239 case SO_TYPE:
1240 case SO_ERROR:
1241 case SO_DEBUG:
1242 case SO_ACCEPTCONN:
1243 case SO_REUSEADDR:
1244 case SO_KEEPALIVE:
1245 case SO_DONTROUTE:
1246 case SO_BROADCAST:
1247 case SO_USELOOPBACK:
1248 case SO_OOBINLINE:
1249 case SO_SNDBUF:
1250 case SO_RCVBUF:
1251 case SO_SNDLOWAT:
1252 case SO_RCVLOWAT:
1253 case SO_DGRAM_ERRIND:
1254 case SO_PROTOTYPE:
1255 case SO_DOMAIN:
1256 if (maxlen < (t_uscalar_t)sizeof (int32_t)) {
1257 error = EINVAL;
1258 eprintsoline(so, error);
1259 goto done;
1261 break;
1262 case SO_LINGER:
1263 if (maxlen < (t_uscalar_t)sizeof (struct linger)) {
1264 error = EINVAL;
1265 eprintsoline(so, error);
1266 goto done;
1268 break;
1272 if (level == IPPROTO_SCTP) {
1274 * Should go through ioctl().
1276 return (EINVAL);
1279 if (maxlen > sizeof (buffer)) {
1280 optbuf = kmem_alloc(maxlen, KM_SLEEP);
1282 optlen = maxlen;
1285 * If the resulting optlen is greater than the provided maxlen, then
1286 * we sliently trucate.
1288 error = sctp_get_opt((struct sctp_s *)so->so_proto_handle, level,
1289 option_name, optbuf, &optlen);
1291 if (error != 0) {
1292 eprintsoline(so, error);
1293 goto free;
1295 len = optlen;
1297 copyout:
1299 len = MIN(len, maxlen);
1300 bcopy(optbuf, optval, len);
1301 *optlenp = optlen;
1302 free:
1303 if (optbuf != &buffer) {
1304 kmem_free(optbuf, maxlen);
1306 done:
1307 return (error);
1311 * Set socket options
1313 /* ARGSUSED */
1314 static int
1315 sosctp_setsockopt(struct sonode *so, int level, int option_name,
1316 const void *optval, t_uscalar_t optlen, struct cred *cr)
1318 struct sctp_sonode *ss = SOTOSSO(so);
1319 struct sctp_soassoc *ssa = NULL;
1320 sctp_assoc_t id;
1321 int error, rc;
1322 void *conn = NULL;
1324 mutex_enter(&so->so_lock);
1327 * For some SCTP level options, one can select the association this
1328 * applies to.
1330 if (so->so_type == SOCK_STREAM) {
1331 conn = so->so_proto_handle;
1332 } else {
1334 * SOCK_SEQPACKET only
1336 id = 0;
1337 if (level == IPPROTO_SCTP) {
1338 switch (option_name) {
1339 case SCTP_RTOINFO:
1340 case SCTP_ASSOCINFO:
1341 case SCTP_SET_PEER_PRIMARY_ADDR:
1342 case SCTP_PRIMARY_ADDR:
1343 case SCTP_PEER_ADDR_PARAMS:
1345 * Association ID is the first element
1346 * params struct
1348 if (optlen < sizeof (sctp_assoc_t)) {
1349 error = EINVAL;
1350 eprintsoline(so, error);
1351 goto done;
1353 id = *(sctp_assoc_t *)optval;
1354 break;
1355 case SCTP_DEFAULT_SEND_PARAM:
1356 if (optlen != sizeof (struct sctp_sndrcvinfo)) {
1357 error = EINVAL;
1358 eprintsoline(so, error);
1359 goto done;
1361 id = ((struct sctp_sndrcvinfo *)
1362 optval)->sinfo_assoc_id;
1363 break;
1364 case SCTP_INITMSG:
1366 * Only applies to future associations
1368 conn = so->so_proto_handle;
1369 break;
1370 default:
1371 break;
1373 } else if (level == SOL_SOCKET) {
1374 if (option_name == SO_LINGER) {
1375 error = EOPNOTSUPP;
1376 eprintsoline(so, error);
1377 goto done;
1380 * These 2 options are applied to all associations.
1381 * The other socket level options are only applied
1382 * to the socket (not associations).
1384 if ((option_name != SO_RCVBUF) &&
1385 (option_name != SO_SNDBUF)) {
1386 conn = so->so_proto_handle;
1388 } else {
1389 conn = NULL;
1393 * If association ID was specified, do op on that assoc.
1394 * Otherwise set the default setting of a socket.
1396 if (id != 0) {
1397 if ((error = sosctp_assoc(ss, id, &ssa)) != 0) {
1398 eprintsoline(so, error);
1399 goto done;
1401 conn = ssa->ssa_conn;
1404 dprint(2, ("sosctp_setsockopt %p (%d) - conn %p %d %d id:%d\n",
1405 (void *)ss, so->so_type, (void *)conn, level, option_name, id));
1407 ASSERT(ssa == NULL || (ssa != NULL && conn != NULL));
1408 if (conn != NULL) {
1409 mutex_exit(&so->so_lock);
1410 error = sctp_set_opt((struct sctp_s *)conn, level, option_name,
1411 optval, optlen);
1412 mutex_enter(&so->so_lock);
1413 if (ssa != NULL)
1414 SSA_REFRELE(ss, ssa);
1415 } else {
1417 * 1-N socket, and we have to apply the operation to ALL
1418 * associations. Like with anything of this sort, the
1419 * problem is what to do if the operation fails.
1420 * Just try to apply the setting to everyone, but store
1421 * error number if someone returns such. And since we are
1422 * looping through all possible aids, some of them can be
1423 * invalid. We just ignore this kind (sosctp_assoc()) of
1424 * errors.
1426 sctp_assoc_t aid;
1428 mutex_exit(&so->so_lock);
1429 error = sctp_set_opt((struct sctp_s *)so->so_proto_handle,
1430 level, option_name, optval, optlen);
1431 mutex_enter(&so->so_lock);
1432 for (aid = 1; aid < ss->ss_maxassoc; aid++) {
1433 if (sosctp_assoc(ss, aid, &ssa) != 0)
1434 continue;
1435 mutex_exit(&so->so_lock);
1436 rc = sctp_set_opt((struct sctp_s *)ssa->ssa_conn, level,
1437 option_name, optval, optlen);
1438 mutex_enter(&so->so_lock);
1439 SSA_REFRELE(ss, ssa);
1440 if (error == 0) {
1441 error = rc;
1445 done:
1446 mutex_exit(&so->so_lock);
1447 return (error);
1450 /*ARGSUSED*/
1451 static int
1452 sosctp_ioctl(struct sonode *so, int cmd, intptr_t arg, int mode,
1453 struct cred *cr, int32_t *rvalp)
1455 struct sctp_sonode *ss;
1456 int32_t value;
1457 int error;
1458 int intval;
1459 pid_t pid;
1460 struct sctp_soassoc *ssa;
1461 void *conn;
1462 void *buf;
1463 STRUCT_DECL(sctpopt, opt);
1464 uint32_t optlen;
1465 int buflen;
1467 ss = SOTOSSO(so);
1469 /* handle socket specific ioctls */
1470 switch (cmd) {
1471 case FIONBIO:
1472 if (so_copyin((void *)arg, &value, sizeof (int32_t),
1473 (mode & (int)FKIOCTL))) {
1474 return (EFAULT);
1476 mutex_enter(&so->so_lock);
1477 if (value) {
1478 so->so_state |= SS_NDELAY;
1479 } else {
1480 so->so_state &= ~SS_NDELAY;
1482 mutex_exit(&so->so_lock);
1483 return (0);
1485 case FIOASYNC:
1486 if (so_copyin((void *)arg, &value, sizeof (int32_t),
1487 (mode & (int)FKIOCTL))) {
1488 return (EFAULT);
1490 mutex_enter(&so->so_lock);
1492 if (value) {
1493 /* Turn on SIGIO */
1494 so->so_state |= SS_ASYNC;
1495 } else {
1496 /* Turn off SIGIO */
1497 so->so_state &= ~SS_ASYNC;
1499 mutex_exit(&so->so_lock);
1500 return (0);
1502 case SIOCSPGRP:
1503 case FIOSETOWN:
1504 if (so_copyin((void *)arg, &pid, sizeof (pid_t),
1505 (mode & (int)FKIOCTL))) {
1506 return (EFAULT);
1508 mutex_enter(&so->so_lock);
1510 error = (pid != so->so_pgrp) ? socket_chgpgrp(so, pid) : 0;
1511 mutex_exit(&so->so_lock);
1512 return (error);
1514 case SIOCGPGRP:
1515 case FIOGETOWN:
1516 if (so_copyout(&so->so_pgrp, (void *)arg,
1517 sizeof (pid_t), (mode & (int)FKIOCTL)))
1518 return (EFAULT);
1519 return (0);
1521 case FIONREAD:
1522 /* XXX: Cannot be used unless standard buffer is used */
1524 * Return number of bytes of data in all data messages
1525 * in queue in "arg".
1526 * For stream socket, amount of available data.
1527 * For sock_dgram, # of available bytes + addresses.
1529 intval = (so->so_state & SS_ACCEPTCONN) ? 0 :
1530 MIN(so->so_rcv_queued, INT_MAX);
1531 if (so_copyout(&intval, (void *)arg, sizeof (intval),
1532 (mode & (int)FKIOCTL)))
1533 return (EFAULT);
1534 return (0);
1535 case SIOCATMARK:
1537 * No support for urgent data.
1539 intval = 0;
1541 if (so_copyout(&intval, (void *)arg, sizeof (int),
1542 (mode & (int)FKIOCTL)))
1543 return (EFAULT);
1544 return (0);
1545 case _I_GETPEERCRED: {
1546 int error = 0;
1548 if ((mode & FKIOCTL) == 0)
1549 return (EINVAL);
1551 mutex_enter(&so->so_lock);
1552 if ((so->so_mode & SM_CONNREQUIRED) == 0) {
1553 error = ENOTSUP;
1554 } else if ((so->so_state & SS_ISCONNECTED) == 0) {
1555 error = ENOTCONN;
1556 } else if (so->so_peercred != NULL) {
1557 k_peercred_t *kp = (k_peercred_t *)arg;
1558 kp->pc_cr = so->so_peercred;
1559 kp->pc_cpid = so->so_cpid;
1560 crhold(so->so_peercred);
1561 } else {
1562 error = EINVAL;
1564 mutex_exit(&so->so_lock);
1565 return (error);
1567 case SIOCSCTPGOPT:
1568 STRUCT_INIT(opt, mode);
1570 if (so_copyin((void *)arg, STRUCT_BUF(opt), STRUCT_SIZE(opt),
1571 (mode & (int)FKIOCTL))) {
1572 return (EFAULT);
1574 if ((optlen = STRUCT_FGET(opt, sopt_len)) > SO_MAXARGSIZE)
1575 return (EINVAL);
1578 * Find the correct sctp_t based on whether it is 1-N socket
1579 * or not.
1581 intval = STRUCT_FGET(opt, sopt_aid);
1582 mutex_enter(&so->so_lock);
1583 if ((so->so_type == SOCK_SEQPACKET) && intval) {
1584 if ((error = sosctp_assoc(ss, intval, &ssa)) != 0) {
1585 mutex_exit(&so->so_lock);
1586 return (error);
1588 conn = ssa->ssa_conn;
1589 ASSERT(conn != NULL);
1590 } else {
1591 conn = so->so_proto_handle;
1592 ssa = NULL;
1594 mutex_exit(&so->so_lock);
1596 /* Copyin the option buffer and then call sctp_get_opt(). */
1597 buflen = optlen;
1598 /* Let's allocate a buffer enough to hold an int */
1599 if (buflen < sizeof (uint32_t))
1600 buflen = sizeof (uint32_t);
1601 buf = kmem_alloc(buflen, KM_SLEEP);
1602 if (so_copyin(STRUCT_FGETP(opt, sopt_val), buf, optlen,
1603 (mode & (int)FKIOCTL))) {
1604 if (ssa != NULL) {
1605 mutex_enter(&so->so_lock);
1606 SSA_REFRELE(ss, ssa);
1607 mutex_exit(&so->so_lock);
1609 kmem_free(buf, buflen);
1610 return (EFAULT);
1612 /* The option level has to be IPPROTO_SCTP */
1613 error = sctp_get_opt((struct sctp_s *)conn, IPPROTO_SCTP,
1614 STRUCT_FGET(opt, sopt_name), buf, &optlen);
1615 if (ssa != NULL) {
1616 mutex_enter(&so->so_lock);
1617 SSA_REFRELE(ss, ssa);
1618 mutex_exit(&so->so_lock);
1620 optlen = MIN(buflen, optlen);
1621 /* No error, copyout the result with the correct buf len. */
1622 if (error == 0) {
1623 STRUCT_FSET(opt, sopt_len, optlen);
1624 if (so_copyout(STRUCT_BUF(opt), (void *)arg,
1625 STRUCT_SIZE(opt), (mode & (int)FKIOCTL))) {
1626 error = EFAULT;
1627 } else if (so_copyout(buf, STRUCT_FGETP(opt, sopt_val),
1628 optlen, (mode & (int)FKIOCTL))) {
1629 error = EFAULT;
1632 kmem_free(buf, buflen);
1633 return (error);
1635 case SIOCSCTPSOPT:
1636 STRUCT_INIT(opt, mode);
1638 if (so_copyin((void *)arg, STRUCT_BUF(opt), STRUCT_SIZE(opt),
1639 (mode & (int)FKIOCTL))) {
1640 return (EFAULT);
1642 if ((optlen = STRUCT_FGET(opt, sopt_len)) > SO_MAXARGSIZE)
1643 return (EINVAL);
1646 * Find the correct sctp_t based on whether it is 1-N socket
1647 * or not.
1649 intval = STRUCT_FGET(opt, sopt_aid);
1650 mutex_enter(&so->so_lock);
1651 if (intval != 0) {
1652 if ((error = sosctp_assoc(ss, intval, &ssa)) != 0) {
1653 mutex_exit(&so->so_lock);
1654 return (error);
1656 conn = ssa->ssa_conn;
1657 ASSERT(conn != NULL);
1658 } else {
1659 conn = so->so_proto_handle;
1660 ssa = NULL;
1662 mutex_exit(&so->so_lock);
1664 /* Copyin the option buffer and then call sctp_set_opt(). */
1665 buf = kmem_alloc(optlen, KM_SLEEP);
1666 if (so_copyin(STRUCT_FGETP(opt, sopt_val), buf, optlen,
1667 (mode & (int)FKIOCTL))) {
1668 if (ssa != NULL) {
1669 mutex_enter(&so->so_lock);
1670 SSA_REFRELE(ss, ssa);
1671 mutex_exit(&so->so_lock);
1673 kmem_free(buf, intval);
1674 return (EFAULT);
1676 /* The option level has to be IPPROTO_SCTP */
1677 error = sctp_set_opt((struct sctp_s *)conn, IPPROTO_SCTP,
1678 STRUCT_FGET(opt, sopt_name), buf, optlen);
1679 if (ssa) {
1680 mutex_enter(&so->so_lock);
1681 SSA_REFRELE(ss, ssa);
1682 mutex_exit(&so->so_lock);
1684 kmem_free(buf, optlen);
1685 return (error);
1687 case SIOCSCTPPEELOFF: {
1688 struct sonode *nso;
1689 struct sctp_uc_swap us;
1690 int nfd;
1691 struct file *nfp;
1692 struct vnode *nvp = NULL;
1693 struct sockparams *sp;
1695 dprint(2, ("sctppeeloff %p\n", (void *)ss));
1697 if (so->so_type != SOCK_SEQPACKET) {
1698 return (EOPNOTSUPP);
1700 if (so_copyin((void *)arg, &intval, sizeof (intval),
1701 (mode & (int)FKIOCTL))) {
1702 return (EFAULT);
1704 if (intval == 0) {
1705 return (EINVAL);
1709 * Find sockparams. This is different from parent's entry,
1710 * as the socket type is different.
1712 error = solookup(so->so_family, SOCK_STREAM, so->so_protocol,
1713 &sp);
1714 if (error != 0)
1715 return (error);
1718 * Allocate the user fd.
1720 if ((nfd = ufalloc(0)) == -1) {
1721 eprintsoline(so, EMFILE);
1722 return (EMFILE);
1726 * Copy the fd out.
1728 if (so_copyout(&nfd, (void *)arg, sizeof (nfd),
1729 (mode & (int)FKIOCTL))) {
1730 error = EFAULT;
1731 goto err;
1733 mutex_enter(&so->so_lock);
1736 * Don't use sosctp_assoc() in order to peel off disconnected
1737 * associations.
1739 ssa = ((uint32_t)intval >= ss->ss_maxassoc) ? NULL :
1740 ss->ss_assocs[intval].ssi_assoc;
1741 if (ssa == NULL) {
1742 mutex_exit(&so->so_lock);
1743 error = EINVAL;
1744 goto err;
1746 SSA_REFHOLD(ssa);
1748 nso = socksctp_create(sp, so->so_family, SOCK_STREAM,
1749 so->so_protocol, so->so_version, SOCKET_NOSLEEP,
1750 &error, cr);
1751 if (nso == NULL) {
1752 SSA_REFRELE(ss, ssa);
1753 mutex_exit(&so->so_lock);
1754 goto err;
1756 nvp = SOTOV(nso);
1757 so_lock_single(so);
1758 mutex_exit(&so->so_lock);
1760 /* cannot fail, only inheriting properties */
1761 (void) sosctp_init(nso, so, CRED(), 0);
1764 * We have a single ref on the new socket. This is normally
1765 * handled by socket_{create,newconn}, but since they are not
1766 * used we have to do it here.
1768 nso->so_count = 1;
1770 us.sus_handle = nso;
1771 us.sus_upcalls = &sosctp_sock_upcalls;
1774 * Upcalls to new socket are blocked for the duration of
1775 * downcall.
1777 mutex_enter(&nso->so_lock);
1779 error = sctp_set_opt((struct sctp_s *)ssa->ssa_conn,
1780 IPPROTO_SCTP, SCTP_UC_SWAP, &us, sizeof (us));
1781 if (error) {
1782 goto peelerr;
1784 error = falloc(nvp, FWRITE|FREAD, &nfp, NULL);
1785 if (error) {
1786 goto peelerr;
1790 * fill in the entries that falloc reserved
1792 nfp->f_vnode = nvp;
1793 mutex_exit(&nfp->f_tlock);
1794 setf(nfd, nfp);
1796 mutex_enter(&so->so_lock);
1798 sosctp_assoc_move(ss, SOTOSSO(nso), ssa);
1800 mutex_exit(&nso->so_lock);
1802 ssa->ssa_conn = NULL;
1803 sosctp_assoc_free(ss, ssa);
1805 so_unlock_single(so, SOLOCKED);
1806 mutex_exit(&so->so_lock);
1808 return (0);
1810 err:
1811 setf(nfd, NULL);
1812 eprintsoline(so, error);
1813 return (error);
1815 peelerr:
1816 mutex_exit(&nso->so_lock);
1817 mutex_enter(&so->so_lock);
1818 ASSERT(nso->so_count == 1);
1819 nso->so_count = 0;
1820 so_unlock_single(so, SOLOCKED);
1821 SSA_REFRELE(ss, ssa);
1822 mutex_exit(&so->so_lock);
1824 setf(nfd, NULL);
1825 ASSERT(nvp->v_count == 1);
1826 socket_destroy(nso);
1827 eprintsoline(so, error);
1828 return (error);
1830 default:
1831 return (EINVAL);
1835 /*ARGSUSED*/
1836 static int
1837 sosctp_close(struct sonode *so, int flag, struct cred *cr)
1839 struct sctp_sonode *ss;
1840 struct sctp_sa_id *ssi;
1841 struct sctp_soassoc *ssa;
1842 int32_t i;
1844 ss = SOTOSSO(so);
1847 * Initiate connection shutdown. Update SCTP's receive
1848 * window.
1850 sctp_recvd((struct sctp_s *)so->so_proto_handle,
1851 so->so_rcvbuf - so->so_rcv_queued);
1852 (void) sctp_disconnect((struct sctp_s *)so->so_proto_handle);
1855 * New associations can't come in, but old ones might get
1856 * closed in upcall. Protect against that by taking a reference
1857 * on the association.
1859 mutex_enter(&so->so_lock);
1860 ssi = ss->ss_assocs;
1861 for (i = 0; i < ss->ss_maxassoc; i++, ssi++) {
1862 if ((ssa = ssi->ssi_assoc) != NULL) {
1863 SSA_REFHOLD(ssa);
1864 sosctp_assoc_isdisconnected(ssa, 0);
1865 mutex_exit(&so->so_lock);
1867 sctp_recvd((struct sctp_s *)ssa->ssa_conn,
1868 so->so_rcvbuf - ssa->ssa_rcv_queued);
1869 (void) sctp_disconnect((struct sctp_s *)ssa->ssa_conn);
1871 mutex_enter(&so->so_lock);
1872 SSA_REFRELE(ss, ssa);
1875 mutex_exit(&so->so_lock);
1877 return (0);
1881 * Closes incoming connections which were never accepted, frees
1882 * resources.
1884 /* ARGSUSED */
1885 void
1886 sosctp_fini(struct sonode *so, struct cred *cr)
1888 struct sctp_sonode *ss;
1889 struct sctp_sa_id *ssi;
1890 struct sctp_soassoc *ssa;
1891 int32_t i;
1893 ss = SOTOSSO(so);
1895 ASSERT(so->so_ops == &sosctp_sonodeops ||
1896 so->so_ops == &sosctp_seq_sonodeops);
1898 /* We are the sole owner of so now */
1899 mutex_enter(&so->so_lock);
1901 so_rcv_flush(so);
1903 /* Free all pending connections */
1904 so_acceptq_flush(so);
1906 ssi = ss->ss_assocs;
1907 for (i = 0; i < ss->ss_maxassoc; i++, ssi++) {
1908 if ((ssa = ssi->ssi_assoc) != NULL) {
1909 SSA_REFHOLD(ssa);
1910 mutex_exit(&so->so_lock);
1912 sctp_close((struct sctp_s *)ssa->ssa_conn);
1914 mutex_enter(&so->so_lock);
1915 ssa->ssa_conn = NULL;
1916 sosctp_assoc_free(ss, ssa);
1919 if (ss->ss_assocs != NULL) {
1920 ASSERT(ss->ss_assoccnt == 0);
1921 kmem_free(ss->ss_assocs,
1922 ss->ss_maxassoc * sizeof (struct sctp_sa_id));
1924 mutex_exit(&so->so_lock);
1926 if (so->so_proto_handle)
1927 sctp_close((struct sctp_s *)so->so_proto_handle);
1928 so->so_proto_handle = NULL;
1930 sonode_fini(so);
1934 * Upcalls from SCTP
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.
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)
1951 struct sonode *lso = (struct sonode *)parenthandle;
1952 struct sctp_sonode *lss = SOTOSSO(lso);
1953 struct sctp_soassoc *ssa;
1954 sctp_assoc_t id;
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);
1961 mutex_enter(&lso->so_lock);
1963 if ((id = sosctp_aid_get(lss)) == -1) {
1965 * Array not large enough; increase size.
1967 if (sosctp_aid_grow(lss, lss->ss_maxassoc, KM_NOSLEEP) < 0) {
1968 mutex_exit(&lso->so_lock);
1969 return (NULL);
1971 id = sosctp_aid_get(lss);
1972 ASSERT(id != -1);
1976 * Create soassoc for this connection
1978 ssa = sosctp_assoc_create(lss, KM_NOSLEEP);
1979 if (ssa == NULL) {
1980 mutex_exit(&lso->so_lock);
1981 return (NULL);
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;
1992 mutex_exit(&lso->so_lock);
1994 *ucp = &sosctp_assoc_upcalls;
1996 return ((sock_upper_handle_t)ssa);
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)
2004 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2005 struct sonode *so = &ssa->ssa_sonode->ss_so;
2007 ASSERT(so->so_type == SOCK_SEQPACKET);
2008 ASSERT(ssa->ssa_conn);
2010 mutex_enter(&so->so_lock);
2011 sosctp_assoc_isconnected(ssa);
2012 mutex_exit(&so->so_lock);
2015 /* ARGSUSED */
2016 static int
2017 sctp_assoc_disconnected(sock_upper_handle_t handle, sock_connid_t id, int error)
2019 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2020 struct sonode *so = &ssa->ssa_sonode->ss_so;
2021 int ret;
2023 ASSERT(so->so_type == SOCK_SEQPACKET);
2024 ASSERT(ssa->ssa_conn != NULL);
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;
2034 SSA_REFRELE(SOTOSSO(so), ssa);
2036 cv_broadcast(&so->so_snd_cv);
2038 mutex_exit(&so->so_lock);
2040 return (ret);
2043 /* ARGSUSED */
2044 static void
2045 sctp_assoc_disconnecting(sock_upper_handle_t handle, sock_opctl_action_t action,
2046 uintptr_t arg)
2048 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2049 struct sonode *so = &ssa->ssa_sonode->ss_so;
2051 ASSERT(so->so_type == SOCK_SEQPACKET);
2052 ASSERT(ssa->ssa_conn != NULL);
2053 ASSERT(action == SOCK_OPCTL_SHUT_SEND);
2055 mutex_enter(&so->so_lock);
2056 sosctp_assoc_isdisconnecting(ssa);
2057 mutex_exit(&so->so_lock);
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)
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;
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);
2079 ASSERT(errorp != NULL);
2080 *errorp = 0;
2083 * Should be getting T_unitdata_req's only.
2084 * Must have address as part of packet.
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);
2091 mutex_enter(&so->so_lock);
2094 * For notify messages, need to fill in association id.
2095 * For data messages, sndrcvinfo could be in ancillary data.
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;
2126 } else {
2127 if (tind->OPT_length > 0) {
2128 struct cmsghdr *cmsg;
2129 char *cend;
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;
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;
2146 if (cmsg->cmsg_len > 0) {
2147 cmsg = (struct cmsghdr *)
2148 ((uchar_t *)cmsg + cmsg->cmsg_len);
2149 } else {
2150 break;
2157 * SCTP has reserved space in the header for storing a pointer.
2158 * Put the pointer to assocation there, and queue the data.
2160 SSA_REFHOLD(ssa);
2161 ASSERT((mp->b_rptr - DB_BASE(mp)) >= sizeof (ssa));
2162 *(struct sctp_soassoc **)DB_BASE(mp) = ssa;
2164 ssa->ssa_rcv_queued += len;
2165 space_available = so->so_rcvbuf - ssa->ssa_rcv_queued;
2166 so_enqueue_msg(so, mp, len);
2168 /* so_notify_data drops so_lock */
2169 so_notify_data(so, len);
2171 return (space_available);
2174 static void
2175 sctp_assoc_xmitted(sock_upper_handle_t handle, boolean_t qfull)
2177 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2178 struct sctp_sonode *ss = ssa->ssa_sonode;
2180 ASSERT(ssa->ssa_type == SOSCTP_ASSOC);
2181 ASSERT(ss->ss_so.so_type == SOCK_SEQPACKET);
2182 ASSERT(ssa->ssa_conn != NULL);
2184 mutex_enter(&ss->ss_so.so_lock);
2186 ssa->ssa_snd_qfull = qfull;
2189 * Wake blocked writers.
2191 cv_broadcast(&ss->ss_so.so_snd_cv);
2193 mutex_exit(&ss->ss_so.so_lock);
2196 static void
2197 sctp_assoc_properties(sock_upper_handle_t handle,
2198 struct sock_proto_props *soppp)
2200 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2201 struct sctp_sonode *ss;
2203 if (ssa->ssa_type == SOSCTP_ASSOC) {
2204 ss = ssa->ssa_sonode;
2205 mutex_enter(&ss->ss_so.so_lock);
2208 * Only change them if they're set.
2210 if (soppp->sopp_wroff != 0) {
2211 ssa->ssa_wroff = soppp->sopp_wroff;
2213 if (soppp->sopp_maxblk != 0) {
2214 ssa->ssa_wrsize = soppp->sopp_maxblk;
2216 } else {
2217 ss = (struct sctp_sonode *)handle;
2218 mutex_enter(&ss->ss_so.so_lock);
2220 if (soppp->sopp_wroff != 0) {
2221 ss->ss_wroff = soppp->sopp_wroff;
2223 if (soppp->sopp_maxblk != 0) {
2224 ss->ss_wrsize = soppp->sopp_maxblk;
2228 mutex_exit(&ss->ss_so.so_lock);