socksctp.c revision 8348:4137e18bfaf0
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 2008 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 */ 60static int sosctp_init(struct sonode *, struct sonode *, struct cred *, int); 61static int sosctp_accept(struct sonode *, int, struct cred *, struct sonode **); 62static int sosctp_bind(struct sonode *, struct sockaddr *, socklen_t, int, 63 struct cred *); 64static int sosctp_listen(struct sonode *, int, struct cred *); 65static int sosctp_connect(struct sonode *, const struct sockaddr *, socklen_t, 66 int, int, struct cred *); 67static int sosctp_recvmsg(struct sonode *, struct nmsghdr *, struct uio *, 68 struct cred *); 69static int sosctp_sendmsg(struct sonode *, struct nmsghdr *, struct uio *, 70 struct cred *); 71static int sosctp_getpeername(struct sonode *, struct sockaddr *, socklen_t *, 72 boolean_t, struct cred *); 73static int sosctp_getsockname(struct sonode *, struct sockaddr *, socklen_t *, 74 struct cred *); 75static int sosctp_shutdown(struct sonode *, int, struct cred *); 76static int sosctp_getsockopt(struct sonode *, int, int, void *, socklen_t *, 77 int, struct cred *); 78static int sosctp_setsockopt(struct sonode *, int, int, const void *, 79 socklen_t, struct cred *); 80static int sosctp_ioctl(struct sonode *, int, intptr_t, int, struct cred *, 81 int32_t *); 82static int sosctp_close(struct sonode *, int, struct cred *); 83void sosctp_fini(struct sonode *, struct cred *); 84 85/* 86 * SCTP sockfs sonode operations, 1-N socket 87 */ 88static int sosctp_seq_connect(struct sonode *, const struct sockaddr *, 89 socklen_t, int, int, struct cred *); 90static int sosctp_seq_sendmsg(struct sonode *, struct nmsghdr *, struct uio *, 91 struct cred *); 92 93/* 94 * Socket association upcalls, 1-N socket connection 95 */ 96sock_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 **); 99static void sctp_assoc_connected(sock_upper_handle_t, sock_connid_t, 100 struct cred *, pid_t); 101static int sctp_assoc_disconnected(sock_upper_handle_t, sock_connid_t, int); 102static void sctp_assoc_disconnecting(sock_upper_handle_t, sock_opctl_action_t, 103 uintptr_t arg); 104static ssize_t sctp_assoc_recv(sock_upper_handle_t, mblk_t *, size_t, int, 105 int *, boolean_t *); 106static void sctp_assoc_xmitted(sock_upper_handle_t, boolean_t); 107static void sctp_assoc_properties(sock_upper_handle_t, 108 struct sock_proto_props *); 109 110sonodeops_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 129sonodeops_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 148sock_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 159sock_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 */ 172static int 173sosctp_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*/ 226static int 227sosctp_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*/ 244static int 245sosctp_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 } 279done: 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 */ 296static int 297sosctp_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 } 337done: 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*/ 348static int 349sosctp_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 } 416done: 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 */ 428static int 429sosctp_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 460done: 461 so_unlock_single(so, SOLOCKED); 462 mutex_exit(&so->so_lock); 463 return (error); 464} 465 466/* 467 * Receive data. 468 */ 469/* ARGSUSED */ 470static int 471sosctp_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); 547again: 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 } 591done: 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 655int 656sosctp_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)) == NULL) { 676 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) || 677 (flags & MSG_DONTWAIT)) { 678 return (EAGAIN); 679 } 680 if ((error = strwaitbuf(size + wroff, BPRI_MED))) { 681 return (error); 682 } 683 } 684 685 dp = mp->b_datap; 686 dp->db_cpid = curproc->p_pid; 687 ASSERT(wroff <= dp->db_lim - mp->b_wptr); 688 mp->b_rptr += wroff; 689 error = uiomove(mp->b_rptr, size, UIO_WRITE, uiop); 690 if (error != 0) { 691 freeb(mp); 692 return (error); 693 } 694 mp->b_wptr = mp->b_rptr + size; 695 count -= size; 696 hdr_mp->b_cont = mp; 697 hdr_mp = mp; 698 } 699 return (0); 700} 701 702/* 703 * Send message. 704 */ 705static int 706sosctp_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop, 707 struct cred *cr) 708{ 709 struct sctp_sonode *ss = SOTOSSO(so); 710 mblk_t *mctl; 711 struct cmsghdr *cmsg; 712 struct sctp_sndrcvinfo *sinfo; 713 int optlen, flags, fflag; 714 ssize_t count, msglen; 715 int error; 716 717 ASSERT(so->so_type == SOCK_STREAM); 718 719 flags = msg->msg_flags; 720 if (flags & MSG_OOB) { 721 /* 722 * No out-of-band data support. 723 */ 724 return (EOPNOTSUPP); 725 } 726 727 if (msg->msg_controllen != 0) { 728 optlen = msg->msg_controllen; 729 cmsg = sosctp_find_cmsg(msg->msg_control, optlen, SCTP_SNDRCV); 730 if (cmsg != NULL) { 731 if (cmsg->cmsg_len < 732 (sizeof (*sinfo) + sizeof (*cmsg))) { 733 eprintsoline(so, EINVAL); 734 return (EINVAL); 735 } 736 sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1); 737 738 /* Both flags should not be set together. */ 739 if ((sinfo->sinfo_flags & MSG_EOF) && 740 (sinfo->sinfo_flags & MSG_ABORT)) { 741 eprintsoline(so, EINVAL); 742 return (EINVAL); 743 } 744 745 /* Initiate a graceful shutdown. */ 746 if (sinfo->sinfo_flags & MSG_EOF) { 747 /* Can't include data in MSG_EOF message. */ 748 if (uiop->uio_resid != 0) { 749 eprintsoline(so, EINVAL); 750 return (EINVAL); 751 } 752 753 /* 754 * This is the same sequence as done in 755 * shutdown(SHUT_WR). 756 */ 757 mutex_enter(&so->so_lock); 758 so_lock_single(so); 759 socantsendmore(so); 760 cv_broadcast(&so->so_snd_cv); 761 so->so_state |= SS_ISDISCONNECTING; 762 mutex_exit(&so->so_lock); 763 764 pollwakeup(&so->so_poll_list, POLLOUT); 765 sctp_recvd((struct sctp_s *)so->so_proto_handle, 766 so->so_rcvbuf); 767 error = sctp_disconnect( 768 (struct sctp_s *)so->so_proto_handle); 769 770 mutex_enter(&so->so_lock); 771 so_unlock_single(so, SOLOCKED); 772 mutex_exit(&so->so_lock); 773 return (error); 774 } 775 } 776 } else { 777 optlen = 0; 778 } 779 780 mutex_enter(&so->so_lock); 781 for (;;) { 782 if (so->so_state & SS_CANTSENDMORE) { 783 mutex_exit(&so->so_lock); 784 return (EPIPE); 785 } 786 787 if (so->so_error != 0) { 788 error = sogeterr(so, B_TRUE); 789 mutex_exit(&so->so_lock); 790 return (error); 791 } 792 793 if (!so->so_snd_qfull) 794 break; 795 796 if (so->so_state & SS_CLOSING) { 797 mutex_exit(&so->so_lock); 798 return (EINTR); 799 } 800 /* 801 * Xmit window full in a blocking socket. 802 */ 803 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) || 804 (flags & MSG_DONTWAIT)) { 805 mutex_exit(&so->so_lock); 806 return (EAGAIN); 807 } else { 808 /* 809 * Wait for space to become available and try again. 810 */ 811 error = cv_wait_sig(&so->so_snd_cv, &so->so_lock); 812 if (!error) { /* signal */ 813 mutex_exit(&so->so_lock); 814 return (EINTR); 815 } 816 } 817 } 818 msglen = count = uiop->uio_resid; 819 820 /* Don't allow sending a message larger than the send buffer size. */ 821 /* XXX Transport module need to enforce this */ 822 if (msglen > so->so_sndbuf) { 823 mutex_exit(&so->so_lock); 824 return (EMSGSIZE); 825 } 826 827 /* 828 * Allow piggybacking data on handshake messages (SS_ISCONNECTING). 829 */ 830 if (!(so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED))) { 831 /* 832 * We need to check here for listener so that the 833 * same error will be returned as with a TCP socket. 834 * In this case, sosctp_connect() returns EOPNOTSUPP 835 * while a TCP socket returns ENOTCONN instead. Catch it 836 * here to have the same behavior as a TCP socket. 837 * 838 * We also need to make sure that the peer address is 839 * provided before we attempt to do the connect. 840 */ 841 if ((so->so_state & SS_ACCEPTCONN) || 842 msg->msg_name == NULL) { 843 mutex_exit(&so->so_lock); 844 error = ENOTCONN; 845 goto error_nofree; 846 } 847 mutex_exit(&so->so_lock); 848 fflag = uiop->uio_fmode; 849 if (flags & MSG_DONTWAIT) { 850 fflag |= FNDELAY; 851 } 852 error = sosctp_connect(so, msg->msg_name, msg->msg_namelen, 853 fflag, (so->so_version == SOV_XPG4_2) * _SOCONNECT_XPG4_2, 854 cr); 855 if (error) { 856 /* 857 * Check for non-fatal errors, socket connected 858 * while the lock had been lifted. 859 */ 860 if (error != EISCONN && error != EALREADY) { 861 goto error_nofree; 862 } 863 error = 0; 864 } 865 } else { 866 mutex_exit(&so->so_lock); 867 } 868 869 mctl = sctp_alloc_hdr(msg->msg_name, msg->msg_namelen, 870 msg->msg_control, optlen, SCTP_CAN_BLOCK); 871 if (mctl == NULL) { 872 error = EINTR; 873 goto error_nofree; 874 } 875 876 /* Copy in the message. */ 877 if ((error = sosctp_uiomove(mctl, count, ss->ss_wrsize, ss->ss_wroff, 878 uiop, flags, cr)) != 0) { 879 goto error_ret; 880 } 881 error = sctp_sendmsg((struct sctp_s *)so->so_proto_handle, mctl, 0); 882 if (error == 0) 883 return (0); 884 885error_ret: 886 freemsg(mctl); 887error_nofree: 888 mutex_enter(&so->so_lock); 889 if ((error == EPIPE) && (so->so_state & SS_CANTSENDMORE)) { 890 /* 891 * We received shutdown between the time lock was 892 * lifted and call to sctp_sendmsg(). 893 */ 894 mutex_exit(&so->so_lock); 895 return (EPIPE); 896 } 897 mutex_exit(&so->so_lock); 898 return (error); 899} 900 901/* 902 * Send message on 1-N socket. Connects automatically if there is 903 * no association. 904 */ 905static int 906sosctp_seq_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop, 907 struct cred *cr) 908{ 909 struct sctp_sonode *ss; 910 struct sctp_soassoc *ssa; 911 struct cmsghdr *cmsg; 912 struct sctp_sndrcvinfo *sinfo; 913 int aid = 0; 914 mblk_t *mctl; 915 int namelen, optlen, flags; 916 ssize_t count, msglen; 917 int error; 918 uint16_t s_flags = 0; 919 920 ASSERT(so->so_type == SOCK_SEQPACKET); 921 922 /* 923 * There shouldn't be problems with alignment, as the memory for 924 * msg_control was alloced with kmem_alloc. 925 */ 926 cmsg = sosctp_find_cmsg(msg->msg_control, msg->msg_controllen, 927 SCTP_SNDRCV); 928 if (cmsg != NULL) { 929 if (cmsg->cmsg_len < (sizeof (*sinfo) + sizeof (*cmsg))) { 930 eprintsoline(so, EINVAL); 931 return (EINVAL); 932 } 933 sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1); 934 s_flags = sinfo->sinfo_flags; 935 aid = sinfo->sinfo_assoc_id; 936 } 937 938 ss = SOTOSSO(so); 939 namelen = msg->msg_namelen; 940 941 if (msg->msg_controllen > 0) { 942 optlen = msg->msg_controllen; 943 } else { 944 optlen = 0; 945 } 946 947 mutex_enter(&so->so_lock); 948 949 /* 950 * If there is no association id, connect to address specified 951 * in msg_name. Otherwise look up the association using the id. 952 */ 953 if (aid == 0) { 954 /* 955 * Connect and shutdown cannot be done together, so check for 956 * MSG_EOF. 957 */ 958 if (msg->msg_name == NULL || namelen == 0 || 959 (s_flags & MSG_EOF)) { 960 error = EINVAL; 961 eprintsoline(so, error); 962 goto done; 963 } 964 flags = uiop->uio_fmode; 965 if (msg->msg_flags & MSG_DONTWAIT) { 966 flags |= FNDELAY; 967 } 968 so_lock_single(so); 969 error = sosctp_assoc_createconn(ss, msg->msg_name, namelen, 970 msg->msg_control, optlen, flags, cr, &ssa); 971 if (error) { 972 if ((so->so_version == SOV_XPG4_2) && 973 (error == EHOSTUNREACH)) { 974 error = ENETUNREACH; 975 } 976 if (ssa == NULL) { 977 /* 978 * Fatal error during connect(). Bail out. 979 * If ssa exists, it means that the handshake 980 * is in progress. 981 */ 982 eprintsoline(so, error); 983 so_unlock_single(so, SOLOCKED); 984 goto done; 985 } 986 /* 987 * All the errors are non-fatal ones, don't return 988 * e.g. EINPROGRESS from sendmsg(). 989 */ 990 error = 0; 991 } 992 so_unlock_single(so, SOLOCKED); 993 } else { 994 if ((error = sosctp_assoc(ss, aid, &ssa)) != 0) { 995 eprintsoline(so, error); 996 goto done; 997 } 998 } 999 1000 /* 1001 * Now we have an association. 1002 */ 1003 flags = msg->msg_flags; 1004 1005 /* 1006 * MSG_EOF initiates graceful shutdown. 1007 */ 1008 if (s_flags & MSG_EOF) { 1009 if (uiop->uio_resid) { 1010 /* 1011 * Can't include data in MSG_EOF message. 1012 */ 1013 error = EINVAL; 1014 } else { 1015 mutex_exit(&so->so_lock); 1016 ssa->ssa_state |= SS_ISDISCONNECTING; 1017 sctp_recvd((struct sctp_s *)ssa->ssa_conn, 1018 so->so_rcvbuf); 1019 error = sctp_disconnect((struct sctp_s *)ssa->ssa_conn); 1020 mutex_enter(&so->so_lock); 1021 } 1022 goto refrele; 1023 } 1024 1025 for (;;) { 1026 if (ssa->ssa_state & SS_CANTSENDMORE) { 1027 SSA_REFRELE(ss, ssa); 1028 mutex_exit(&so->so_lock); 1029 return (EPIPE); 1030 } 1031 if (ssa->ssa_error != 0) { 1032 error = ssa->ssa_error; 1033 ssa->ssa_error = 0; 1034 goto refrele; 1035 } 1036 1037 if (!ssa->ssa_snd_qfull) 1038 break; 1039 1040 if (so->so_state & SS_CLOSING) { 1041 error = EINTR; 1042 goto refrele; 1043 } 1044 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) || 1045 (flags & MSG_DONTWAIT)) { 1046 error = EAGAIN; 1047 goto refrele; 1048 } else { 1049 /* 1050 * Wait for space to become available and try again. 1051 */ 1052 error = cv_wait_sig(&so->so_snd_cv, &so->so_lock); 1053 if (!error) { /* signal */ 1054 error = EINTR; 1055 goto refrele; 1056 } 1057 } 1058 } 1059 1060 msglen = count = uiop->uio_resid; 1061 1062 /* Don't allow sending a message larger than the send buffer size. */ 1063 if (msglen > so->so_sndbuf) { 1064 error = EMSGSIZE; 1065 goto refrele; 1066 } 1067 1068 /* 1069 * Update TX buffer usage here so that we can lift the socket lock. 1070 */ 1071 mutex_exit(&so->so_lock); 1072 1073 mctl = sctp_alloc_hdr(msg->msg_name, namelen, msg->msg_control, 1074 optlen, SCTP_CAN_BLOCK); 1075 if (mctl == NULL) { 1076 error = EINTR; 1077 goto lock_rele; 1078 } 1079 1080 /* Copy in the message. */ 1081 if ((error = sosctp_uiomove(mctl, count, ssa->ssa_wrsize, 1082 ssa->ssa_wroff, uiop, flags, cr)) != 0) { 1083 goto lock_rele; 1084 } 1085 error = sctp_sendmsg((struct sctp_s *)ssa->ssa_conn, mctl, 0); 1086lock_rele: 1087 mutex_enter(&so->so_lock); 1088 if (error != 0) { 1089 freemsg(mctl); 1090 if ((error == EPIPE) && (ssa->ssa_state & SS_CANTSENDMORE)) { 1091 /* 1092 * We received shutdown between the time lock was 1093 * lifted and call to sctp_sendmsg(). 1094 */ 1095 SSA_REFRELE(ss, ssa); 1096 mutex_exit(&so->so_lock); 1097 return (EPIPE); 1098 } 1099 } 1100 1101refrele: 1102 SSA_REFRELE(ss, ssa); 1103done: 1104 mutex_exit(&so->so_lock); 1105 return (error); 1106} 1107 1108/* 1109 * Get address of remote node. 1110 */ 1111/* ARGSUSED */ 1112static int 1113sosctp_getpeername(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen, 1114 boolean_t accept, struct cred *cr) 1115{ 1116 return (sctp_getpeername((struct sctp_s *)so->so_proto_handle, addr, 1117 addrlen)); 1118} 1119 1120/* 1121 * Get local address. 1122 */ 1123/* ARGSUSED */ 1124static int 1125sosctp_getsockname(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen, 1126 struct cred *cr) 1127{ 1128 return (sctp_getsockname((struct sctp_s *)so->so_proto_handle, addr, 1129 addrlen)); 1130} 1131 1132/* 1133 * Called from shutdown(). 1134 */ 1135/* ARGSUSED */ 1136static int 1137sosctp_shutdown(struct sonode *so, int how, struct cred *cr) 1138{ 1139 uint_t state_change; 1140 int wakesig = 0; 1141 int error = 0; 1142 1143 mutex_enter(&so->so_lock); 1144 /* 1145 * Record the current state and then perform any state changes. 1146 * Then use the difference between the old and new states to 1147 * determine which needs to be done. 1148 */ 1149 state_change = so->so_state; 1150 1151 switch (how) { 1152 case SHUT_RD: 1153 socantrcvmore(so); 1154 break; 1155 case SHUT_WR: 1156 socantsendmore(so); 1157 break; 1158 case SHUT_RDWR: 1159 socantsendmore(so); 1160 socantrcvmore(so); 1161 break; 1162 default: 1163 mutex_exit(&so->so_lock); 1164 return (EINVAL); 1165 } 1166 1167 state_change = so->so_state & ~state_change; 1168 1169 if (state_change & SS_CANTRCVMORE) { 1170 if (so->so_rcv_q_head == NULL) { 1171 cv_signal(&so->so_rcv_cv); 1172 } 1173 wakesig = POLLIN|POLLRDNORM; 1174 1175 socket_sendsig(so, SOCKETSIG_READ); 1176 } 1177 if (state_change & SS_CANTSENDMORE) { 1178 cv_broadcast(&so->so_snd_cv); 1179 wakesig |= POLLOUT; 1180 1181 so->so_state |= SS_ISDISCONNECTING; 1182 } 1183 mutex_exit(&so->so_lock); 1184 1185 pollwakeup(&so->so_poll_list, wakesig); 1186 1187 if (state_change & SS_CANTSENDMORE) { 1188 sctp_recvd((struct sctp_s *)so->so_proto_handle, so->so_rcvbuf); 1189 error = sctp_disconnect((struct sctp_s *)so->so_proto_handle); 1190 } 1191 1192 /* 1193 * HACK: sctp_disconnect() may return EWOULDBLOCK. But this error is 1194 * not documented in standard socket API. Catch it here. 1195 */ 1196 if (error == EWOULDBLOCK) 1197 error = 0; 1198 return (error); 1199} 1200 1201/* 1202 * Get socket options. 1203 */ 1204/*ARGSUSED5*/ 1205static int 1206sosctp_getsockopt(struct sonode *so, int level, int option_name, 1207 void *optval, socklen_t *optlenp, int flags, struct cred *cr) 1208{ 1209 if (level == IPPROTO_SCTP) { 1210 /* 1211 * Should go through ioctl(). 1212 */ 1213 return (EINVAL); 1214 } 1215 return (sctp_get_opt((struct sctp_s *)so->so_proto_handle, level, 1216 option_name, optval, optlenp)); 1217} 1218 1219/* 1220 * Set socket options 1221 */ 1222/* ARGSUSED */ 1223static int 1224sosctp_setsockopt(struct sonode *so, int level, int option_name, 1225 const void *optval, t_uscalar_t optlen, struct cred *cr) 1226{ 1227 struct sctp_sonode *ss = SOTOSSO(so); 1228 struct sctp_soassoc *ssa = NULL; 1229 sctp_assoc_t id; 1230 int error, rc; 1231 void *conn = NULL; 1232 1233 mutex_enter(&so->so_lock); 1234 1235 /* 1236 * For some SCTP level options, one can select the association this 1237 * applies to. 1238 */ 1239 if (so->so_type == SOCK_STREAM) { 1240 conn = so->so_proto_handle; 1241 } else { 1242 /* 1243 * SOCK_SEQPACKET only 1244 */ 1245 id = 0; 1246 if (level == IPPROTO_SCTP) { 1247 switch (option_name) { 1248 case SCTP_RTOINFO: 1249 case SCTP_ASSOCINFO: 1250 case SCTP_SET_PEER_PRIMARY_ADDR: 1251 case SCTP_PRIMARY_ADDR: 1252 case SCTP_PEER_ADDR_PARAMS: 1253 /* 1254 * Association ID is the first element 1255 * params struct 1256 */ 1257 if (optlen < sizeof (sctp_assoc_t)) { 1258 error = EINVAL; 1259 eprintsoline(so, error); 1260 goto done; 1261 } 1262 id = *(sctp_assoc_t *)optval; 1263 break; 1264 case SCTP_DEFAULT_SEND_PARAM: 1265 if (optlen != sizeof (struct sctp_sndrcvinfo)) { 1266 error = EINVAL; 1267 eprintsoline(so, error); 1268 goto done; 1269 } 1270 id = ((struct sctp_sndrcvinfo *) 1271 optval)->sinfo_assoc_id; 1272 break; 1273 case SCTP_INITMSG: 1274 /* 1275 * Only applies to future associations 1276 */ 1277 conn = so->so_proto_handle; 1278 break; 1279 default: 1280 break; 1281 } 1282 } else if (level == SOL_SOCKET) { 1283 if (option_name == SO_LINGER) { 1284 error = EOPNOTSUPP; 1285 eprintsoline(so, error); 1286 goto done; 1287 } 1288 /* 1289 * These 2 options are applied to all associations. 1290 * The other socket level options are only applied 1291 * to the socket (not associations). 1292 */ 1293 if ((option_name != SO_RCVBUF) && 1294 (option_name != SO_SNDBUF)) { 1295 conn = so->so_proto_handle; 1296 } 1297 } else { 1298 conn = NULL; 1299 } 1300 1301 /* 1302 * If association ID was specified, do op on that assoc. 1303 * Otherwise set the default setting of a socket. 1304 */ 1305 if (id != 0) { 1306 if ((error = sosctp_assoc(ss, id, &ssa)) != 0) { 1307 eprintsoline(so, error); 1308 goto done; 1309 } 1310 conn = ssa->ssa_conn; 1311 } 1312 } 1313 dprint(2, ("sosctp_setsockopt %p (%d) - conn %p %d %d id:%d\n", 1314 (void *)ss, so->so_type, (void *)conn, level, option_name, id)); 1315 1316 ASSERT(ssa == NULL || (ssa != NULL && conn != NULL)); 1317 if (conn != NULL) { 1318 mutex_exit(&so->so_lock); 1319 error = sctp_set_opt((struct sctp_s *)conn, level, option_name, 1320 optval, optlen); 1321 mutex_enter(&so->so_lock); 1322 if (ssa != NULL) 1323 SSA_REFRELE(ss, ssa); 1324 } else { 1325 /* 1326 * 1-N socket, and we have to apply the operation to ALL 1327 * associations. Like with anything of this sort, the 1328 * problem is what to do if the operation fails. 1329 * Just try to apply the setting to everyone, but store 1330 * error number if someone returns such. And since we are 1331 * looping through all possible aids, some of them can be 1332 * invalid. We just ignore this kind (sosctp_assoc()) of 1333 * errors. 1334 */ 1335 sctp_assoc_t aid; 1336 1337 mutex_exit(&so->so_lock); 1338 error = sctp_set_opt((struct sctp_s *)so->so_proto_handle, 1339 level, option_name, optval, optlen); 1340 mutex_enter(&so->so_lock); 1341 for (aid = 1; aid < ss->ss_maxassoc; aid++) { 1342 if (sosctp_assoc(ss, aid, &ssa) != 0) 1343 continue; 1344 mutex_exit(&so->so_lock); 1345 rc = sctp_set_opt((struct sctp_s *)ssa->ssa_conn, level, 1346 option_name, optval, optlen); 1347 mutex_enter(&so->so_lock); 1348 SSA_REFRELE(ss, ssa); 1349 if (error == 0) { 1350 error = rc; 1351 } 1352 } 1353 } 1354done: 1355 mutex_exit(&so->so_lock); 1356 return (error); 1357} 1358 1359/*ARGSUSED*/ 1360static int 1361sosctp_ioctl(struct sonode *so, int cmd, intptr_t arg, int mode, 1362 struct cred *cr, int32_t *rvalp) 1363{ 1364 struct sctp_sonode *ss; 1365 int32_t value; 1366 int error; 1367 int intval; 1368 pid_t pid; 1369 struct sctp_soassoc *ssa; 1370 void *conn; 1371 void *buf; 1372 STRUCT_DECL(sctpopt, opt); 1373 uint32_t optlen; 1374 int buflen; 1375 1376 ss = SOTOSSO(so); 1377 1378 /* handle socket specific ioctls */ 1379 switch (cmd) { 1380 case FIONBIO: 1381 if (so_copyin((void *)arg, &value, sizeof (int32_t), 1382 (mode & (int)FKIOCTL))) { 1383 return (EFAULT); 1384 } 1385 mutex_enter(&so->so_lock); 1386 if (value) { 1387 so->so_state |= SS_NDELAY; 1388 } else { 1389 so->so_state &= ~SS_NDELAY; 1390 } 1391 mutex_exit(&so->so_lock); 1392 return (0); 1393 1394 case FIOASYNC: 1395 if (so_copyin((void *)arg, &value, sizeof (int32_t), 1396 (mode & (int)FKIOCTL))) { 1397 return (EFAULT); 1398 } 1399 mutex_enter(&so->so_lock); 1400 1401 if (value) { 1402 /* Turn on SIGIO */ 1403 so->so_state |= SS_ASYNC; 1404 } else { 1405 /* Turn off SIGIO */ 1406 so->so_state &= ~SS_ASYNC; 1407 } 1408 mutex_exit(&so->so_lock); 1409 return (0); 1410 1411 case SIOCSPGRP: 1412 case FIOSETOWN: 1413 if (so_copyin((void *)arg, &pid, sizeof (pid_t), 1414 (mode & (int)FKIOCTL))) { 1415 return (EFAULT); 1416 } 1417 mutex_enter(&so->so_lock); 1418 1419 error = (pid != so->so_pgrp) ? socket_chgpgrp(so, pid) : 0; 1420 mutex_exit(&so->so_lock); 1421 return (error); 1422 1423 case SIOCGPGRP: 1424 case FIOGETOWN: 1425 if (so_copyout(&so->so_pgrp, (void *)arg, 1426 sizeof (pid_t), (mode & (int)FKIOCTL))) 1427 return (EFAULT); 1428 return (0); 1429 1430 case FIONREAD: 1431 /* XXX: Cannot be used unless standard buffer is used */ 1432 /* 1433 * Return number of bytes of data in all data messages 1434 * in queue in "arg". 1435 * For stream socket, amount of available data. 1436 * For sock_dgram, # of available bytes + addresses. 1437 */ 1438 intval = (so->so_state & SS_ACCEPTCONN) ? 0 : 1439 MIN(so->so_rcv_queued, INT_MAX); 1440 if (so_copyout(&intval, (void *)arg, sizeof (intval), 1441 (mode & (int)FKIOCTL))) 1442 return (EFAULT); 1443 return (0); 1444 case SIOCATMARK: 1445 /* 1446 * No support for urgent data. 1447 */ 1448 intval = 0; 1449 1450 if (so_copyout(&intval, (void *)arg, sizeof (int), 1451 (mode & (int)FKIOCTL))) 1452 return (EFAULT); 1453 return (0); 1454 case SIOCSCTPGOPT: 1455 STRUCT_INIT(opt, mode); 1456 1457 if (so_copyin((void *)arg, STRUCT_BUF(opt), STRUCT_SIZE(opt), 1458 (mode & (int)FKIOCTL))) { 1459 return (EFAULT); 1460 } 1461 if ((optlen = STRUCT_FGET(opt, sopt_len)) > SO_MAXARGSIZE) 1462 return (EINVAL); 1463 1464 /* 1465 * Find the correct sctp_t based on whether it is 1-N socket 1466 * or not. 1467 */ 1468 intval = STRUCT_FGET(opt, sopt_aid); 1469 mutex_enter(&so->so_lock); 1470 if ((so->so_type == SOCK_SEQPACKET) && intval) { 1471 if ((error = sosctp_assoc(ss, intval, &ssa)) != 0) { 1472 mutex_exit(&so->so_lock); 1473 return (error); 1474 } 1475 conn = ssa->ssa_conn; 1476 ASSERT(conn != NULL); 1477 } else { 1478 conn = so->so_proto_handle; 1479 ssa = NULL; 1480 } 1481 mutex_exit(&so->so_lock); 1482 1483 /* Copyin the option buffer and then call sctp_get_opt(). */ 1484 buflen = optlen; 1485 /* Let's allocate a buffer enough to hold an int */ 1486 if (buflen < sizeof (uint32_t)) 1487 buflen = sizeof (uint32_t); 1488 buf = kmem_alloc(buflen, KM_SLEEP); 1489 if (so_copyin(STRUCT_FGETP(opt, sopt_val), buf, optlen, 1490 (mode & (int)FKIOCTL))) { 1491 if (ssa != NULL) { 1492 mutex_enter(&so->so_lock); 1493 SSA_REFRELE(ss, ssa); 1494 mutex_exit(&so->so_lock); 1495 } 1496 kmem_free(buf, buflen); 1497 return (EFAULT); 1498 } 1499 /* The option level has to be IPPROTO_SCTP */ 1500 error = sctp_get_opt((struct sctp_s *)conn, IPPROTO_SCTP, 1501 STRUCT_FGET(opt, sopt_name), buf, &optlen); 1502 if (ssa != NULL) { 1503 mutex_enter(&so->so_lock); 1504 SSA_REFRELE(ss, ssa); 1505 mutex_exit(&so->so_lock); 1506 } 1507 optlen = MIN(buflen, optlen); 1508 /* No error, copyout the result with the correct buf len. */ 1509 if (error == 0) { 1510 STRUCT_FSET(opt, sopt_len, optlen); 1511 if (so_copyout(STRUCT_BUF(opt), (void *)arg, 1512 STRUCT_SIZE(opt), (mode & (int)FKIOCTL))) { 1513 error = EFAULT; 1514 } else if (so_copyout(buf, STRUCT_FGETP(opt, sopt_val), 1515 optlen, (mode & (int)FKIOCTL))) { 1516 error = EFAULT; 1517 } 1518 } 1519 kmem_free(buf, buflen); 1520 return (error); 1521 1522 case SIOCSCTPSOPT: 1523 STRUCT_INIT(opt, mode); 1524 1525 if (so_copyin((void *)arg, STRUCT_BUF(opt), STRUCT_SIZE(opt), 1526 (mode & (int)FKIOCTL))) { 1527 return (EFAULT); 1528 } 1529 if ((optlen = STRUCT_FGET(opt, sopt_len)) > SO_MAXARGSIZE) 1530 return (EINVAL); 1531 1532 /* 1533 * Find the correct sctp_t based on whether it is 1-N socket 1534 * or not. 1535 */ 1536 intval = STRUCT_FGET(opt, sopt_aid); 1537 mutex_enter(&so->so_lock); 1538 if (intval != 0) { 1539 if ((error = sosctp_assoc(ss, intval, &ssa)) != 0) { 1540 mutex_exit(&so->so_lock); 1541 return (error); 1542 } 1543 conn = ssa->ssa_conn; 1544 ASSERT(conn != NULL); 1545 } else { 1546 conn = so->so_proto_handle; 1547 ssa = NULL; 1548 } 1549 mutex_exit(&so->so_lock); 1550 1551 /* Copyin the option buffer and then call sctp_set_opt(). */ 1552 buf = kmem_alloc(optlen, KM_SLEEP); 1553 if (so_copyin(STRUCT_FGETP(opt, sopt_val), buf, optlen, 1554 (mode & (int)FKIOCTL))) { 1555 if (ssa != NULL) { 1556 mutex_enter(&so->so_lock); 1557 SSA_REFRELE(ss, ssa); 1558 mutex_exit(&so->so_lock); 1559 } 1560 kmem_free(buf, intval); 1561 return (EFAULT); 1562 } 1563 /* The option level has to be IPPROTO_SCTP */ 1564 error = sctp_set_opt((struct sctp_s *)conn, IPPROTO_SCTP, 1565 STRUCT_FGET(opt, sopt_name), buf, optlen); 1566 if (ssa) { 1567 mutex_enter(&so->so_lock); 1568 SSA_REFRELE(ss, ssa); 1569 mutex_exit(&so->so_lock); 1570 } 1571 kmem_free(buf, optlen); 1572 return (error); 1573 1574 case SIOCSCTPPEELOFF: { 1575 struct sonode *nso; 1576 struct sctp_uc_swap us; 1577 int nfd; 1578 struct file *nfp; 1579 struct vnode *nvp = NULL; 1580 struct sockparams *sp; 1581 1582 dprint(2, ("sctppeeloff %p\n", (void *)ss)); 1583 1584 if (so->so_type != SOCK_SEQPACKET) { 1585 return (EOPNOTSUPP); 1586 } 1587 if (so_copyin((void *)arg, &intval, sizeof (intval), 1588 (mode & (int)FKIOCTL))) { 1589 return (EFAULT); 1590 } 1591 if (intval == 0) { 1592 return (EINVAL); 1593 } 1594 1595 /* 1596 * Find sockparams. This is different from parent's entry, 1597 * as the socket type is different. 1598 */ 1599 error = solookup(so->so_family, SOCK_STREAM, so->so_protocol, 1600 &sp); 1601 1602 /* 1603 * Allocate the user fd. 1604 */ 1605 if ((nfd = ufalloc(0)) == -1) { 1606 eprintsoline(so, EMFILE); 1607 return (EMFILE); 1608 } 1609 1610 /* 1611 * Copy the fd out. 1612 */ 1613 if (so_copyout(&nfd, (void *)arg, sizeof (nfd), 1614 (mode & (int)FKIOCTL))) { 1615 error = EFAULT; 1616 goto err; 1617 } 1618 mutex_enter(&so->so_lock); 1619 1620 /* 1621 * Don't use sosctp_assoc() in order to peel off disconnected 1622 * associations. 1623 */ 1624 ssa = ((uint32_t)intval >= ss->ss_maxassoc) ? NULL : 1625 ss->ss_assocs[intval].ssi_assoc; 1626 if (ssa == NULL) { 1627 mutex_exit(&so->so_lock); 1628 error = EINVAL; 1629 goto err; 1630 } 1631 SSA_REFHOLD(ssa); 1632 1633 nso = socksctp_create(sp, so->so_family, SOCK_STREAM, 1634 so->so_protocol, so->so_version, SOCKET_NOSLEEP, 1635 &error, cr); 1636 if (nso == NULL) { 1637 SSA_REFRELE(ss, ssa); 1638 mutex_exit(&so->so_lock); 1639 goto err; 1640 } 1641 /* cannot fail, only inheriting properties */ 1642 (void) sosctp_init(nso, so, CRED(), 0); 1643 nvp = SOTOV(nso); 1644 so_lock_single(so); 1645 mutex_exit(&so->so_lock); 1646 us.sus_handle = SOTOSSO(nso); 1647 us.sus_upcalls = &sosctp_sock_upcalls; 1648 1649 /* 1650 * Upcalls to new socket are blocked for the duration of 1651 * downcall. 1652 */ 1653 mutex_enter(&nso->so_lock); 1654 1655 error = sctp_set_opt((struct sctp_s *)ssa->ssa_conn, 1656 IPPROTO_SCTP, SCTP_UC_SWAP, &us, sizeof (us)); 1657 if (error) { 1658 goto peelerr; 1659 } 1660 error = falloc(nvp, FWRITE|FREAD, &nfp, NULL); 1661 if (error) { 1662 goto peelerr; 1663 } 1664 1665 /* 1666 * fill in the entries that falloc reserved 1667 */ 1668 nfp->f_vnode = nvp; 1669 mutex_exit(&nfp->f_tlock); 1670 setf(nfd, nfp); 1671 1672 mutex_enter(&so->so_lock); 1673 1674 sosctp_assoc_move(ss, SOTOSSO(nso), ssa); 1675 1676 mutex_exit(&nso->so_lock); 1677 1678 ssa->ssa_conn = NULL; 1679 sosctp_assoc_free(ss, ssa); 1680 1681 so_unlock_single(so, SOLOCKED); 1682 mutex_exit(&so->so_lock); 1683 1684 return (0); 1685 1686err: 1687 setf(nfd, NULL); 1688 eprintsoline(so, error); 1689 return (error); 1690 1691peelerr: 1692 mutex_exit(&nso->so_lock); 1693 mutex_enter(&so->so_lock); 1694 ASSERT(nso->so_count == 1); 1695 nso->so_count = 0; 1696 so_unlock_single(so, SOLOCKED); 1697 SSA_REFRELE(ss, ssa); 1698 mutex_exit(&so->so_lock); 1699 1700 setf(nfd, NULL); 1701 ASSERT(nvp->v_count == 1); 1702 socket_destroy(nso); 1703 eprintsoline(so, error); 1704 return (error); 1705 } 1706 default: 1707 return (EINVAL); 1708 } 1709} 1710 1711/*ARGSUSED*/ 1712static int 1713sosctp_close(struct sonode *so, int flag, struct cred *cr) 1714{ 1715 struct sctp_sonode *ss; 1716 struct sctp_sa_id *ssi; 1717 struct sctp_soassoc *ssa; 1718 int32_t i; 1719 1720 ss = SOTOSSO(so); 1721 1722 /* 1723 * Initiate connection shutdown. Update SCTP's receive 1724 * window. 1725 */ 1726 sctp_recvd((struct sctp_s *)so->so_proto_handle, 1727 so->so_rcvbuf - so->so_rcv_queued); 1728 (void) sctp_disconnect((struct sctp_s *)so->so_proto_handle); 1729 1730 /* 1731 * New associations can't come in, but old ones might get 1732 * closed in upcall. Protect against that by taking a reference 1733 * on the association. 1734 */ 1735 mutex_enter(&so->so_lock); 1736 ssi = ss->ss_assocs; 1737 for (i = 0; i < ss->ss_maxassoc; i++, ssi++) { 1738 if ((ssa = ssi->ssi_assoc) != NULL) { 1739 SSA_REFHOLD(ssa); 1740 sosctp_assoc_isdisconnected(ssa, 0); 1741 mutex_exit(&so->so_lock); 1742 1743 sctp_recvd((struct sctp_s *)ssa->ssa_conn, 1744 so->so_rcvbuf - ssa->ssa_rcv_queued); 1745 (void) sctp_disconnect((struct sctp_s *)ssa->ssa_conn); 1746 1747 mutex_enter(&so->so_lock); 1748 SSA_REFRELE(ss, ssa); 1749 } 1750 } 1751 mutex_exit(&so->so_lock); 1752 1753 return (0); 1754} 1755 1756/* 1757 * Closes incoming connections which were never accepted, frees 1758 * resources. 1759 */ 1760/* ARGSUSED */ 1761void 1762sosctp_fini(struct sonode *so, struct cred *cr) 1763{ 1764 struct sctp_sonode *ss; 1765 struct sctp_sa_id *ssi; 1766 struct sctp_soassoc *ssa; 1767 int32_t i; 1768 1769 ss = SOTOSSO(so); 1770 1771 ASSERT(so->so_ops == &sosctp_sonodeops || 1772 so->so_ops == &sosctp_seq_sonodeops); 1773 1774 /* We are the sole owner of so now */ 1775 mutex_enter(&so->so_lock); 1776 1777 so_rcv_flush(so); 1778 1779 /* Free all pending connections */ 1780 so_acceptq_flush(so); 1781 1782 ssi = ss->ss_assocs; 1783 for (i = 0; i < ss->ss_maxassoc; i++, ssi++) { 1784 if ((ssa = ssi->ssi_assoc) != NULL) { 1785 SSA_REFHOLD(ssa); 1786 mutex_exit(&so->so_lock); 1787 1788 sctp_close((struct sctp_s *)ssa->ssa_conn); 1789 1790 mutex_enter(&so->so_lock); 1791 ssa->ssa_conn = NULL; 1792 sosctp_assoc_free(ss, ssa); 1793 } 1794 } 1795 if (ss->ss_assocs != NULL) { 1796 ASSERT(ss->ss_assoccnt == 0); 1797 kmem_free(ss->ss_assocs, 1798 ss->ss_maxassoc * sizeof (struct sctp_sa_id)); 1799 } 1800 mutex_exit(&so->so_lock); 1801 1802 if (so->so_proto_handle) 1803 sctp_close((struct sctp_s *)so->so_proto_handle); 1804 so->so_proto_handle = NULL; 1805 1806 sonode_fini(so); 1807} 1808 1809/* 1810 * Upcalls from SCTP 1811 */ 1812 1813/* 1814 * This is the upcall function for 1-N (SOCK_SEQPACKET) socket when a new 1815 * association is created. Note that the first argument (handle) is of type 1816 * sctp_sonode *, which is the one changed to a listener for new 1817 * associations. All the other upcalls for 1-N socket take sctp_soassoc * 1818 * as handle. The only exception is the su_properties upcall, which 1819 * can take both types as handle. 1820 */ 1821/* ARGSUSED */ 1822sock_upper_handle_t 1823sctp_assoc_newconn(sock_upper_handle_t parenthandle, 1824 sock_lower_handle_t connind, sock_downcalls_t *dc, 1825 struct cred *peer_cred, pid_t peer_cpid, sock_upcalls_t **ucp) 1826{ 1827 struct sonode *lso = (struct sonode *)parenthandle; 1828 struct sctp_sonode *lss = SOTOSSO(lso); 1829 struct sctp_soassoc *ssa; 1830 sctp_assoc_t id; 1831 1832 ASSERT(lss->ss_type == SOSCTP_SOCKET); 1833 ASSERT(lso->so_state & SS_ACCEPTCONN); 1834 ASSERT(lso->so_proto_handle != NULL); /* closed conn */ 1835 ASSERT(lso->so_type == SOCK_SEQPACKET); 1836 1837 mutex_enter(&lso->so_lock); 1838 1839 if ((id = sosctp_aid_get(lss)) == -1) { 1840 /* 1841 * Array not large enough; increase size. 1842 */ 1843 if (sosctp_aid_grow(lss, lss->ss_maxassoc, KM_NOSLEEP) < 0) { 1844 mutex_exit(&lso->so_lock); 1845 return (NULL); 1846 } 1847 id = sosctp_aid_get(lss); 1848 ASSERT(id != -1); 1849 } 1850 1851 /* 1852 * Create soassoc for this connection 1853 */ 1854 ssa = sosctp_assoc_create(lss, KM_NOSLEEP); 1855 if (ssa == NULL) { 1856 mutex_exit(&lso->so_lock); 1857 return (NULL); 1858 } 1859 sosctp_aid_reserve(lss, id, 1); 1860 lss->ss_assocs[id].ssi_assoc = ssa; 1861 ++lss->ss_assoccnt; 1862 ssa->ssa_id = id; 1863 ssa->ssa_conn = (struct sctp_s *)connind; 1864 ssa->ssa_state = (SS_ISBOUND | SS_ISCONNECTED); 1865 ssa->ssa_wroff = lss->ss_wroff; 1866 ssa->ssa_wrsize = lss->ss_wrsize; 1867 1868 mutex_exit(&lso->so_lock); 1869 1870 *ucp = &sosctp_assoc_upcalls; 1871 1872 return ((sock_upper_handle_t)ssa); 1873} 1874 1875/* ARGSUSED */ 1876static void 1877sctp_assoc_connected(sock_upper_handle_t handle, sock_connid_t id, 1878 struct cred *peer_cred, pid_t peer_cpid) 1879{ 1880 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle; 1881 struct sonode *so = &ssa->ssa_sonode->ss_so; 1882 1883 ASSERT(so->so_type == SOCK_SEQPACKET); 1884 ASSERT(ssa->ssa_conn); 1885 1886 mutex_enter(&so->so_lock); 1887 sosctp_assoc_isconnected(ssa); 1888 mutex_exit(&so->so_lock); 1889} 1890 1891/* ARGSUSED */ 1892static int 1893sctp_assoc_disconnected(sock_upper_handle_t handle, sock_connid_t id, int error) 1894{ 1895 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle; 1896 struct sonode *so = &ssa->ssa_sonode->ss_so; 1897 int ret; 1898 1899 ASSERT(so->so_type == SOCK_SEQPACKET); 1900 ASSERT(ssa->ssa_conn != NULL); 1901 1902 mutex_enter(&so->so_lock); 1903 sosctp_assoc_isdisconnected(ssa, error); 1904 if (ssa->ssa_refcnt == 1) { 1905 ret = 1; 1906 ssa->ssa_conn = NULL; 1907 } else { 1908 ret = 0; 1909 } 1910 SSA_REFRELE(SOTOSSO(so), ssa); 1911 1912 cv_broadcast(&so->so_snd_cv); 1913 1914 mutex_exit(&so->so_lock); 1915 1916 return (ret); 1917} 1918 1919/* ARGSUSED */ 1920static void 1921sctp_assoc_disconnecting(sock_upper_handle_t handle, sock_opctl_action_t action, 1922 uintptr_t arg) 1923{ 1924 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle; 1925 struct sonode *so = &ssa->ssa_sonode->ss_so; 1926 1927 ASSERT(so->so_type == SOCK_SEQPACKET); 1928 ASSERT(ssa->ssa_conn != NULL); 1929 ASSERT(action == SOCK_OPCTL_SHUT_SEND); 1930 1931 mutex_enter(&so->so_lock); 1932 sosctp_assoc_isdisconnecting(ssa); 1933 mutex_exit(&so->so_lock); 1934} 1935 1936/* ARGSUSED */ 1937static ssize_t 1938sctp_assoc_recv(sock_upper_handle_t handle, mblk_t *mp, size_t len, int flags, 1939 int *errorp, boolean_t *forcepush) 1940{ 1941 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle; 1942 struct sctp_sonode *ss = ssa->ssa_sonode; 1943 struct sonode *so = &ss->ss_so; 1944 struct T_unitdata_ind *tind; 1945 mblk_t *mp2; 1946 union sctp_notification *sn; 1947 struct sctp_sndrcvinfo *sinfo; 1948 1949 ASSERT(ssa->ssa_type == SOSCTP_ASSOC); 1950 ASSERT(so->so_type == SOCK_SEQPACKET); 1951 ASSERT(ssa->ssa_conn != NULL); /* closed conn */ 1952 ASSERT(mp != NULL); 1953 1954 ASSERT(errorp != NULL); 1955 *errorp = 0; 1956 1957 /* 1958 * Should be getting T_unitdata_req's only. 1959 * Must have address as part of packet. 1960 */ 1961 tind = (struct T_unitdata_ind *)mp->b_rptr; 1962 ASSERT((DB_TYPE(mp) == M_PROTO) && 1963 (tind->PRIM_type == T_UNITDATA_IND)); 1964 ASSERT(tind->SRC_length); 1965 1966 mutex_enter(&so->so_lock); 1967 1968 /* 1969 * Override b_flag for SCTP sockfs internal use 1970 */ 1971 mp->b_flag = (short)flags; 1972 1973 /* 1974 * For notify messages, need to fill in association id. 1975 * For data messages, sndrcvinfo could be in ancillary data. 1976 */ 1977 if (flags & SCTP_NOTIFICATION) { 1978 mp2 = mp->b_cont; 1979 sn = (union sctp_notification *)mp2->b_rptr; 1980 switch (sn->sn_header.sn_type) { 1981 case SCTP_ASSOC_CHANGE: 1982 sn->sn_assoc_change.sac_assoc_id = ssa->ssa_id; 1983 break; 1984 case SCTP_PEER_ADDR_CHANGE: 1985 sn->sn_paddr_change.spc_assoc_id = ssa->ssa_id; 1986 break; 1987 case SCTP_REMOTE_ERROR: 1988 sn->sn_remote_error.sre_assoc_id = ssa->ssa_id; 1989 break; 1990 case SCTP_SEND_FAILED: 1991 sn->sn_send_failed.ssf_assoc_id = ssa->ssa_id; 1992 break; 1993 case SCTP_SHUTDOWN_EVENT: 1994 sn->sn_shutdown_event.sse_assoc_id = ssa->ssa_id; 1995 break; 1996 case SCTP_ADAPTATION_INDICATION: 1997 sn->sn_adaptation_event.sai_assoc_id = ssa->ssa_id; 1998 break; 1999 case SCTP_PARTIAL_DELIVERY_EVENT: 2000 sn->sn_pdapi_event.pdapi_assoc_id = ssa->ssa_id; 2001 break; 2002 default: 2003 ASSERT(0); 2004 break; 2005 } 2006 } else { 2007 if (tind->OPT_length > 0) { 2008 struct cmsghdr *cmsg; 2009 char *cend; 2010 2011 cmsg = (struct cmsghdr *) 2012 ((uchar_t *)mp->b_rptr + tind->OPT_offset); 2013 cend = (char *)cmsg + tind->OPT_length; 2014 for (;;) { 2015 if ((char *)(cmsg + 1) > cend || 2016 ((char *)cmsg + cmsg->cmsg_len) > cend) { 2017 break; 2018 } 2019 if ((cmsg->cmsg_level == IPPROTO_SCTP) && 2020 (cmsg->cmsg_type == SCTP_SNDRCV)) { 2021 sinfo = (struct sctp_sndrcvinfo *) 2022 (cmsg + 1); 2023 sinfo->sinfo_assoc_id = ssa->ssa_id; 2024 break; 2025 } 2026 if (cmsg->cmsg_len > 0) { 2027 cmsg = (struct cmsghdr *) 2028 ((uchar_t *)cmsg + cmsg->cmsg_len); 2029 } else { 2030 break; 2031 } 2032 } 2033 } 2034 } 2035 2036 /* 2037 * SCTP has reserved space in the header for storing a pointer. 2038 * Put the pointer to assocation there, and queue the data. 2039 */ 2040 SSA_REFHOLD(ssa); 2041 ASSERT((mp->b_rptr - DB_BASE(mp)) >= sizeof (ssa)); 2042 *(struct sctp_soassoc **)DB_BASE(mp) = ssa; 2043 2044 mutex_exit(&so->so_lock); 2045 2046 return (so_queue_msg((sock_upper_handle_t)so, mp, len, 0, errorp, 2047 NULL)); 2048} 2049 2050static void 2051sctp_assoc_xmitted(sock_upper_handle_t handle, boolean_t qfull) 2052{ 2053 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle; 2054 struct sctp_sonode *ss = ssa->ssa_sonode; 2055 2056 ASSERT(ssa->ssa_type == SOSCTP_ASSOC); 2057 ASSERT(ss->ss_so.so_type == SOCK_SEQPACKET); 2058 ASSERT(ssa->ssa_conn != NULL); 2059 2060 mutex_enter(&ss->ss_so.so_lock); 2061 2062 ssa->ssa_snd_qfull = qfull; 2063 2064 /* 2065 * Wake blocked writers. 2066 */ 2067 cv_broadcast(&ss->ss_so.so_snd_cv); 2068 2069 mutex_exit(&ss->ss_so.so_lock); 2070} 2071 2072static void 2073sctp_assoc_properties(sock_upper_handle_t handle, 2074 struct sock_proto_props *soppp) 2075{ 2076 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle; 2077 struct sctp_sonode *ss; 2078 2079 if (ssa->ssa_type == SOSCTP_ASSOC) { 2080 ss = ssa->ssa_sonode; 2081 mutex_enter(&ss->ss_so.so_lock); 2082 2083 /* 2084 * Only change them if they're set. 2085 */ 2086 if (soppp->sopp_wroff != 0) { 2087 ssa->ssa_wroff = soppp->sopp_wroff; 2088 } 2089 if (soppp->sopp_maxblk != 0) { 2090 ssa->ssa_wrsize = soppp->sopp_maxblk; 2091 } 2092 } else { 2093 ss = (struct sctp_sonode *)handle; 2094 mutex_enter(&ss->ss_so.so_lock); 2095 2096 if (soppp->sopp_wroff != 0) { 2097 ss->ss_wroff = soppp->sopp_wroff; 2098 } 2099 if (soppp->sopp_maxblk != 0) { 2100 ss->ss_wrsize = soppp->sopp_maxblk; 2101 } 2102 } 2103 2104 mutex_exit(&ss->ss_so.so_lock); 2105} 2106