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