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