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 2010 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/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 *, const 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, const 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 return (0); 1099 } 1100 1101 *reventsp = 0; 1102 1103 /* 1104 * Don't mark socket as writable until TX queued data is 1105 * below watermark. 1106 */ 1107 if (so->so_type == SOCK_STREAM) { 1108 if (sdp_polldata( 1109 (struct sdp_conn_struct_t *)so->so_proto_handle, 1110 SDP_XMIT)) { 1111 *reventsp |= POLLOUT & events; 1112 } 1113 } else { 1114 *reventsp = 0; 1115 goto done; 1116 } 1117 1118 if (sdp_polldata((struct sdp_conn_struct_t *)so->so_proto_handle, 1119 SDP_READ)) { 1120 *reventsp |= (POLLIN|POLLRDNORM) & events; 1121 } 1122 1123 if ((so_state & SS_CANTRCVMORE) || (so->so_acceptq_head != NULL)) { 1124 *reventsp |= (POLLIN|POLLRDNORM) & events; 1125 } 1126 1127 done: 1128 if (!*reventsp && !anyyet) { 1129 *phpp = &so->so_poll_list; 1130 } 1131 1132 return (0); 1133 } 1134 1135 /* ARGSUSED */ 1136 static int 1137 sosdp_close(struct sonode *so, int flag, struct cred *cr) 1138 { 1139 int error = 0; 1140 1141 mutex_enter(&so->so_lock); 1142 so_lock_single(so); 1143 /* 1144 * Need to set flags as there might be ops in progress on 1145 * this socket. 1146 * 1147 * If socket already disconnected/disconnecting, 1148 * don't send signal (again). 1149 */ 1150 soisdisconnected(so, 0); 1151 mutex_exit(&so->so_lock); 1152 1153 /* 1154 * Initiate connection shutdown. 1155 */ 1156 error = sdp_disconnect((struct sdp_conn_struct_t *)so->so_proto_handle, 1157 flag); 1158 1159 mutex_enter(&so->so_lock); 1160 so_unlock_single(so, SOLOCKED); 1161 so_notify_disconnected(so, error); 1162 1163 return (error); 1164 } 1165 1166 /* ARGSUSED */ 1167 void 1168 sosdp_fini(struct sonode *so, struct cred *cr) 1169 { 1170 dprint(3, ("sosdp_fini: so:%p so_proto_handle:%p", (void *)so, 1171 (void *)so->so_proto_handle)); 1172 1173 ASSERT(so->so_ops == &sosdp_sonodeops); 1174 1175 if (so->so_proto_handle != NULL) 1176 sdp_close((struct sdp_conn_struct_t *)so->so_proto_handle); 1177 so->so_proto_handle = NULL; 1178 1179 mutex_enter(&so->so_lock); 1180 1181 so_acceptq_flush(so, B_TRUE); 1182 1183 mutex_exit(&so->so_lock); 1184 1185 sonode_fini(so); 1186 } 1187 1188 /* 1189 * Upcalls from SDP 1190 */ 1191 1192 /* 1193 * Incoming connection on listen socket. 1194 */ 1195 static void * 1196 sdp_sock_newconn(void *parenthandle, void *connind) 1197 { 1198 struct sonode *lso = parenthandle; 1199 struct sonode *nso; 1200 int error; 1201 1202 ASSERT(lso->so_state & SS_ACCEPTCONN); 1203 ASSERT(lso->so_proto_handle != NULL); /* closed conn */ 1204 ASSERT(lso->so_type == SOCK_STREAM); 1205 1206 dprint(3, ("sosdp_newconn A: so:%p so_proto_handle:%p", (void *)lso, 1207 (void *)lso->so_proto_handle)); 1208 1209 /* 1210 * Check current # of queued conns against backlog 1211 */ 1212 if (lso->so_rcv_queued >= lso->so_backlog) { 1213 return (NULL); 1214 } 1215 1216 nso = socket_newconn(lso, connind, NULL, SOCKET_NOSLEEP, &error); 1217 if (nso == NULL) { 1218 eprintsoline(lso, error); 1219 return (NULL); 1220 } 1221 1222 dprint(2, ("sdp_stream_newconn: new %p\n", (void *)nso)); 1223 1224 (void) so_acceptq_enqueue(lso, nso); 1225 1226 mutex_enter(&lso->so_lock); 1227 so_notify_newconn(lso); 1228 return (nso); 1229 } 1230 1231 /* 1232 * For outgoing connections, the connection has been established. 1233 */ 1234 static void 1235 sdp_sock_connected(void *handle) 1236 { 1237 struct sonode *so = handle; 1238 1239 ASSERT(so->so_type == SOCK_STREAM); 1240 dprint(3, ("sosdp_connected C: so:%p so_proto_handle:%p", (void *)so, 1241 (void *)so->so_proto_handle)); 1242 1243 mutex_enter(&so->so_lock); 1244 ASSERT(so->so_proto_handle); /* closed conn */ 1245 1246 ASSERT(!(so->so_state & SS_ACCEPTCONN)); 1247 soisconnected(so); 1248 1249 so_notify_connected(so); 1250 } 1251 1252 /* 1253 * Connection got disconnected. Either with an error, or through 1254 * normal handshake. 1255 */ 1256 static void 1257 sdp_sock_disconnected(void *handle, int error) 1258 { 1259 struct sonode *so = handle; 1260 1261 ASSERT(so->so_type == SOCK_STREAM); 1262 dprint(2, ("sosdp_disconnected C: so:%p so_proto_handle:%p error:%d", 1263 (void *)so, (void *)so->so_proto_handle, error)); 1264 1265 mutex_enter(&so->so_lock); 1266 ASSERT(so->so_proto_handle != NULL); /* closed conn */ 1267 1268 soisdisconnected(so, error); 1269 so_notify_disconnected(so, error); 1270 } 1271 1272 /* 1273 * Incoming data. 1274 */ 1275 /*ARGSUSED*/ 1276 static int 1277 sdp_sock_recv(void *handle, mblk_t *mp, int flags) 1278 { 1279 struct sonode *so = handle; 1280 1281 ASSERT(so->so_type == SOCK_STREAM); 1282 1283 mutex_enter(&so->so_lock); 1284 so_notify_data(so, 0); 1285 1286 return (so->so_rcvbuf); 1287 } 1288 1289 /* 1290 * TX queued data got acknowledged. 1291 */ 1292 static void 1293 sdp_sock_xmitted(void *handle, int writeable) 1294 { 1295 struct sonode *so = handle; 1296 1297 dprint(4, ("sosdp_sock_xmitted: so:%p so_proto_handle:%p txq:%d", 1298 (void *)so, (void *)so->so_proto_handle, writeable)); 1299 mutex_enter(&so->so_lock); 1300 ASSERT(so->so_proto_handle != NULL); /* closed conn */ 1301 1302 1303 /* 1304 * Only do pollwakeup if the amount of queued data is less than 1305 * watermark. 1306 */ 1307 if (!writeable) { 1308 so_notify_writable(so); 1309 } else { 1310 mutex_exit(&so->so_lock); 1311 } 1312 } 1313 1314 1315 /* 1316 * SDP notifies socket for presence of urgent data. 1317 */ 1318 static void 1319 sdp_sock_urgdata(void *handle) 1320 { 1321 struct sonode *so = handle; 1322 1323 ASSERT(so->so_type == SOCK_STREAM); 1324 1325 mutex_enter(&so->so_lock); 1326 1327 ASSERT(so->so_proto_handle != NULL); /* closed conn */ 1328 so_notify_oobsig(so); 1329 } 1330 1331 /* 1332 * SDP notifies socket about receiving of conn close request from peer side. 1333 */ 1334 static void 1335 sdp_sock_ordrel(void *handle) 1336 { 1337 struct sonode *so = handle; 1338 1339 ASSERT(so->so_type == SOCK_STREAM); 1340 1341 dprint(4, ("sdp_sock_ordrel : so:%p, so_proto_handle:%p", 1342 (void *)so, (void *)so->so_proto_handle)); 1343 mutex_enter(&so->so_lock); 1344 socantrcvmore(so); 1345 so_notify_eof(so); 1346 } 1347 1348 static void 1349 sdp_sock_connfail(void *handle, int error) 1350 { 1351 struct sonode *so = handle; 1352 1353 dprint(3, ("sosdp_conn Failed: so:%p so_proto_handle:%p", (void *)so, 1354 (void *)so->so_proto_handle)); 1355 mutex_enter(&so->so_lock); 1356 ASSERT(so->so_proto_handle != NULL); /* closed conn */ 1357 so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 1358 so->so_error = (ushort_t)error; 1359 mutex_exit(&so->so_lock); 1360 cv_broadcast(&so->so_state_cv); 1361 } 1362