1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2017 Joyent, Inc. 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/policy.h> 40 41 #include <sys/filio.h> 42 #include <sys/sockio.h> 43 44 #include <sys/project.h> 45 #include <sys/tihdr.h> 46 #include <sys/strsubr.h> 47 48 #include <sys/socket.h> 49 #include <sys/socketvar.h> 50 #include <sys/strsun.h> 51 52 #include <sys/tsol/label.h> 53 54 #include <inet/sdp_itf.h> 55 #include "socksdp.h" 56 #include <fs/sockfs/sockcommon.h> 57 58 /* 59 * SDP sockfs sonode operations 60 */ 61 static int sosdp_init(struct sonode *, struct sonode *, struct cred *, int); 62 static int sosdp_accept(struct sonode *, int, struct cred *, struct sonode **); 63 static int sosdp_bind(struct sonode *, struct sockaddr *, socklen_t, int, 64 struct cred *); 65 static int sosdp_listen(struct sonode *, int, struct cred *); 66 static int sosdp_connect(struct sonode *, struct sockaddr *, socklen_t, 67 int, int, struct cred *); 68 static int sosdp_recvmsg(struct sonode *, struct nmsghdr *, struct uio *, 69 struct cred *); 70 static int sosdp_sendmsg(struct sonode *, struct nmsghdr *, struct uio *, 71 struct cred *); 72 static int sosdp_getpeername(struct sonode *, struct sockaddr *, socklen_t *, 73 boolean_t, struct cred *); 74 static int sosdp_getsockname(struct sonode *, struct sockaddr *, socklen_t *, 75 struct cred *); 76 static int sosdp_shutdown(struct sonode *, int, struct cred *); 77 static int sosdp_getsockopt(struct sonode *, int, int, void *, socklen_t *, 78 int, struct cred *); 79 static int sosdp_setsockopt(struct sonode *, int, int, const void *, 80 socklen_t, struct cred *); 81 static int sosdp_ioctl(struct sonode *, int, intptr_t, int, struct cred *, 82 int32_t *); 83 static int sosdp_poll(struct sonode *, short, int, short *, 84 struct pollhead **); 85 static int sosdp_close(struct sonode *, int, struct cred *); 86 void sosdp_fini(struct sonode *, struct cred *); 87 88 89 /* 90 * Socket upcalls 91 */ 92 static void *sdp_sock_newconn(void *parenthandle, void *connind); 93 static void sdp_sock_connected(void *handle); 94 static void sdp_sock_disconnected(void *handle, int error); 95 static void sdp_sock_connfail(void *handle, int error); 96 static int sdp_sock_recv(void *handle, mblk_t *mp, int flags); 97 static void sdp_sock_xmitted(void *handle, int txqueued); 98 static void sdp_sock_urgdata(void *handle); 99 static void sdp_sock_ordrel(void *handle); 100 101 sonodeops_t sosdp_sonodeops = { 102 sosdp_init, /* sop_init */ 103 sosdp_accept, /* sop_accept */ 104 sosdp_bind, /* sop_bind */ 105 sosdp_listen, /* sop_listen */ 106 sosdp_connect, /* sop_connect */ 107 sosdp_recvmsg, /* sop_recvmsg */ 108 sosdp_sendmsg, /* sop_sendmsg */ 109 so_sendmblk_notsupp, /* sop_sendmblk */ 110 sosdp_getpeername, /* sop_getpeername */ 111 sosdp_getsockname, /* sop_getsockname */ 112 sosdp_shutdown, /* sop_shutdown */ 113 sosdp_getsockopt, /* sop_getsockopt */ 114 sosdp_setsockopt, /* sop_setsockopt */ 115 sosdp_ioctl, /* sop_ioctl */ 116 sosdp_poll, /* sop_poll */ 117 sosdp_close, /* sop_close */ 118 }; 119 120 sdp_upcalls_t sosdp_sock_upcalls = { 121 sdp_sock_newconn, 122 sdp_sock_connected, 123 sdp_sock_disconnected, 124 sdp_sock_connfail, 125 sdp_sock_recv, 126 sdp_sock_xmitted, 127 sdp_sock_urgdata, 128 sdp_sock_ordrel, 129 }; 130 131 /* ARGSUSED */ 132 static int 133 sosdp_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags) 134 { 135 int error = 0; 136 sdp_sockbuf_limits_t sbl; 137 sdp_upcalls_t *upcalls; 138 139 if (pso != NULL) { 140 /* passive open, just inherit settings from parent */ 141 142 mutex_enter(&so->so_lock); 143 144 so->so_state |= (SS_ISBOUND | SS_ISCONNECTED | 145 (pso->so_state & SS_ASYNC)); 146 sosdp_so_inherit(pso, so); 147 so->so_proto_props = pso->so_proto_props; 148 149 mutex_exit(&so->so_lock); 150 151 return (0); 152 } 153 154 if ((error = secpolicy_basic_net_access(cr)) != 0) 155 return (error); 156 157 upcalls = &sosdp_sock_upcalls; 158 159 so->so_proto_handle = (sock_lower_handle_t)sdp_create(so, NULL, 160 so->so_family, SDP_CAN_BLOCK, upcalls, &sbl, cr, &error); 161 if (so->so_proto_handle == NULL) 162 return (ENOMEM); 163 164 so->so_rcvbuf = sbl.sbl_rxbuf; 165 so->so_rcvlowat = sbl.sbl_rxlowat; 166 so->so_sndbuf = sbl.sbl_txbuf; 167 so->so_sndlowat = sbl.sbl_txlowat; 168 169 return (error); 170 } 171 172 /* 173 * Accept incoming connection. 174 */ 175 /* ARGSUSED */ 176 static int 177 sosdp_accept(struct sonode *lso, int fflag, struct cred *cr, 178 struct sonode **nsop) 179 { 180 int error = 0; 181 struct sonode *nso; 182 183 dprint(3, ("sosdp_accept: so:%p so_proto_handle:%p", (void *)lso, 184 (void *)lso->so_proto_handle)); 185 186 if (!(lso->so_state & SS_ACCEPTCONN)) { 187 /* 188 * Not a listen socket. 189 */ 190 eprintsoline(lso, EINVAL); 191 return (EINVAL); 192 } 193 /* 194 * Returns right away if socket is nonblocking. 195 */ 196 error = so_acceptq_dequeue(lso, (fflag & (FNONBLOCK|FNDELAY)), &nso); 197 if (error != 0) { 198 eprintsoline(lso, error); 199 dprint(4, ("sosdp_accept: failed %d:lso:%p so_proto_handle:%p", 200 error, (void *)lso, (void *)lso->so_proto_handle)); 201 return (error); 202 } 203 204 dprint(2, ("sosdp_accept: new %p\n", (void *)nso)); 205 *nsop = nso; 206 207 return (0); 208 } 209 210 /* 211 * Bind local endpoint. 212 */ 213 /* ARGSUSED */ 214 int 215 sosdp_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen, 216 int flags, struct cred *cr) 217 { 218 int error = 0; 219 220 if (!(flags & _SOBIND_LOCK_HELD)) { 221 mutex_enter(&so->so_lock); 222 so_lock_single(so); /* Set SOLOCKED */ 223 } else { 224 ASSERT(MUTEX_HELD(&so->so_lock)); 225 ASSERT(so->so_flag & SOLOCKED); 226 } 227 228 if ((so->so_state & SS_ISBOUND) || name == NULL || namelen == 0) { 229 /* 230 * Multiple binds not allowed for any SDP socket. 231 * Also binding with null address is not supported. 232 */ 233 error = EINVAL; 234 eprintsoline(so, error); 235 goto done; 236 } 237 238 /* 239 * X/Open requires this check 240 */ 241 if (so->so_state & SS_CANTSENDMORE) { 242 error = EINVAL; 243 goto done; 244 } 245 246 /* 247 * Protocol module does address family checks 248 */ 249 mutex_exit(&so->so_lock); 250 251 error = sdp_bind((struct sdp_conn_struct_t *)so->so_proto_handle, 252 name, namelen); 253 254 mutex_enter(&so->so_lock); 255 256 if (error == 0) { 257 so->so_state |= SS_ISBOUND; 258 } else { 259 eprintsoline(so, error); 260 } 261 done: 262 if (!(flags & _SOBIND_LOCK_HELD)) { 263 so_unlock_single(so, SOLOCKED); 264 mutex_exit(&so->so_lock); 265 } else { 266 /* If the caller held the lock don't release it here */ 267 ASSERT(MUTEX_HELD(&so->so_lock)); 268 ASSERT(so->so_flag & SOLOCKED); 269 } 270 return (error); 271 } 272 273 /* 274 * Turn socket into a listen socket. 275 */ 276 /* ARGSUSED */ 277 static int 278 sosdp_listen(struct sonode *so, int backlog, struct cred *cr) 279 { 280 int error = 0; 281 282 mutex_enter(&so->so_lock); 283 so_lock_single(so); 284 285 /* 286 * If this socket is trying to do connect, or if it has 287 * been connected, disallow. 288 */ 289 if (so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED | 290 SS_ISDISCONNECTING | SS_CANTRCVMORE | SS_CANTSENDMORE)) { 291 error = EINVAL; 292 eprintsoline(so, EINVAL); 293 goto done; 294 } 295 /* 296 * If listen() is only called to change backlog, we don't 297 * need to notify protocol module. 298 */ 299 if (so->so_state & SS_ACCEPTCONN) { 300 so->so_backlog = backlog; 301 goto done; 302 } 303 304 mutex_exit(&so->so_lock); 305 306 error = sdp_listen((struct sdp_conn_struct_t *)so->so_proto_handle, 307 backlog); 308 309 mutex_enter(&so->so_lock); 310 if (error == 0) { 311 so->so_state |= (SS_ACCEPTCONN | SS_ISBOUND); 312 so->so_backlog = backlog; 313 } else { 314 eprintsoline(so, error); 315 } 316 done: 317 so_unlock_single(so, SOLOCKED); 318 mutex_exit(&so->so_lock); 319 320 return (error); 321 } 322 323 /* 324 * Active open. 325 */ 326 /*ARGSUSED*/ 327 static int 328 sosdp_connect(struct sonode *so, struct sockaddr *name, 329 socklen_t namelen, int fflag, int flags, struct cred *cr) 330 { 331 int error = 0; 332 333 mutex_enter(&so->so_lock); 334 so_lock_single(so); 335 336 /* 337 * Can't connect() after listen(), or if the socket is already 338 * connected. 339 */ 340 if (so->so_state & (SS_ACCEPTCONN|SS_ISCONNECTED|SS_ISCONNECTING)) { 341 if (so->so_state & SS_ISCONNECTED) { 342 error = EISCONN; 343 } else if (so->so_state & SS_ISCONNECTING) { 344 error = EALREADY; 345 } else { 346 error = EOPNOTSUPP; 347 } 348 eprintsoline(so, error); 349 goto done; 350 } 351 352 /* 353 * check for failure of an earlier call 354 */ 355 if (so->so_error != 0) { 356 error = sogeterr(so, B_TRUE); 357 eprintsoline(so, error); 358 goto done; 359 } 360 361 /* 362 * Connection is closing, or closed, don't allow reconnect. 363 * TCP allows this to proceed, but the socket remains unwriteable. 364 * BSD returns EINVAL. 365 */ 366 if (so->so_state & (SS_ISDISCONNECTING|SS_CANTRCVMORE| 367 SS_CANTSENDMORE)) { 368 error = EINVAL; 369 eprintsoline(so, error); 370 goto done; 371 } 372 if (name == NULL || namelen == 0) { 373 eprintsoline(so, EINVAL); 374 goto done; 375 } 376 soisconnecting(so); 377 mutex_exit(&so->so_lock); 378 379 error = sdp_connect((struct sdp_conn_struct_t *)so->so_proto_handle, 380 name, namelen); 381 382 mutex_enter(&so->so_lock); 383 if (error == 0) { 384 /* 385 * Allow other threads to access the socket 386 */ 387 error = sowaitconnected(so, fflag, 0); 388 dprint(4, 389 ("sosdp_connect: wait on so:%p " 390 "so_proto_handle:%p failed:%d", 391 (void *)so, (void *)so->so_proto_handle, error)); 392 } 393 394 switch (error) { 395 case 0: 396 case EINPROGRESS: 397 case EALREADY: 398 case EINTR: 399 /* Non-fatal errors */ 400 so->so_state |= SS_ISBOUND; 401 break; 402 default: 403 /* clear SS_ISCONNECTING in case it was set */ 404 so->so_state &= ~SS_ISCONNECTING; 405 break; 406 } 407 done: 408 so_unlock_single(so, SOLOCKED); 409 mutex_exit(&so->so_lock); 410 return (error); 411 } 412 413 /* 414 * Receive data. 415 */ 416 /* ARGSUSED */ 417 int 418 sosdp_recvmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop, 419 struct cred *cr) 420 { 421 int flags, error = 0; 422 int size; 423 424 flags = msg->msg_flags; 425 msg->msg_flags = 0; 426 427 428 if (!(so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING| 429 SS_CANTRCVMORE))) { 430 return (ENOTCONN); 431 } 432 433 /* 434 * flag possibilities: 435 * 436 * MSG_PEEK Don't consume data 437 * MSG_WAITALL Wait for full quantity of data (ignored if MSG_PEEK) 438 * MSG_DONTWAIT Non-blocking (same as FNDELAY | FNONBLOCK) 439 * 440 * MSG_WAITALL can return less than the full buffer if either 441 * 442 * 1. we would block and we are non-blocking 443 * 2. a full message cannot be delivered 444 * 445 */ 446 447 mutex_enter(&so->so_lock); 448 449 /* 450 * Allow just one reader at a time. 451 */ 452 error = so_lock_read_intr(so, 453 uiop->uio_fmode | ((flags & MSG_DONTWAIT) ? FNONBLOCK : 0)); 454 if (error != 0) { 455 mutex_exit(&so->so_lock); 456 return (error); 457 } 458 size = uiop->uio_resid; 459 mutex_exit(&so->so_lock); 460 461 if (!(so->so_state & SS_CANTRCVMORE)) { 462 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK)) { 463 flags |= MSG_DONTWAIT; 464 } 465 error = sdp_recv( 466 (struct sdp_conn_struct_t *)so->so_proto_handle, msg, 467 size, flags, uiop); 468 } else { 469 msg->msg_controllen = 0; 470 msg->msg_namelen = 0; 471 } 472 done: 473 mutex_enter(&so->so_lock); 474 so_unlock_read(so); 475 mutex_exit(&so->so_lock); 476 return (error); 477 } 478 479 /* 480 * Send message. 481 */ 482 /* ARGSUSED */ 483 static int 484 sosdp_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop, 485 struct cred *cr) 486 { 487 int flags; 488 ssize_t count; 489 int error; 490 491 ASSERT(so->so_type == SOCK_STREAM); 492 493 dprint(4, ("sosdp_sendmsg: so:%p so_proto_handle:%p", 494 (void *)so, (void *)so->so_proto_handle)); 495 496 flags = msg->msg_flags; 497 498 if (msg->msg_controllen != 0) { 499 return (EOPNOTSUPP); 500 } 501 502 mutex_enter(&so->so_lock); 503 if (so->so_state & SS_CANTSENDMORE) { 504 mutex_exit(&so->so_lock); 505 return (EPIPE); 506 } 507 508 if (so->so_error != 0) { 509 error = sogeterr(so, B_TRUE); 510 mutex_exit(&so->so_lock); 511 return (error); 512 } 513 514 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK)) 515 flags |= MSG_DONTWAIT; 516 517 count = uiop->uio_resid; 518 519 if (!(so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED))) { 520 dprint(4, ("sosdp_sendmsg: invalid state: <%x>", 521 so->so_state)); 522 mutex_exit(&so->so_lock); 523 return (ENOTCONN); 524 } 525 526 mutex_exit(&so->so_lock); 527 error = sdp_send((struct sdp_conn_struct_t *)so->so_proto_handle, 528 msg, count, flags, uiop); 529 530 return (error); 531 } 532 533 /* 534 * Get address of remote node. 535 */ 536 /* ARGSUSED */ 537 static int 538 sosdp_getpeername(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen, 539 boolean_t accept, struct cred *cr) 540 { 541 542 if (!accept && !(so->so_state & SS_ISCONNECTED)) { 543 return (ENOTCONN); 544 } else { 545 return (sdp_getpeername( 546 (struct sdp_conn_struct_t *)so->so_proto_handle, 547 addr, addrlen)); 548 } 549 } 550 551 /* 552 * Get local address. 553 */ 554 /* ARGSUSED */ 555 static int 556 sosdp_getsockname(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen, 557 struct cred *cr) 558 { 559 mutex_enter(&so->so_lock); 560 561 if (!(so->so_state & SS_ISBOUND)) { 562 /* 563 * Zero address, except for address family 564 */ 565 if (so->so_family == AF_INET || so->so_family == AF_INET6) { 566 bzero(addr, *addrlen); 567 *addrlen = (so->so_family == AF_INET6) ? 568 sizeof (struct sockaddr_in6) : 569 sizeof (struct sockaddr_in); 570 addr->sa_family = so->so_family; 571 } 572 mutex_exit(&so->so_lock); 573 return (0); 574 } else { 575 mutex_exit(&so->so_lock); 576 return (sdp_getsockname( 577 (struct sdp_conn_struct_t *)so->so_proto_handle, 578 addr, addrlen)); 579 } 580 } 581 582 /* 583 * Called from shutdown(). 584 */ 585 /* ARGSUSED */ 586 static int 587 sosdp_shutdown(struct sonode *so, int how, struct cred *cr) 588 { 589 uint_t state_change; 590 int error = 0; 591 592 mutex_enter(&so->so_lock); 593 so_lock_single(so); 594 /* 595 * Record the current state and then perform any state changes. 596 * Then use the difference between the old and new states to 597 * determine which needs to be done. 598 */ 599 state_change = so->so_state; 600 if (!(state_change & SS_ISCONNECTED)) { 601 error = ENOTCONN; 602 goto done; 603 } 604 605 switch (how) { 606 case SHUT_RD: 607 socantrcvmore(so); 608 break; 609 case SHUT_WR: 610 socantsendmore(so); 611 break; 612 case SHUT_RDWR: 613 socantsendmore(so); 614 socantrcvmore(so); 615 break; 616 default: 617 error = EINVAL; 618 goto done; 619 } 620 621 state_change = so->so_state & ~state_change; 622 623 if (state_change & SS_CANTSENDMORE) { 624 so->so_state |= SS_ISDISCONNECTING; 625 } 626 so_notify_shutdown(so); 627 628 if (state_change & SS_CANTSENDMORE) { 629 error = sdp_shutdown( 630 (struct sdp_conn_struct_t *)so->so_proto_handle, how); 631 } 632 633 mutex_enter(&so->so_lock); 634 done: 635 so_unlock_single(so, SOLOCKED); 636 mutex_exit(&so->so_lock); 637 638 /* 639 * HACK: sdp_disconnect() may return EWOULDBLOCK. But this error is 640 * not documented in standard socket API. Catch it here. 641 */ 642 if (error == EWOULDBLOCK) 643 error = 0; 644 return (error); 645 } 646 647 /* 648 * Get socket options. 649 */ 650 /*ARGSUSED*/ 651 static int 652 sosdp_getsockopt(struct sonode *so, int level, int option_name, 653 void *optval, socklen_t *optlenp, int flags, struct cred *cr) 654 { 655 int error = 0; 656 void *option = NULL; 657 socklen_t maxlen = *optlenp, len, optlen; 658 uint32_t value; 659 uint8_t buffer[4]; 660 void *optbuf = &buffer; 661 662 663 mutex_enter(&so->so_lock); 664 665 if (level == SOL_SOCKET) { 666 switch (option_name) { 667 case SO_TYPE: 668 case SO_ERROR: 669 case SO_DEBUG: 670 case SO_ACCEPTCONN: 671 case SO_REUSEADDR: 672 case SO_KEEPALIVE: 673 case SO_DONTROUTE: 674 case SO_BROADCAST: 675 case SO_USELOOPBACK: 676 case SO_OOBINLINE: 677 case SO_SNDBUF: 678 case SO_RCVBUF: 679 case SO_SNDLOWAT: 680 case SO_RCVLOWAT: 681 case SO_DGRAM_ERRIND: 682 if (maxlen < (t_uscalar_t)sizeof (int32_t)) { 683 error = EINVAL; 684 eprintsoline(so, error); 685 goto done; 686 } 687 break; 688 case SO_LINGER: 689 if (maxlen < (t_uscalar_t)sizeof (struct linger)) { 690 error = EINVAL; 691 eprintsoline(so, error); 692 goto done; 693 } 694 break; 695 } 696 len = (t_uscalar_t)sizeof (uint32_t); /* Default */ 697 option = &value; 698 699 switch (option_name) { 700 case SO_TYPE: 701 value = so->so_type; 702 goto copyout; 703 704 case SO_ERROR: 705 value = sogeterr(so, B_TRUE); 706 goto copyout; 707 708 case SO_ACCEPTCONN: 709 value = (so->so_state & SS_ACCEPTCONN) ? 710 SO_ACCEPTCONN : 0; 711 goto copyout; 712 713 case SO_DEBUG: 714 case SO_REUSEADDR: 715 case SO_KEEPALIVE: 716 case SO_DONTROUTE: 717 case SO_BROADCAST: 718 case SO_USELOOPBACK: 719 case SO_OOBINLINE: 720 case SO_DGRAM_ERRIND: 721 value = (so->so_options & option_name); 722 goto copyout; 723 724 /* 725 * The following options are only returned by sockfs 726 * when sdp_get_opt() fails. 727 */ 728 729 case SO_LINGER: 730 option = &so->so_linger; 731 len = (t_uscalar_t)sizeof (struct linger); 732 break; 733 case SO_SNDBUF: 734 value = so->so_sndbuf; 735 len = (t_uscalar_t)sizeof (int); 736 goto copyout; 737 738 case SO_RCVBUF: 739 value = so->so_rcvbuf; 740 len = (t_uscalar_t)sizeof (int); 741 goto copyout; 742 743 case SO_SNDLOWAT: 744 value = so->so_sndlowat; 745 len = (t_uscalar_t)sizeof (int); 746 goto copyout; 747 748 case SO_RCVLOWAT: 749 value = so->so_rcvlowat; 750 len = (t_uscalar_t)sizeof (int); 751 goto copyout; 752 753 default: 754 option = NULL; 755 break; 756 } 757 } 758 if (maxlen > sizeof (buffer)) { 759 optbuf = kmem_alloc(maxlen, KM_SLEEP); 760 } 761 optlen = maxlen; 762 mutex_exit(&so->so_lock); 763 error = sdp_get_opt((struct sdp_conn_struct_t *)so->so_proto_handle, 764 level, option_name, optbuf, &optlen); 765 mutex_enter(&so->so_lock); 766 ASSERT(optlen <= maxlen); 767 if (error != 0) { 768 if (option == NULL) { 769 /* We have no fallback value */ 770 eprintsoline(so, error); 771 goto free; 772 } 773 error = 0; 774 goto copyout; 775 } 776 777 option = optbuf; 778 len = optlen; 779 780 copyout: 781 len = MIN(len, maxlen); 782 bcopy(option, optval, len); 783 *optlenp = len; 784 785 free: 786 if (optbuf != &buffer) { 787 kmem_free(optbuf, maxlen); 788 } 789 done: 790 mutex_exit(&so->so_lock); 791 return (error); 792 } 793 794 /* 795 * Set socket options 796 */ 797 /* ARGSUSED */ 798 static int 799 sosdp_setsockopt(struct sonode *so, int level, int option_name, 800 const void *optval, t_uscalar_t optlen, struct cred *cr) 801 { 802 void *conn = NULL; 803 int error = 0; 804 805 if (so->so_state & SS_CANTSENDMORE) { 806 return (EINVAL); 807 } 808 809 mutex_enter(&so->so_lock); 810 so_lock_single(so); 811 812 if (so->so_type == SOCK_STREAM) { 813 conn = (void *)so->so_proto_handle; 814 } 815 816 dprint(2, ("sosdp_setsockopt (%d) - conn %p %d %d \n", 817 so->so_type, conn, level, option_name)); 818 819 if (conn != NULL) { 820 mutex_exit(&so->so_lock); 821 error = sdp_set_opt((struct sdp_conn_struct_t *)conn, level, 822 option_name, optval, optlen); 823 mutex_enter(&so->so_lock); 824 } 825 826 /* 827 * Check for SOL_SOCKET options and record their values. 828 * If we know about a SOL_SOCKET parameter and the transport 829 * failed it with TBADOPT or TOUTSTATE (i.e. ENOPROTOOPT or 830 * EPROTO) we let the setsockopt succeed. 831 */ 832 if (level == SOL_SOCKET) { 833 boolean_t handled = B_FALSE; 834 835 /* Check parameters */ 836 switch (option_name) { 837 case SO_DEBUG: 838 case SO_REUSEADDR: 839 case SO_KEEPALIVE: 840 case SO_DONTROUTE: 841 case SO_BROADCAST: 842 case SO_USELOOPBACK: 843 case SO_OOBINLINE: 844 case SO_SNDBUF: 845 case SO_RCVBUF: 846 case SO_SNDLOWAT: 847 case SO_RCVLOWAT: 848 case SO_DGRAM_ERRIND: 849 if (optlen != (t_uscalar_t)sizeof (int32_t)) { 850 error = EINVAL; 851 eprintsoline(so, error); 852 goto done; 853 } 854 ASSERT(optval); 855 handled = B_TRUE; 856 break; 857 case SO_LINGER: 858 if (optlen != (t_uscalar_t)sizeof (struct linger)) { 859 error = EINVAL; 860 eprintsoline(so, error); 861 goto done; 862 } 863 ASSERT(optval); 864 handled = B_TRUE; 865 break; 866 } 867 868 #define intvalue (*(int32_t *)optval) 869 870 switch (option_name) { 871 case SO_TYPE: 872 case SO_ERROR: 873 case SO_ACCEPTCONN: 874 /* Can't be set */ 875 error = ENOPROTOOPT; 876 goto done; 877 case SO_LINGER: { 878 struct linger *l = (struct linger *)optval; 879 880 so->so_linger.l_linger = l->l_linger; 881 if (l->l_onoff) { 882 so->so_linger.l_onoff = SO_LINGER; 883 so->so_options |= SO_LINGER; 884 } else { 885 so->so_linger.l_onoff = 0; 886 so->so_options &= ~SO_LINGER; 887 } 888 break; 889 } 890 891 case SO_DEBUG: 892 case SO_REUSEADDR: 893 case SO_KEEPALIVE: 894 case SO_DONTROUTE: 895 case SO_BROADCAST: 896 case SO_USELOOPBACK: 897 case SO_OOBINLINE: 898 case SO_DGRAM_ERRIND: 899 if (intvalue != 0) { 900 dprintso(so, 1, 901 ("sosdp_setsockopt: setting 0x%x\n", 902 option_name)); 903 so->so_options |= option_name; 904 } else { 905 dprintso(so, 1, 906 ("sosdp_setsockopt: clearing 0x%x\n", 907 option_name)); 908 so->so_options &= ~option_name; 909 } 910 break; 911 912 case SO_SNDBUF: 913 so->so_sndbuf = intvalue; 914 if (so->so_sndlowat > so->so_sndbuf) { 915 so->so_sndlowat = so->so_sndbuf; 916 } 917 break; 918 case SO_RCVBUF: 919 so->so_rcvbuf = intvalue; 920 if (so->so_rcvlowat > so->so_rcvbuf) { 921 so->so_rcvlowat = so->so_rcvbuf; 922 } 923 break; 924 case SO_SNDLOWAT: 925 if (so->so_sndlowat > so->so_sndbuf) { 926 so->so_sndlowat = so->so_sndbuf; 927 } 928 break; 929 case SO_RCVLOWAT: 930 if (so->so_rcvlowat > so->so_rcvbuf) { 931 so->so_rcvlowat = so->so_rcvbuf; 932 } 933 break; 934 } 935 #undef intvalue 936 937 if (error != 0) { 938 if ((error == ENOPROTOOPT || error == EPROTO || 939 error == EINVAL) && handled) { 940 dprintso(so, 1, 941 ("sosdp_setsockopt: ignoring error %d " 942 "for 0x%x\n", error, option_name)); 943 error = 0; 944 } 945 } 946 } 947 948 done: 949 so_unlock_single(so, SOLOCKED); 950 mutex_exit(&so->so_lock); 951 952 return (error); 953 } 954 955 /* ARGSUSED */ 956 static int 957 sosdp_ioctl(struct sonode *so, int cmd, intptr_t arg, int mode, 958 struct cred *cr, int32_t *rvalp) 959 { 960 int32_t value; 961 int error, intval; 962 pid_t pid; 963 964 /* handle socket specific ioctls */ 965 switch (cmd) { 966 case FIONBIO: 967 if (so_copyin((void *)arg, &value, sizeof (int32_t), 968 (mode & (int)FKIOCTL))) { 969 return (EFAULT); 970 } 971 mutex_enter(&so->so_lock); 972 if (value != 0) { 973 so->so_state |= SS_NDELAY; 974 } else { 975 so->so_state &= ~SS_NDELAY; 976 } 977 mutex_exit(&so->so_lock); 978 return (0); 979 980 case FIOASYNC: 981 if (so_copyin((void *)arg, &value, sizeof (int32_t), 982 (mode & (int)FKIOCTL))) { 983 return (EFAULT); 984 } 985 mutex_enter(&so->so_lock); 986 987 if (value) { 988 /* Turn on SIGIO */ 989 so->so_state |= SS_ASYNC; 990 } else { 991 /* Turn off SIGIO */ 992 so->so_state &= ~SS_ASYNC; 993 } 994 mutex_exit(&so->so_lock); 995 return (0); 996 997 case SIOCSPGRP: 998 case FIOSETOWN: 999 if (so_copyin((void *)arg, &pid, sizeof (pid_t), 1000 (mode & (int)FKIOCTL))) { 1001 return (EFAULT); 1002 } 1003 mutex_enter(&so->so_lock); 1004 1005 error = (pid != so->so_pgrp) ? socket_chgpgrp(so, pid) : 0; 1006 mutex_exit(&so->so_lock); 1007 return (error); 1008 1009 case SIOCGPGRP: 1010 case FIOGETOWN: 1011 if (so_copyout(&so->so_pgrp, (void *)arg, 1012 sizeof (pid_t), (mode & (int)FKIOCTL))) 1013 return (EFAULT); 1014 return (0); 1015 1016 case SIOCATMARK: 1017 intval = 0; 1018 error = sdp_ioctl( 1019 (struct sdp_conn_struct_t *)so->so_proto_handle, cmd, 1020 &intval, cr); 1021 if (so_copyout(&intval, (void *)arg, sizeof (int), 1022 (mode & (int)FKIOCTL))) 1023 return (EFAULT); 1024 return (0); 1025 1026 1027 case SIOCSENABLESDP: { 1028 int32_t enable; 1029 1030 /* 1031 * System wide enable SDP 1032 */ 1033 1034 if (so_copyin((void *)arg, &enable, sizeof (int32_t), 1035 mode & (int)FKIOCTL)) 1036 return (EFAULT); 1037 1038 error = sdp_ioctl( 1039 (struct sdp_conn_struct_t *)so->so_proto_handle, cmd, 1040 &enable, cr); 1041 if (so_copyout(&enable, (void *)arg, 1042 sizeof (int32_t), (mode & (int)FKIOCTL))) 1043 return (EFAULT); 1044 return (0); 1045 } 1046 /* from strioctl */ 1047 case FIONREAD: 1048 /* 1049 * Return number of bytes of data in all data messages 1050 * in queue in "arg". 1051 * For stream socket, amount of available data. 1052 */ 1053 if (so->so_state & SS_ACCEPTCONN) { 1054 intval = 0; 1055 } else { 1056 mutex_enter(&so->so_lock); 1057 intval = sdp_polldata( 1058 (struct sdp_conn_struct_t *)so->so_proto_handle, 1059 SDP_READ); 1060 mutex_exit(&so->so_lock); 1061 } 1062 if (so_copyout(&intval, (void *)arg, sizeof (intval), 1063 (mode & (int)FKIOCTL))) 1064 return (EFAULT); 1065 return (0); 1066 default: 1067 return (EINVAL); 1068 } 1069 } 1070 1071 /* 1072 * Check socktpi_poll() on why so_lock is not held in this function. 1073 */ 1074 static int 1075 sosdp_poll(struct sonode *so, short events, int anyyet, short *reventsp, 1076 struct pollhead **phpp) 1077 { 1078 short origevents = events; 1079 int so_state; 1080 1081 so_state = so->so_state; 1082 1083 ASSERT(so->so_version != SOV_STREAM); 1084 1085 if (!(so_state & SS_ISCONNECTED) && (so->so_type == SOCK_STREAM)) { 1086 /* 1087 * Not connected yet - turn off write side events 1088 */ 1089 events &= ~(POLLOUT|POLLWRBAND); 1090 } 1091 1092 /* 1093 * Check for errors 1094 */ 1095 if (so->so_error != 0 && 1096 ((POLLIN|POLLRDNORM|POLLOUT) & origevents) != 0) { 1097 *reventsp = (POLLIN|POLLRDNORM|POLLOUT) & origevents; 1098 goto done; 1099 } 1100 1101 *reventsp = 0; 1102 if (so->so_type != SOCK_STREAM) { 1103 goto done; 1104 } 1105 1106 /* 1107 * Don't mark socket writable until TX queued data is below watermark. 1108 */ 1109 if (sdp_polldata((struct sdp_conn_struct_t *)so->so_proto_handle, 1110 SDP_XMIT)) { 1111 *reventsp |= POLLOUT & events; 1112 } 1113 1114 if (sdp_polldata((struct sdp_conn_struct_t *)so->so_proto_handle, 1115 SDP_READ)) { 1116 *reventsp |= (POLLIN|POLLRDNORM) & events; 1117 } 1118 1119 if ((so_state & SS_CANTRCVMORE) || (so->so_acceptq_len > 0)) { 1120 *reventsp |= (POLLIN|POLLRDNORM) & events; 1121 } 1122 1123 done: 1124 if ((*reventsp == 0 && !anyyet) || (events & POLLET)) { 1125 *phpp = &so->so_poll_list; 1126 } 1127 1128 return (0); 1129 } 1130 1131 /* ARGSUSED */ 1132 static int 1133 sosdp_close(struct sonode *so, int flag, struct cred *cr) 1134 { 1135 int error = 0; 1136 1137 mutex_enter(&so->so_lock); 1138 so_lock_single(so); 1139 /* 1140 * Need to set flags as there might be ops in progress on 1141 * this socket. 1142 * 1143 * If socket already disconnected/disconnecting, 1144 * don't send signal (again). 1145 */ 1146 soisdisconnected(so, 0); 1147 mutex_exit(&so->so_lock); 1148 1149 /* 1150 * Initiate connection shutdown. 1151 */ 1152 error = sdp_disconnect((struct sdp_conn_struct_t *)so->so_proto_handle, 1153 flag); 1154 1155 mutex_enter(&so->so_lock); 1156 so_unlock_single(so, SOLOCKED); 1157 so_notify_disconnected(so, B_FALSE, error); 1158 1159 return (error); 1160 } 1161 1162 /* ARGSUSED */ 1163 void 1164 sosdp_fini(struct sonode *so, struct cred *cr) 1165 { 1166 dprint(3, ("sosdp_fini: so:%p so_proto_handle:%p", (void *)so, 1167 (void *)so->so_proto_handle)); 1168 1169 ASSERT(so->so_ops == &sosdp_sonodeops); 1170 1171 if (so->so_proto_handle != NULL) 1172 sdp_close((struct sdp_conn_struct_t *)so->so_proto_handle); 1173 so->so_proto_handle = NULL; 1174 1175 mutex_enter(&so->so_lock); 1176 1177 so_acceptq_flush(so, B_TRUE); 1178 1179 mutex_exit(&so->so_lock); 1180 1181 sonode_fini(so); 1182 } 1183 1184 /* 1185 * Upcalls from SDP 1186 */ 1187 1188 /* 1189 * Incoming connection on listen socket. 1190 */ 1191 static void * 1192 sdp_sock_newconn(void *parenthandle, void *connind) 1193 { 1194 struct sonode *lso = parenthandle; 1195 struct sonode *nso; 1196 int error; 1197 1198 ASSERT(lso->so_state & SS_ACCEPTCONN); 1199 ASSERT(lso->so_proto_handle != NULL); /* closed conn */ 1200 ASSERT(lso->so_type == SOCK_STREAM); 1201 1202 dprint(3, ("sosdp_newconn A: so:%p so_proto_handle:%p", (void *)lso, 1203 (void *)lso->so_proto_handle)); 1204 1205 /* 1206 * Check current # of queued conns against backlog 1207 */ 1208 if (lso->so_rcv_queued >= lso->so_backlog) { 1209 return (NULL); 1210 } 1211 1212 nso = socket_newconn(lso, connind, NULL, SOCKET_NOSLEEP, &error); 1213 if (nso == NULL) { 1214 eprintsoline(lso, error); 1215 return (NULL); 1216 } 1217 1218 dprint(2, ("sdp_stream_newconn: new %p\n", (void *)nso)); 1219 1220 (void) so_acceptq_enqueue(lso, nso); 1221 1222 mutex_enter(&lso->so_lock); 1223 so_notify_newconn(lso); 1224 return (nso); 1225 } 1226 1227 /* 1228 * For outgoing connections, the connection has been established. 1229 */ 1230 static void 1231 sdp_sock_connected(void *handle) 1232 { 1233 struct sonode *so = handle; 1234 1235 ASSERT(so->so_type == SOCK_STREAM); 1236 dprint(3, ("sosdp_connected C: so:%p so_proto_handle:%p", (void *)so, 1237 (void *)so->so_proto_handle)); 1238 1239 mutex_enter(&so->so_lock); 1240 ASSERT(so->so_proto_handle); /* closed conn */ 1241 1242 ASSERT(!(so->so_state & SS_ACCEPTCONN)); 1243 soisconnected(so); 1244 1245 so_notify_connected(so); 1246 } 1247 1248 /* 1249 * Connection got disconnected. Either with an error, or through 1250 * normal handshake. 1251 */ 1252 static void 1253 sdp_sock_disconnected(void *handle, int error) 1254 { 1255 struct sonode *so = handle; 1256 1257 ASSERT(so->so_type == SOCK_STREAM); 1258 dprint(2, ("sosdp_disconnected C: so:%p so_proto_handle:%p error:%d", 1259 (void *)so, (void *)so->so_proto_handle, error)); 1260 1261 mutex_enter(&so->so_lock); 1262 ASSERT(so->so_proto_handle != NULL); /* closed conn */ 1263 1264 soisdisconnected(so, error); 1265 so_notify_disconnected(so, B_FALSE, error); 1266 } 1267 1268 /* 1269 * Incoming data. 1270 */ 1271 /*ARGSUSED*/ 1272 static int 1273 sdp_sock_recv(void *handle, mblk_t *mp, int flags) 1274 { 1275 struct sonode *so = handle; 1276 1277 ASSERT(so->so_type == SOCK_STREAM); 1278 1279 mutex_enter(&so->so_lock); 1280 so_notify_data(so, 0); 1281 1282 return (so->so_rcvbuf); 1283 } 1284 1285 /* 1286 * TX queued data got acknowledged. 1287 */ 1288 static void 1289 sdp_sock_xmitted(void *handle, int writeable) 1290 { 1291 struct sonode *so = handle; 1292 1293 dprint(4, ("sosdp_sock_xmitted: so:%p so_proto_handle:%p txq:%d", 1294 (void *)so, (void *)so->so_proto_handle, writeable)); 1295 mutex_enter(&so->so_lock); 1296 ASSERT(so->so_proto_handle != NULL); /* closed conn */ 1297 1298 1299 /* 1300 * Only do pollwakeup if the amount of queued data is less than 1301 * watermark. 1302 */ 1303 if (!writeable) { 1304 so_notify_writable(so); 1305 } else { 1306 mutex_exit(&so->so_lock); 1307 } 1308 } 1309 1310 1311 /* 1312 * SDP notifies socket for presence of urgent data. 1313 */ 1314 static void 1315 sdp_sock_urgdata(void *handle) 1316 { 1317 struct sonode *so = handle; 1318 1319 ASSERT(so->so_type == SOCK_STREAM); 1320 1321 mutex_enter(&so->so_lock); 1322 1323 ASSERT(so->so_proto_handle != NULL); /* closed conn */ 1324 so_notify_oobsig(so); 1325 } 1326 1327 /* 1328 * SDP notifies socket about receiving of conn close request from peer side. 1329 */ 1330 static void 1331 sdp_sock_ordrel(void *handle) 1332 { 1333 struct sonode *so = handle; 1334 1335 ASSERT(so->so_type == SOCK_STREAM); 1336 1337 dprint(4, ("sdp_sock_ordrel : so:%p, so_proto_handle:%p", 1338 (void *)so, (void *)so->so_proto_handle)); 1339 mutex_enter(&so->so_lock); 1340 socantrcvmore(so); 1341 so_notify_eof(so); 1342 } 1343 1344 static void 1345 sdp_sock_connfail(void *handle, int error) 1346 { 1347 struct sonode *so = handle; 1348 1349 dprint(3, ("sosdp_conn Failed: so:%p so_proto_handle:%p", (void *)so, 1350 (void *)so->so_proto_handle)); 1351 mutex_enter(&so->so_lock); 1352 ASSERT(so->so_proto_handle != NULL); /* closed conn */ 1353 so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 1354 so->so_error = (ushort_t)error; 1355 mutex_exit(&so->so_lock); 1356 cv_broadcast(&so->so_state_cv); 1357 } 1358