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