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 2011 Nexenta Systems, Inc. All rights reserved. 24 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 25 * Copyright (c) 2014, Joyent, Inc. All rights reserved. 26 */ 27 28 #include <sys/file.h> 29 #include <sys/stropts.h> 30 #include <sys/socket.h> 31 #include <sys/socketvar.h> 32 #include <sys/sysmacros.h> 33 #include <sys/filio.h> /* FIO* ioctls */ 34 #include <sys/sockio.h> /* SIOC* ioctls */ 35 #include <sys/poll_impl.h> 36 #include <sys/cmn_err.h> 37 #include <sys/ksocket.h> 38 #include <io/ksocket/ksocket_impl.h> 39 #include <fs/sockfs/sockcommon.h> 40 41 #define SOCKETMOD_TCP "tcp" 42 #define SOCKETMOD_UDP "udp" 43 /* 44 * Kernel Sockets 45 * 46 * Mostly a wrapper around the private socket_* functions. 47 */ 48 int 49 ksocket_socket(ksocket_t *ksp, int domain, int type, int protocol, int flags, 50 struct cred *cr) 51 { 52 static const int version = SOV_DEFAULT; 53 int error = 0; 54 struct sonode *so; 55 *ksp = NULL; 56 57 /* All Solaris components should pass a cred for this operation. */ 58 ASSERT(cr != NULL); 59 60 if (domain == AF_NCA) 61 return (EAFNOSUPPORT); 62 63 ASSERT(flags == KSOCKET_SLEEP || flags == KSOCKET_NOSLEEP); 64 so = socket_create(domain, type, protocol, NULL, NULL, version, flags, 65 cr, &error); 66 if (so == NULL) { 67 if (error == EAFNOSUPPORT) { 68 char *mod = NULL; 69 70 /* 71 * Could be that root file system is not loaded or 72 * soconfig has not run yet. 73 */ 74 if (type == SOCK_STREAM && (domain == AF_INET || 75 domain == AF_INET6) && (protocol == 0 || 76 protocol == IPPROTO_TCP)) { 77 mod = SOCKETMOD_TCP; 78 } else if (type == SOCK_DGRAM && (domain == AF_INET || 79 domain == AF_INET6) && (protocol == 0 || 80 protocol == IPPROTO_UDP)) { 81 mod = SOCKETMOD_UDP; 82 } else { 83 return (EAFNOSUPPORT); 84 } 85 86 so = socket_create(domain, type, protocol, NULL, 87 mod, version, flags, cr, &error); 88 if (so == NULL) 89 return (error); 90 } else { 91 return (error); 92 } 93 } 94 95 so->so_mode |= SM_KERNEL; 96 97 *ksp = SOTOKS(so); 98 99 return (0); 100 } 101 int 102 ksocket_bind(ksocket_t ks, struct sockaddr *addr, socklen_t addrlen, 103 struct cred *cr) 104 { 105 int error; 106 107 /* All Solaris components should pass a cred for this operation. */ 108 ASSERT(cr != NULL); 109 110 if (!KSOCKET_VALID(ks)) 111 return (ENOTSOCK); 112 113 error = socket_bind(KSTOSO(ks), addr, addrlen, _SOBIND_SOCKBSD, cr); 114 115 return (error); 116 } 117 118 int 119 ksocket_listen(ksocket_t ks, int backlog, struct cred *cr) 120 { 121 /* All Solaris components should pass a cred for this operation. */ 122 ASSERT(cr != NULL); 123 124 if (!KSOCKET_VALID(ks)) 125 return (ENOTSOCK); 126 127 return (socket_listen(KSTOSO(ks), backlog, cr)); 128 } 129 130 int 131 ksocket_accept(ksocket_t ks, struct sockaddr *addr, 132 socklen_t *addrlenp, ksocket_t *nks, struct cred *cr) 133 { 134 int error; 135 struct sonode *nso = NULL; 136 137 /* All Solaris components should pass a cred for this operation. */ 138 ASSERT(cr != NULL); 139 140 *nks = NULL; 141 142 if (!KSOCKET_VALID(ks)) 143 return (ENOTSOCK); 144 145 if (addr != NULL && addrlenp == NULL) 146 return (EFAULT); 147 148 error = socket_accept(KSTOSO(ks), KSOCKET_FMODE(ks), cr, &nso); 149 if (error != 0) 150 return (error); 151 152 ASSERT(nso != NULL); 153 154 nso->so_mode |= SM_KERNEL; 155 156 if (addr != NULL && addrlenp != NULL) { 157 error = socket_getpeername(nso, addr, addrlenp, B_TRUE, cr); 158 if (error != 0) { 159 (void) socket_close(nso, 0, cr); 160 socket_destroy(nso); 161 return ((error == ENOTCONN) ? ECONNABORTED : error); 162 } 163 } 164 165 *nks = SOTOKS(nso); 166 167 return (error); 168 } 169 170 int 171 ksocket_connect(ksocket_t ks, struct sockaddr *addr, socklen_t addrlen, 172 struct cred *cr) 173 { 174 /* All Solaris components should pass a cred for this operation. */ 175 ASSERT(cr != NULL); 176 177 if (!KSOCKET_VALID(ks)) 178 return (ENOTSOCK); 179 180 return (socket_connect(KSTOSO(ks), addr, addrlen, 181 KSOCKET_FMODE(ks), 0, cr)); 182 } 183 184 int 185 ksocket_send(ksocket_t ks, void *msg, size_t msglen, int flags, 186 size_t *sent, struct cred *cr) 187 { 188 int error; 189 struct nmsghdr msghdr; 190 struct uio auio; 191 struct iovec iov; 192 193 /* All Solaris components should pass a cred for this operation. */ 194 ASSERT(cr != NULL); 195 196 if (!KSOCKET_VALID(ks)) { 197 if (sent != NULL) 198 *sent = 0; 199 return (ENOTSOCK); 200 } 201 202 iov.iov_base = msg; 203 iov.iov_len = msglen; 204 205 bzero(&auio, sizeof (struct uio)); 206 auio.uio_loffset = 0; 207 auio.uio_iov = &iov; 208 auio.uio_iovcnt = 1; 209 auio.uio_resid = msglen; 210 if (flags & MSG_USERSPACE) 211 auio.uio_segflg = UIO_USERSPACE; 212 else 213 auio.uio_segflg = UIO_SYSSPACE; 214 auio.uio_extflg = UIO_COPY_DEFAULT; 215 auio.uio_limit = 0; 216 auio.uio_fmode = KSOCKET_FMODE(ks); 217 218 msghdr.msg_name = NULL; 219 msghdr.msg_namelen = 0; 220 msghdr.msg_control = NULL; 221 msghdr.msg_controllen = 0; 222 msghdr.msg_flags = flags | MSG_EOR; 223 224 error = socket_sendmsg(KSTOSO(ks), &msghdr, &auio, cr); 225 if (error != 0) { 226 if (sent != NULL) 227 *sent = 0; 228 return (error); 229 } 230 231 if (sent != NULL) 232 *sent = msglen - auio.uio_resid; 233 return (0); 234 } 235 236 int 237 ksocket_sendto(ksocket_t ks, void *msg, size_t msglen, int flags, 238 struct sockaddr *name, socklen_t namelen, size_t *sent, struct cred *cr) 239 { 240 int error; 241 struct nmsghdr msghdr; 242 struct uio auio; 243 struct iovec iov; 244 245 /* All Solaris components should pass a cred for this operation. */ 246 ASSERT(cr != NULL); 247 248 if (!KSOCKET_VALID(ks)) { 249 if (sent != NULL) 250 *sent = 0; 251 return (ENOTSOCK); 252 } 253 254 iov.iov_base = msg; 255 iov.iov_len = msglen; 256 257 bzero(&auio, sizeof (struct uio)); 258 auio.uio_loffset = 0; 259 auio.uio_iov = &iov; 260 auio.uio_iovcnt = 1; 261 auio.uio_resid = msglen; 262 if (flags & MSG_USERSPACE) 263 auio.uio_segflg = UIO_USERSPACE; 264 else 265 auio.uio_segflg = UIO_SYSSPACE; 266 auio.uio_extflg = UIO_COPY_DEFAULT; 267 auio.uio_limit = 0; 268 auio.uio_fmode = KSOCKET_FMODE(ks); 269 270 msghdr.msg_iov = &iov; 271 msghdr.msg_iovlen = 1; 272 msghdr.msg_name = (char *)name; 273 msghdr.msg_namelen = namelen; 274 msghdr.msg_control = NULL; 275 msghdr.msg_controllen = 0; 276 msghdr.msg_flags = flags | MSG_EOR; 277 278 error = socket_sendmsg(KSTOSO(ks), &msghdr, &auio, cr); 279 if (error != 0) { 280 if (sent != NULL) 281 *sent = 0; 282 return (error); 283 } 284 if (sent != NULL) 285 *sent = msglen - auio.uio_resid; 286 return (0); 287 } 288 289 int 290 ksocket_sendmsg(ksocket_t ks, struct nmsghdr *msg, int flags, 291 size_t *sent, struct cred *cr) 292 { 293 int error; 294 ssize_t len; 295 int i; 296 struct uio auio; 297 298 /* All Solaris components should pass a cred for this operation. */ 299 ASSERT(cr != NULL); 300 301 if (!KSOCKET_VALID(ks)) { 302 if (sent != NULL) 303 *sent = 0; 304 return (ENOTSOCK); 305 } 306 307 bzero(&auio, sizeof (struct uio)); 308 auio.uio_loffset = 0; 309 auio.uio_iov = msg->msg_iov; 310 auio.uio_iovcnt = msg->msg_iovlen; 311 if (flags & MSG_USERSPACE) 312 auio.uio_segflg = UIO_USERSPACE; 313 else 314 auio.uio_segflg = UIO_SYSSPACE; 315 auio.uio_extflg = UIO_COPY_DEFAULT; 316 auio.uio_limit = 0; 317 auio.uio_fmode = KSOCKET_FMODE(ks); 318 len = 0; 319 for (i = 0; i < msg->msg_iovlen; i++) { 320 ssize_t iovlen; 321 iovlen = (msg->msg_iov)[i].iov_len; 322 len += iovlen; 323 if (len < 0 || iovlen < 0) 324 return (EINVAL); 325 } 326 auio.uio_resid = len; 327 328 msg->msg_flags = flags | MSG_EOR; 329 330 error = socket_sendmsg(KSTOSO(ks), msg, &auio, cr); 331 if (error != 0) { 332 if (sent != NULL) 333 *sent = 0; 334 return (error); 335 } 336 337 if (sent != NULL) 338 *sent = len - auio.uio_resid; 339 return (0); 340 } 341 342 343 int 344 ksocket_recv(ksocket_t ks, void *msg, size_t msglen, int flags, 345 size_t *recv, struct cred *cr) 346 { 347 int error; 348 struct nmsghdr msghdr; 349 struct uio auio; 350 struct iovec iov; 351 352 /* All Solaris components should pass a cred for this operation. */ 353 ASSERT(cr != NULL); 354 355 if (!KSOCKET_VALID(ks)) { 356 if (recv != NULL) 357 *recv = 0; 358 return (ENOTSOCK); 359 } 360 361 iov.iov_base = msg; 362 iov.iov_len = msglen; 363 364 bzero(&auio, sizeof (struct uio)); 365 auio.uio_loffset = 0; 366 auio.uio_iov = &iov; 367 auio.uio_iovcnt = 1; 368 auio.uio_resid = msglen; 369 if (flags & MSG_USERSPACE) 370 auio.uio_segflg = UIO_USERSPACE; 371 else 372 auio.uio_segflg = UIO_SYSSPACE; 373 auio.uio_extflg = UIO_COPY_DEFAULT; 374 auio.uio_limit = 0; 375 auio.uio_fmode = KSOCKET_FMODE(ks); 376 377 msghdr.msg_name = NULL; 378 msghdr.msg_namelen = 0; 379 msghdr.msg_control = NULL; 380 msghdr.msg_controllen = 0; 381 msghdr.msg_flags = flags & (MSG_OOB | MSG_PEEK | MSG_WAITALL | 382 MSG_DONTWAIT | MSG_USERSPACE); 383 384 error = socket_recvmsg(KSTOSO(ks), &msghdr, &auio, cr); 385 if (error != 0) { 386 if (recv != NULL) 387 *recv = 0; 388 return (error); 389 } 390 391 if (recv != NULL) 392 *recv = msglen - auio.uio_resid; 393 return (0); 394 } 395 396 int 397 ksocket_recvfrom(ksocket_t ks, void *msg, size_t msglen, int flags, 398 struct sockaddr *name, socklen_t *namelen, size_t *recv, struct cred *cr) 399 { 400 int error; 401 struct nmsghdr msghdr; 402 struct uio auio; 403 struct iovec iov; 404 405 /* All Solaris components should pass a cred for this operation. */ 406 ASSERT(cr != NULL); 407 408 if (!KSOCKET_VALID(ks)) { 409 if (recv != NULL) 410 *recv = 0; 411 return (ENOTSOCK); 412 } 413 414 iov.iov_base = msg; 415 iov.iov_len = msglen; 416 417 bzero(&auio, sizeof (struct uio)); 418 auio.uio_loffset = 0; 419 auio.uio_iov = &iov; 420 auio.uio_iovcnt = 1; 421 auio.uio_resid = msglen; 422 if (flags & MSG_USERSPACE) 423 auio.uio_segflg = UIO_USERSPACE; 424 else 425 auio.uio_segflg = UIO_SYSSPACE; 426 auio.uio_extflg = UIO_COPY_DEFAULT; 427 auio.uio_limit = 0; 428 auio.uio_fmode = KSOCKET_FMODE(ks); 429 430 msghdr.msg_name = (char *)name; 431 msghdr.msg_namelen = *namelen; 432 msghdr.msg_control = NULL; 433 msghdr.msg_controllen = 0; 434 msghdr.msg_flags = flags & (MSG_OOB | MSG_PEEK | MSG_WAITALL | 435 MSG_DONTWAIT | MSG_USERSPACE); 436 437 error = socket_recvmsg(KSTOSO(ks), &msghdr, &auio, cr); 438 if (error != 0) { 439 if (recv != NULL) 440 *recv = 0; 441 return (error); 442 } 443 if (recv != NULL) 444 *recv = msglen - auio.uio_resid; 445 446 bcopy(msghdr.msg_name, name, msghdr.msg_namelen); 447 bcopy(&msghdr.msg_namelen, namelen, sizeof (msghdr.msg_namelen)); 448 return (0); 449 } 450 451 int 452 ksocket_recvmsg(ksocket_t ks, struct nmsghdr *msg, int flags, size_t *recv, 453 struct cred *cr) 454 { 455 int error; 456 ssize_t len; 457 int i; 458 struct uio auio; 459 460 /* All Solaris components should pass a cred for this operation. */ 461 ASSERT(cr != NULL); 462 463 if (!KSOCKET_VALID(ks)) { 464 if (recv != NULL) 465 *recv = 0; 466 return (ENOTSOCK); 467 } 468 469 bzero(&auio, sizeof (struct uio)); 470 auio.uio_loffset = 0; 471 auio.uio_iov = msg->msg_iov; 472 auio.uio_iovcnt = msg->msg_iovlen; 473 if (msg->msg_flags & MSG_USERSPACE) 474 auio.uio_segflg = UIO_USERSPACE; 475 else 476 auio.uio_segflg = UIO_SYSSPACE; 477 auio.uio_extflg = UIO_COPY_DEFAULT; 478 auio.uio_limit = 0; 479 auio.uio_fmode = KSOCKET_FMODE(ks); 480 len = 0; 481 482 for (i = 0; i < msg->msg_iovlen; i++) { 483 ssize_t iovlen; 484 iovlen = (msg->msg_iov)[i].iov_len; 485 len += iovlen; 486 if (len < 0 || iovlen < 0) 487 return (EINVAL); 488 } 489 auio.uio_resid = len; 490 491 msg->msg_flags = flags & (MSG_OOB | MSG_PEEK | MSG_WAITALL | 492 MSG_DONTWAIT | MSG_USERSPACE); 493 494 error = socket_recvmsg(KSTOSO(ks), msg, &auio, cr); 495 if (error != 0) { 496 if (recv != NULL) 497 *recv = 0; 498 return (error); 499 } 500 if (recv != NULL) 501 *recv = len - auio.uio_resid; 502 return (0); 503 504 } 505 506 int 507 ksocket_shutdown(ksocket_t ks, int how, struct cred *cr) 508 { 509 struct sonode *so; 510 511 /* All Solaris components should pass a cred for this operation. */ 512 ASSERT(cr != NULL); 513 514 if (!KSOCKET_VALID(ks)) 515 return (ENOTSOCK); 516 517 so = KSTOSO(ks); 518 519 return (socket_shutdown(so, how, cr)); 520 } 521 522 int 523 ksocket_close(ksocket_t ks, struct cred *cr) 524 { 525 struct sonode *so; 526 so = KSTOSO(ks); 527 528 /* All Solaris components should pass a cred for this operation. */ 529 ASSERT(cr != NULL); 530 531 mutex_enter(&so->so_lock); 532 533 if (!KSOCKET_VALID(ks)) { 534 mutex_exit(&so->so_lock); 535 return (ENOTSOCK); 536 } 537 538 so->so_state |= SS_CLOSING; 539 540 if (so->so_count > 1) { 541 mutex_enter(&so->so_acceptq_lock); 542 cv_broadcast(&so->so_acceptq_cv); 543 mutex_exit(&so->so_acceptq_lock); 544 cv_broadcast(&so->so_rcv_cv); 545 cv_broadcast(&so->so_state_cv); 546 cv_broadcast(&so->so_single_cv); 547 cv_broadcast(&so->so_read_cv); 548 cv_broadcast(&so->so_snd_cv); 549 cv_broadcast(&so->so_copy_cv); 550 } 551 while (so->so_count > 1) 552 cv_wait(&so->so_closing_cv, &so->so_lock); 553 554 mutex_exit(&so->so_lock); 555 /* Remove callbacks, if any */ 556 (void) ksocket_setcallbacks(ks, NULL, NULL, cr); 557 558 (void) socket_close(so, 0, cr); 559 socket_destroy(so); 560 561 return (0); 562 } 563 564 int 565 ksocket_getsockname(ksocket_t ks, struct sockaddr *addr, socklen_t *addrlen, 566 struct cred *cr) 567 { 568 struct sonode *so; 569 570 /* All Solaris components should pass a cred for this operation. */ 571 ASSERT(cr != NULL); 572 573 if (!KSOCKET_VALID(ks)) 574 return (ENOTSOCK); 575 576 so = KSTOSO(ks); 577 578 if (addrlen == NULL || (addr == NULL && *addrlen != 0)) 579 return (EFAULT); 580 581 return (socket_getsockname(so, addr, addrlen, cr)); 582 } 583 584 int 585 ksocket_getpeername(ksocket_t ks, struct sockaddr *addr, socklen_t *addrlen, 586 struct cred *cr) 587 { 588 struct sonode *so; 589 590 /* All Solaris components should pass a cred for this operation. */ 591 ASSERT(cr != NULL); 592 593 if (!KSOCKET_VALID(ks)) 594 return (ENOTSOCK); 595 596 so = KSTOSO(ks); 597 598 if (addrlen == NULL || (addr == NULL && *addrlen != 0)) 599 return (EFAULT); 600 601 return (socket_getpeername(so, addr, addrlen, B_FALSE, cr)); 602 } 603 604 int 605 ksocket_getsockopt(ksocket_t ks, int level, int optname, void *optval, 606 int *optlen, struct cred *cr) 607 { 608 struct sonode *so; 609 610 /* All Solaris components should pass a cred for this operation. */ 611 ASSERT(cr != NULL); 612 613 if (!KSOCKET_VALID(ks)) 614 return (ENOTSOCK); 615 616 so = KSTOSO(ks); 617 618 if (optlen == NULL) 619 return (EFAULT); 620 if (*optlen > SO_MAXARGSIZE) 621 return (EINVAL); 622 623 return (socket_getsockopt(so, level, optname, optval, 624 (socklen_t *)optlen, 0, cr)); 625 } 626 627 int 628 ksocket_setsockopt(ksocket_t ks, int level, int optname, const void *optval, 629 int optlen, struct cred *cr) 630 { 631 struct sonode *so; 632 633 /* All Solaris components should pass a cred for this operation. */ 634 ASSERT(cr != NULL); 635 636 if (!KSOCKET_VALID(ks)) 637 return (ENOTSOCK); 638 639 so = KSTOSO(ks); 640 641 if (optval == NULL) 642 optlen = 0; 643 644 return (socket_setsockopt(so, level, optname, optval, 645 (t_uscalar_t)optlen, cr)); 646 } 647 648 /* ARGSUSED */ 649 int 650 ksocket_setcallbacks(ksocket_t ks, ksocket_callbacks_t *cb, void *arg, 651 struct cred *cr) 652 { 653 struct sonode *so; 654 655 /* All Solaris components should pass a cred for this operation. */ 656 ASSERT(cr != NULL); 657 658 if (!KSOCKET_VALID(ks)) 659 return (ENOTSOCK); 660 661 so = KSTOSO(ks); 662 663 if (cb == NULL && arg != NULL) 664 return (EFAULT); 665 if (cb == NULL) { 666 mutex_enter(&so->so_lock); 667 bzero(&(so->so_ksock_callbacks), sizeof (ksocket_callbacks_t)); 668 so->so_ksock_cb_arg = NULL; 669 mutex_exit(&so->so_lock); 670 } else { 671 mutex_enter(&so->so_lock); 672 SETCALLBACK(so, cb, connected, KSOCKET_CB_CONNECTED) 673 SETCALLBACK(so, cb, connectfailed, KSOCKET_CB_CONNECTFAILED) 674 SETCALLBACK(so, cb, disconnected, KSOCKET_CB_DISCONNECTED) 675 SETCALLBACK(so, cb, newdata, KSOCKET_CB_NEWDATA) 676 SETCALLBACK(so, cb, newconn, KSOCKET_CB_NEWCONN) 677 SETCALLBACK(so, cb, cansend, KSOCKET_CB_CANSEND) 678 SETCALLBACK(so, cb, oobdata, KSOCKET_CB_OOBDATA) 679 SETCALLBACK(so, cb, cantsendmore, KSOCKET_CB_CANTSENDMORE) 680 SETCALLBACK(so, cb, cantrecvmore, KSOCKET_CB_CANTRECVMORE) 681 so->so_ksock_cb_arg = arg; 682 mutex_exit(&so->so_lock); 683 } 684 return (0); 685 } 686 687 int 688 ksocket_ioctl(ksocket_t ks, int cmd, intptr_t arg, int *rvalp, struct cred *cr) 689 { 690 struct sonode *so; 691 int rval; 692 693 /* All Solaris components should pass a cred for this operation. */ 694 ASSERT(cr != NULL); 695 696 if (!KSOCKET_VALID(ks)) 697 return (ENOTSOCK); 698 699 so = KSTOSO(ks); 700 701 switch (cmd) { 702 default: 703 /* STREAM iotcls are not supported */ 704 if ((cmd & 0xffffff00U) == STR) { 705 rval = EOPNOTSUPP; 706 } else { 707 rval = socket_ioctl(so, cmd, arg, 708 KSOCKET_FMODE(ks) | FKIOCTL, cr, rvalp); 709 } 710 break; 711 case FIOASYNC: 712 case SIOCSPGRP: 713 case FIOSETOWN: 714 case SIOCGPGRP: 715 case FIOGETOWN: 716 rval = EOPNOTSUPP; 717 break; 718 } 719 720 return (rval); 721 } 722 723 /* 724 * Wait for an input event, similar to t_kspoll(). 725 * Ideas and code borrowed from ../devpoll.c 726 * Basically, setup just enough poll data structures so 727 * we can block on a CV until timeout or pollwakeup(). 728 */ 729 int 730 ksocket_spoll(ksocket_t ks, int timo, short events, short *revents, 731 struct cred *cr) 732 { 733 struct sonode *so; 734 pollhead_t *php, *php2; 735 polldat_t *pdp; 736 pollcache_t *pcp; 737 int error; 738 clock_t expires = 0; 739 clock_t rval; 740 741 /* All Solaris components should pass a cred for this operation. */ 742 ASSERT(cr != NULL); 743 ASSERT(curthread->t_pollcache == NULL); 744 745 if (revents == NULL) 746 return (EINVAL); 747 if (!KSOCKET_VALID(ks)) 748 return (ENOTSOCK); 749 so = KSTOSO(ks); 750 751 /* 752 * Check if there are any events already pending. 753 * If we're not willing to block, (timo == 0) then 754 * pass "anyyet">0 to socket_poll so it can skip 755 * some work. Othewise pass "anyyet"=0 and if 756 * there are no events pending, it will fill in 757 * the pollhead pointer we need for pollwakeup(). 758 * 759 * XXX - pollrelock() logic needs to know which 760 * which pollcache lock to grab. It'd be a 761 * cleaner solution if we could pass pcp as 762 * an arguement in VOP_POLL interface instead 763 * of implicitly passing it using thread_t 764 * struct. On the other hand, changing VOP_POLL 765 * interface will require all driver/file system 766 * poll routine to change. May want to revisit 767 * the tradeoff later. 768 */ 769 php = NULL; 770 *revents = 0; 771 pcp = pcache_alloc(); 772 pcache_create(pcp, 1); 773 774 mutex_enter(&pcp->pc_lock); 775 curthread->t_pollcache = pcp; 776 error = socket_poll(so, (short)events, (timo == 0), 777 revents, &php); 778 curthread->t_pollcache = NULL; 779 mutex_exit(&pcp->pc_lock); 780 781 if (error != 0 || *revents != 0 || timo == 0) 782 goto out; 783 784 /* 785 * Need to block. Did not get *revents, so the 786 * php should be non-NULL, but let's verify. 787 * Also compute when our sleep expires. 788 */ 789 if (php == NULL) { 790 error = EIO; 791 goto out; 792 } 793 if (timo > 0) 794 expires = ddi_get_lbolt() + 795 MSEC_TO_TICK_ROUNDUP(timo); 796 797 /* 798 * Setup: pollhead -> polldat -> pollcache 799 * needed for pollwakeup() 800 * pdp should be freed by pcache_destroy 801 */ 802 pdp = kmem_zalloc(sizeof (*pdp), KM_SLEEP); 803 pdp->pd_fd = 0; 804 pdp->pd_events = events; 805 pdp->pd_pcache = pcp; 806 pcache_insert_fd(pcp, pdp, 1); 807 pollhead_insert(php, pdp); 808 pdp->pd_php = php; 809 810 mutex_enter(&pcp->pc_lock); 811 while (!(so->so_state & SS_CLOSING)) { 812 pcp->pc_flag = 0; 813 814 /* Ditto pcp comment above. */ 815 curthread->t_pollcache = pcp; 816 error = socket_poll(so, (short)events, 0, 817 revents, &php2); 818 curthread->t_pollcache = NULL; 819 ASSERT(php2 == php); 820 821 if (error != 0 || *revents != 0) 822 break; 823 824 if (pcp->pc_flag & PC_POLLWAKE) 825 continue; 826 827 if (timo == -1) { 828 rval = cv_wait_sig(&pcp->pc_cv, &pcp->pc_lock); 829 } else { 830 rval = cv_timedwait_sig(&pcp->pc_cv, &pcp->pc_lock, 831 expires); 832 } 833 if (rval <= 0) { 834 if (rval == 0) 835 error = EINTR; 836 break; 837 } 838 } 839 mutex_exit(&pcp->pc_lock); 840 841 if (pdp->pd_php != NULL) { 842 pollhead_delete(pdp->pd_php, pdp); 843 pdp->pd_php = NULL; 844 pdp->pd_fd = NULL; 845 } 846 847 /* 848 * pollwakeup() may still interact with this pollcache. Wait until 849 * it is done. 850 */ 851 mutex_enter(&pcp->pc_no_exit); 852 ASSERT(pcp->pc_busy >= 0); 853 while (pcp->pc_busy > 0) 854 cv_wait(&pcp->pc_busy_cv, &pcp->pc_no_exit); 855 mutex_exit(&pcp->pc_no_exit); 856 out: 857 pcache_destroy(pcp); 858 return (error); 859 } 860 861 int 862 ksocket_sendmblk(ksocket_t ks, struct nmsghdr *msg, int flags, 863 mblk_t **mpp, cred_t *cr) 864 { 865 struct sonode *so; 866 int i_val; 867 socklen_t val_len; 868 mblk_t *mp = *mpp; 869 int error; 870 871 /* All Solaris components should pass a cred for this operation. */ 872 ASSERT(cr != NULL); 873 874 if (!KSOCKET_VALID(ks)) 875 return (ENOTSOCK); 876 877 so = KSTOSO(ks); 878 879 if (flags & MSG_MBLK_QUICKRELE) { 880 error = socket_getsockopt(so, SOL_SOCKET, SO_SND_COPYAVOID, 881 &i_val, &val_len, 0, cr); 882 if (error != 0) 883 return (error); 884 885 /* Zero copy is not enable */ 886 if (i_val == 0) 887 return (ECANCELED); 888 889 for (; mp != NULL; mp = mp->b_cont) 890 mp->b_datap->db_struioflag |= STRUIO_ZC; 891 } 892 893 error = socket_sendmblk(so, msg, flags, cr, mpp); 894 895 return (error); 896 } 897 898 899 void 900 ksocket_hold(ksocket_t ks) 901 { 902 struct sonode *so; 903 so = KSTOSO(ks); 904 905 if (!mutex_owned(&so->so_lock)) { 906 mutex_enter(&so->so_lock); 907 so->so_count++; 908 mutex_exit(&so->so_lock); 909 } else 910 so->so_count++; 911 } 912 913 void 914 ksocket_rele(ksocket_t ks) 915 { 916 struct sonode *so; 917 918 so = KSTOSO(ks); 919 /* 920 * When so_count equals 1 means no thread working on this ksocket 921 */ 922 if (so->so_count < 2) 923 cmn_err(CE_PANIC, "ksocket_rele: sonode ref count 0 or 1"); 924 925 if (!mutex_owned(&so->so_lock)) { 926 mutex_enter(&so->so_lock); 927 if (--so->so_count == 1) 928 cv_signal(&so->so_closing_cv); 929 mutex_exit(&so->so_lock); 930 } else { 931 if (--so->so_count == 1) 932 cv_signal(&so->so_closing_cv); 933 } 934 } 935