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