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