1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94 30 * $FreeBSD: src/sys/kern/uipc_usrreq.c,v 1.54.2.10 2003/03/04 17:28:09 nectar Exp $ 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/kernel.h> 36 #include <sys/domain.h> 37 #include <sys/fcntl.h> 38 #include <sys/malloc.h> /* XXX must be before <sys/file.h> */ 39 #include <sys/proc.h> 40 #include <sys/file.h> 41 #include <sys/filedesc.h> 42 #include <sys/mbuf.h> 43 #include <sys/nlookup.h> 44 #include <sys/protosw.h> 45 #include <sys/socket.h> 46 #include <sys/socketvar.h> 47 #include <sys/resourcevar.h> 48 #include <sys/stat.h> 49 #include <sys/mount.h> 50 #include <sys/sysctl.h> 51 #include <sys/un.h> 52 #include <sys/unpcb.h> 53 #include <sys/vnode.h> 54 #include <sys/kern_syscall.h> 55 #include <sys/taskqueue.h> 56 57 #include <sys/file2.h> 58 #include <sys/spinlock2.h> 59 #include <sys/socketvar2.h> 60 #include <sys/msgport2.h> 61 62 #define UNP_DETACHED UNP_PRIVATE1 63 #define UNP_CONNECTING UNP_PRIVATE2 64 #define UNP_DROPPED UNP_PRIVATE3 65 #define UNP_MARKER UNP_PRIVATE4 66 67 /* For unp_internalize() and unp_externalize() */ 68 CTASSERT(sizeof(struct file *) >= sizeof(int)); 69 70 #define UNP_ISATTACHED(unp) \ 71 ((unp) != NULL && ((unp)->unp_flags & UNP_DETACHED) == 0) 72 73 #ifdef INVARIANTS 74 #define UNP_ASSERT_TOKEN_HELD(unp) \ 75 ASSERT_LWKT_TOKEN_HELD(lwkt_token_pool_lookup((unp))) 76 #else /* !INVARIANTS */ 77 #define UNP_ASSERT_TOKEN_HELD(unp) 78 #endif /* INVARIANTS */ 79 80 struct unp_defdiscard { 81 SLIST_ENTRY(unp_defdiscard) next; 82 struct file *fp; 83 }; 84 SLIST_HEAD(unp_defdiscard_list, unp_defdiscard); 85 86 TAILQ_HEAD(unpcb_qhead, unpcb); 87 struct unp_global_head { 88 struct unpcb_qhead list; 89 int count; 90 }; 91 92 static MALLOC_DEFINE(M_UNPCB, "unpcb", "unpcb struct"); 93 static unp_gen_t unp_gencnt; 94 95 static struct unp_global_head unp_stream_head; 96 static struct unp_global_head unp_dgram_head; 97 static struct unp_global_head unp_seqpkt_head; 98 99 static struct lwkt_token unp_token = LWKT_TOKEN_INITIALIZER(unp_token); 100 static struct taskqueue *unp_taskqueue; 101 102 static struct unp_defdiscard_list unp_defdiscard_head; 103 static struct spinlock unp_defdiscard_spin; 104 static struct task unp_defdiscard_task; 105 106 /* 107 * Unix communications domain. 108 * 109 * TODO: 110 * RDM 111 * rethink name space problems 112 * need a proper out-of-band 113 * lock pushdown 114 */ 115 static struct sockaddr sun_noname = { sizeof(sun_noname), AF_LOCAL }; 116 static ino_t unp_ino = 1; /* prototype for fake inode numbers */ 117 118 static int unp_attach (struct socket *, struct pru_attach_info *); 119 static void unp_detach (struct unpcb *); 120 static int unp_bind (struct unpcb *,struct sockaddr *, struct thread *); 121 static int unp_connect (struct socket *,struct sockaddr *, 122 struct thread *); 123 static void unp_disconnect(struct unpcb *, int); 124 static void unp_shutdown (struct unpcb *); 125 static void unp_gc(void *, int); 126 static int unp_gc_clearmarks(struct file *, void *); 127 static int unp_gc_checkmarks(struct file *, void *); 128 static int unp_gc_checkrefs(struct file *, void *); 129 static void unp_scan (struct mbuf *, void (*)(struct file *, void *), 130 void *data); 131 static void unp_mark (struct file *, void *data); 132 static void unp_discard (struct file *, void *); 133 static int unp_internalize (struct mbuf *, struct thread *); 134 static int unp_listen (struct unpcb *, struct thread *); 135 static void unp_fp_externalize(struct lwp *lp, struct file *fp, int fd, 136 int flags); 137 static int unp_find_lockref(struct sockaddr *nam, struct thread *td, 138 short type, struct unpcb **unp_ret); 139 static int unp_connect_pair(struct unpcb *unp, struct unpcb *unp2); 140 static void unp_drop(struct unpcb *unp, int error); 141 static void unp_defdiscard_taskfunc(void *, int); 142 143 static int unp_rights; /* file descriptors in flight */ 144 static struct lwkt_token unp_rights_token = 145 LWKT_TOKEN_INITIALIZER(unp_rights_token); 146 static struct task unp_gc_task; 147 148 SYSCTL_DECL(_net_local); 149 SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, &unp_rights, 0, 150 "File descriptors in flight"); 151 152 /* 153 * SMP Considerations: 154 * 155 * Since unp_token will be automaticly released upon execution of 156 * blocking code, we need to reference unp_conn before any possible 157 * blocking code to prevent it from being ripped behind our back. 158 * 159 * Any adjustment to unp->unp_conn requires both the global unp_token 160 * AND the per-unp token (lwkt_token_pool_lookup(unp)) to be held. 161 * 162 * Any access to so_pcb to obtain unp requires the pool token for 163 * unp to be held. 164 */ 165 166 static __inline void 167 unp_reference(struct unpcb *unp) 168 { 169 /* 0->1 transition will not work */ 170 KKASSERT(unp->unp_refcnt > 0); 171 atomic_add_int(&unp->unp_refcnt, 1); 172 } 173 174 static __inline void 175 unp_free(struct unpcb *unp) 176 { 177 KKASSERT(unp->unp_refcnt > 0); 178 if (atomic_fetchadd_int(&unp->unp_refcnt, -1) == 1) 179 unp_detach(unp); 180 } 181 182 static __inline struct unpcb * 183 unp_getsocktoken(struct socket *so) 184 { 185 struct unpcb *unp; 186 187 /* 188 * The unp pointer is invalid until we verify that it is 189 * good by re-checking so_pcb AFTER obtaining the token. 190 */ 191 while ((unp = so->so_pcb) != NULL) { 192 lwkt_getpooltoken(unp); 193 if (unp == so->so_pcb) 194 break; 195 lwkt_relpooltoken(unp); 196 } 197 return unp; 198 } 199 200 static __inline void 201 unp_reltoken(struct unpcb *unp) 202 { 203 if (unp != NULL) 204 lwkt_relpooltoken(unp); 205 } 206 207 static __inline void 208 unp_setflags(struct unpcb *unp, int flags) 209 { 210 atomic_set_int(&unp->unp_flags, flags); 211 } 212 213 static __inline void 214 unp_clrflags(struct unpcb *unp, int flags) 215 { 216 atomic_clear_int(&unp->unp_flags, flags); 217 } 218 219 static __inline struct unp_global_head * 220 unp_globalhead(short type) 221 { 222 switch (type) { 223 case SOCK_STREAM: 224 return &unp_stream_head; 225 case SOCK_DGRAM: 226 return &unp_dgram_head; 227 case SOCK_SEQPACKET: 228 return &unp_seqpkt_head; 229 default: 230 panic("unknown socket type %d", type); 231 } 232 } 233 234 static __inline void 235 unp_add_right(struct file *fp) 236 { 237 ASSERT_LWKT_TOKEN_HELD(&unp_rights_token); 238 fp->f_msgcount++; 239 unp_rights++; 240 } 241 242 static __inline void 243 unp_del_right(struct file *fp) 244 { 245 ASSERT_LWKT_TOKEN_HELD(&unp_rights_token); 246 fp->f_msgcount--; 247 unp_rights--; 248 } 249 250 /* 251 * NOTE: (so) is referenced from soabort*() and netmsg_pru_abort() 252 * will sofree() it when we return. 253 */ 254 static void 255 uipc_abort(netmsg_t msg) 256 { 257 struct unpcb *unp; 258 int error; 259 260 lwkt_gettoken(&unp_token); 261 unp = unp_getsocktoken(msg->base.nm_so); 262 263 if (UNP_ISATTACHED(unp)) { 264 unp_drop(unp, ECONNABORTED); 265 error = 0; 266 } else { 267 error = EINVAL; 268 } 269 270 unp_reltoken(unp); 271 lwkt_reltoken(&unp_token); 272 273 lwkt_replymsg(&msg->lmsg, error); 274 } 275 276 static void 277 uipc_accept(netmsg_t msg) 278 { 279 struct unpcb *unp; 280 int error; 281 282 lwkt_gettoken(&unp_token); 283 unp = unp_getsocktoken(msg->base.nm_so); 284 285 if (!UNP_ISATTACHED(unp)) { 286 error = EINVAL; 287 } else { 288 struct unpcb *unp2 = unp->unp_conn; 289 290 /* 291 * Pass back name of connected socket, 292 * if it was bound and we are still connected 293 * (our peer may have closed already!). 294 */ 295 if (unp2 && unp2->unp_addr) { 296 unp_reference(unp2); 297 *msg->accept.nm_nam = dup_sockaddr( 298 (struct sockaddr *)unp2->unp_addr); 299 unp_free(unp2); 300 } else { 301 *msg->accept.nm_nam = dup_sockaddr(&sun_noname); 302 } 303 error = 0; 304 } 305 306 unp_reltoken(unp); 307 lwkt_reltoken(&unp_token); 308 309 lwkt_replymsg(&msg->lmsg, error); 310 } 311 312 static void 313 uipc_attach(netmsg_t msg) 314 { 315 int error; 316 317 lwkt_gettoken(&unp_token); 318 319 KASSERT(msg->base.nm_so->so_pcb == NULL, ("double unp attach")); 320 error = unp_attach(msg->base.nm_so, msg->attach.nm_ai); 321 322 lwkt_reltoken(&unp_token); 323 lwkt_replymsg(&msg->lmsg, error); 324 } 325 326 static void 327 uipc_bind(netmsg_t msg) 328 { 329 struct unpcb *unp; 330 int error; 331 332 lwkt_gettoken(&unp_token); 333 unp = unp_getsocktoken(msg->base.nm_so); 334 335 if (UNP_ISATTACHED(unp)) 336 error = unp_bind(unp, msg->bind.nm_nam, msg->bind.nm_td); 337 else 338 error = EINVAL; 339 340 unp_reltoken(unp); 341 lwkt_reltoken(&unp_token); 342 343 lwkt_replymsg(&msg->lmsg, error); 344 } 345 346 static void 347 uipc_connect(netmsg_t msg) 348 { 349 int error; 350 351 error = unp_connect(msg->base.nm_so, msg->connect.nm_nam, 352 msg->connect.nm_td); 353 lwkt_replymsg(&msg->lmsg, error); 354 } 355 356 static void 357 uipc_connect2(netmsg_t msg) 358 { 359 int error; 360 361 error = unp_connect2(msg->connect2.nm_so1, msg->connect2.nm_so2); 362 lwkt_replymsg(&msg->lmsg, error); 363 } 364 365 /* control is EOPNOTSUPP */ 366 367 static void 368 uipc_detach(netmsg_t msg) 369 { 370 struct unpcb *unp; 371 int error; 372 373 lwkt_gettoken(&unp_token); 374 unp = unp_getsocktoken(msg->base.nm_so); 375 376 if (UNP_ISATTACHED(unp)) { 377 unp_drop(unp, 0); 378 error = 0; 379 } else { 380 error = EINVAL; 381 } 382 383 unp_reltoken(unp); 384 lwkt_reltoken(&unp_token); 385 386 lwkt_replymsg(&msg->lmsg, error); 387 } 388 389 static void 390 uipc_disconnect(netmsg_t msg) 391 { 392 struct unpcb *unp; 393 int error; 394 395 lwkt_gettoken(&unp_token); 396 unp = unp_getsocktoken(msg->base.nm_so); 397 398 if (UNP_ISATTACHED(unp)) { 399 unp_disconnect(unp, 0); 400 error = 0; 401 } else { 402 error = EINVAL; 403 } 404 405 unp_reltoken(unp); 406 lwkt_reltoken(&unp_token); 407 408 lwkt_replymsg(&msg->lmsg, error); 409 } 410 411 static void 412 uipc_listen(netmsg_t msg) 413 { 414 struct unpcb *unp; 415 int error; 416 417 lwkt_gettoken(&unp_token); 418 unp = unp_getsocktoken(msg->base.nm_so); 419 420 if (!UNP_ISATTACHED(unp) || unp->unp_vnode == NULL) 421 error = EINVAL; 422 else 423 error = unp_listen(unp, msg->listen.nm_td); 424 425 unp_reltoken(unp); 426 lwkt_reltoken(&unp_token); 427 428 lwkt_replymsg(&msg->lmsg, error); 429 } 430 431 static void 432 uipc_peeraddr(netmsg_t msg) 433 { 434 struct unpcb *unp; 435 int error; 436 437 lwkt_gettoken(&unp_token); 438 unp = unp_getsocktoken(msg->base.nm_so); 439 440 if (!UNP_ISATTACHED(unp)) { 441 error = EINVAL; 442 } else if (unp->unp_conn && unp->unp_conn->unp_addr) { 443 struct unpcb *unp2 = unp->unp_conn; 444 445 unp_reference(unp2); 446 *msg->peeraddr.nm_nam = dup_sockaddr( 447 (struct sockaddr *)unp2->unp_addr); 448 unp_free(unp2); 449 error = 0; 450 } else { 451 /* 452 * XXX: It seems that this test always fails even when 453 * connection is established. So, this else clause is 454 * added as workaround to return PF_LOCAL sockaddr. 455 */ 456 *msg->peeraddr.nm_nam = dup_sockaddr(&sun_noname); 457 error = 0; 458 } 459 460 unp_reltoken(unp); 461 lwkt_reltoken(&unp_token); 462 463 lwkt_replymsg(&msg->lmsg, error); 464 } 465 466 static void 467 uipc_rcvd(netmsg_t msg) 468 { 469 struct unpcb *unp, *unp2; 470 struct socket *so; 471 struct socket *so2; 472 int error; 473 474 /* 475 * so_pcb is only modified with both the global and the unp 476 * pool token held. 477 */ 478 so = msg->base.nm_so; 479 unp = unp_getsocktoken(so); 480 481 if (!UNP_ISATTACHED(unp)) { 482 error = EINVAL; 483 goto done; 484 } 485 486 switch (so->so_type) { 487 case SOCK_DGRAM: 488 panic("uipc_rcvd DGRAM?"); 489 /*NOTREACHED*/ 490 case SOCK_STREAM: 491 case SOCK_SEQPACKET: 492 if (unp->unp_conn == NULL) 493 break; 494 unp2 = unp->unp_conn; /* protected by pool token */ 495 496 /* 497 * Because we are transfering mbufs directly to the 498 * peer socket we have to use SSB_STOP on the sender 499 * to prevent it from building up infinite mbufs. 500 * 501 * As in several places in this module w ehave to ref unp2 502 * to ensure that it does not get ripped out from under us 503 * if we block on the so2 token or in sowwakeup(). 504 */ 505 so2 = unp2->unp_socket; 506 unp_reference(unp2); 507 lwkt_gettoken(&so2->so_rcv.ssb_token); 508 if (so->so_rcv.ssb_cc < so2->so_snd.ssb_hiwat && 509 so->so_rcv.ssb_mbcnt < so2->so_snd.ssb_mbmax 510 ) { 511 atomic_clear_int(&so2->so_snd.ssb_flags, SSB_STOP); 512 513 sowwakeup(so2); 514 } 515 lwkt_reltoken(&so2->so_rcv.ssb_token); 516 unp_free(unp2); 517 break; 518 default: 519 panic("uipc_rcvd unknown socktype"); 520 /*NOTREACHED*/ 521 } 522 error = 0; 523 done: 524 unp_reltoken(unp); 525 lwkt_replymsg(&msg->lmsg, error); 526 } 527 528 /* pru_rcvoob is EOPNOTSUPP */ 529 530 static void 531 uipc_send(netmsg_t msg) 532 { 533 struct unpcb *unp, *unp2; 534 struct socket *so; 535 struct socket *so2; 536 struct mbuf *control; 537 struct mbuf *m; 538 int error = 0; 539 540 so = msg->base.nm_so; 541 control = msg->send.nm_control; 542 m = msg->send.nm_m; 543 544 /* 545 * so_pcb is only modified with both the global and the unp 546 * pool token held. 547 */ 548 so = msg->base.nm_so; 549 unp = unp_getsocktoken(so); 550 551 if (!UNP_ISATTACHED(unp)) { 552 error = EINVAL; 553 goto release; 554 } 555 556 if (msg->send.nm_flags & PRUS_OOB) { 557 error = EOPNOTSUPP; 558 goto release; 559 } 560 561 wakeup_start_delayed(); 562 563 if (control && (error = unp_internalize(control, msg->send.nm_td))) 564 goto release; 565 566 switch (so->so_type) { 567 case SOCK_DGRAM: 568 { 569 struct sockaddr *from; 570 571 if (msg->send.nm_addr) { 572 if (unp->unp_conn) { 573 error = EISCONN; 574 break; 575 } 576 lwkt_gettoken(&unp_token); 577 error = unp_find_lockref(msg->send.nm_addr, 578 msg->send.nm_td, so->so_type, &unp2); 579 lwkt_reltoken(&unp_token); 580 if (error) 581 break; 582 /* 583 * NOTE: 584 * unp2 is locked and referenced. 585 * 586 * We could unlock unp2 now, since it was checked 587 * and referenced. 588 */ 589 unp_reltoken(unp2); 590 } else { 591 if (unp->unp_conn == NULL) { 592 error = ENOTCONN; 593 break; 594 } 595 unp2 = unp->unp_conn; 596 unp_reference(unp2); 597 } 598 /* NOTE: unp2 is referenced. */ 599 so2 = unp2->unp_socket; 600 601 if (unp->unp_addr) 602 from = (struct sockaddr *)unp->unp_addr; 603 else 604 from = &sun_noname; 605 606 lwkt_gettoken(&so2->so_rcv.ssb_token); 607 if (ssb_appendaddr(&so2->so_rcv, from, m, control)) { 608 sorwakeup(so2); 609 m = NULL; 610 control = NULL; 611 } else { 612 error = ENOBUFS; 613 } 614 lwkt_reltoken(&so2->so_rcv.ssb_token); 615 616 unp_free(unp2); 617 break; 618 } 619 620 case SOCK_STREAM: 621 case SOCK_SEQPACKET: 622 /* Connect if not connected yet. */ 623 /* 624 * Note: A better implementation would complain 625 * if not equal to the peer's address. 626 */ 627 if (unp->unp_conn == NULL) { 628 if (msg->send.nm_addr) { 629 error = unp_connect(so, 630 msg->send.nm_addr, 631 msg->send.nm_td); 632 if (error) 633 break; /* XXX */ 634 } 635 /* 636 * NOTE: 637 * unp_conn still could be NULL, even if the 638 * above unp_connect() succeeds; since the 639 * current unp's token could be released due 640 * to blocking operations after unp_conn is 641 * assigned. 642 */ 643 if (unp->unp_conn == NULL) { 644 error = ENOTCONN; 645 break; 646 } 647 } 648 if (so->so_state & SS_CANTSENDMORE) { 649 error = EPIPE; 650 break; 651 } 652 653 unp2 = unp->unp_conn; 654 KASSERT(unp2 != NULL, ("unp is not connected")); 655 so2 = unp2->unp_socket; 656 657 unp_reference(unp2); 658 659 /* 660 * Send to paired receive port, and then reduce 661 * send buffer hiwater marks to maintain backpressure. 662 * Wake up readers. 663 */ 664 lwkt_gettoken(&so2->so_rcv.ssb_token); 665 if (control) { 666 if (ssb_appendcontrol(&so2->so_rcv, m, control)) { 667 control = NULL; 668 m = NULL; 669 } 670 } else if (so->so_type == SOCK_SEQPACKET) { 671 sbappendrecord(&so2->so_rcv.sb, m); 672 m = NULL; 673 } else { 674 sbappend(&so2->so_rcv.sb, m); 675 m = NULL; 676 } 677 678 /* 679 * Because we are transfering mbufs directly to the 680 * peer socket we have to use SSB_STOP on the sender 681 * to prevent it from building up infinite mbufs. 682 */ 683 if (so2->so_rcv.ssb_cc >= so->so_snd.ssb_hiwat || 684 so2->so_rcv.ssb_mbcnt >= so->so_snd.ssb_mbmax 685 ) { 686 atomic_set_int(&so->so_snd.ssb_flags, SSB_STOP); 687 } 688 lwkt_reltoken(&so2->so_rcv.ssb_token); 689 sorwakeup(so2); 690 691 unp_free(unp2); 692 break; 693 694 default: 695 panic("uipc_send unknown socktype"); 696 } 697 698 /* 699 * SEND_EOF is equivalent to a SEND followed by a SHUTDOWN. 700 */ 701 if (msg->send.nm_flags & PRUS_EOF) { 702 socantsendmore(so); 703 unp_shutdown(unp); 704 } 705 706 if (control && error != 0) 707 unp_dispose(control); 708 release: 709 unp_reltoken(unp); 710 wakeup_end_delayed(); 711 712 if (control) 713 m_freem(control); 714 if (m) 715 m_freem(m); 716 lwkt_replymsg(&msg->lmsg, error); 717 } 718 719 /* 720 * MPSAFE 721 */ 722 static void 723 uipc_sense(netmsg_t msg) 724 { 725 struct unpcb *unp; 726 struct socket *so; 727 struct stat *sb; 728 int error; 729 730 so = msg->base.nm_so; 731 sb = msg->sense.nm_stat; 732 733 /* 734 * so_pcb is only modified with both the global and the unp 735 * pool token held. 736 */ 737 unp = unp_getsocktoken(so); 738 739 if (!UNP_ISATTACHED(unp)) { 740 error = EINVAL; 741 goto done; 742 } 743 744 sb->st_blksize = so->so_snd.ssb_hiwat; 745 sb->st_dev = NOUDEV; 746 if (unp->unp_ino == 0) { /* make up a non-zero inode number */ 747 unp->unp_ino = atomic_fetchadd_long(&unp_ino, 1); 748 if (__predict_false(unp->unp_ino == 0)) 749 unp->unp_ino = atomic_fetchadd_long(&unp_ino, 1); 750 } 751 sb->st_ino = unp->unp_ino; 752 error = 0; 753 done: 754 unp_reltoken(unp); 755 lwkt_replymsg(&msg->lmsg, error); 756 } 757 758 static void 759 uipc_shutdown(netmsg_t msg) 760 { 761 struct socket *so; 762 struct unpcb *unp; 763 int error; 764 765 /* 766 * so_pcb is only modified with both the global and the unp 767 * pool token held. 768 */ 769 so = msg->base.nm_so; 770 unp = unp_getsocktoken(so); 771 772 if (UNP_ISATTACHED(unp)) { 773 socantsendmore(so); 774 unp_shutdown(unp); 775 error = 0; 776 } else { 777 error = EINVAL; 778 } 779 780 unp_reltoken(unp); 781 lwkt_replymsg(&msg->lmsg, error); 782 } 783 784 static void 785 uipc_sockaddr(netmsg_t msg) 786 { 787 struct unpcb *unp; 788 int error; 789 790 /* 791 * so_pcb is only modified with both the global and the unp 792 * pool token held. 793 */ 794 unp = unp_getsocktoken(msg->base.nm_so); 795 796 if (UNP_ISATTACHED(unp)) { 797 if (unp->unp_addr) { 798 *msg->sockaddr.nm_nam = 799 dup_sockaddr((struct sockaddr *)unp->unp_addr); 800 } 801 error = 0; 802 } else { 803 error = EINVAL; 804 } 805 806 unp_reltoken(unp); 807 lwkt_replymsg(&msg->lmsg, error); 808 } 809 810 struct pr_usrreqs uipc_usrreqs = { 811 .pru_abort = uipc_abort, 812 .pru_accept = uipc_accept, 813 .pru_attach = uipc_attach, 814 .pru_bind = uipc_bind, 815 .pru_connect = uipc_connect, 816 .pru_connect2 = uipc_connect2, 817 .pru_control = pr_generic_notsupp, 818 .pru_detach = uipc_detach, 819 .pru_disconnect = uipc_disconnect, 820 .pru_listen = uipc_listen, 821 .pru_peeraddr = uipc_peeraddr, 822 .pru_rcvd = uipc_rcvd, 823 .pru_rcvoob = pr_generic_notsupp, 824 .pru_send = uipc_send, 825 .pru_sense = uipc_sense, 826 .pru_shutdown = uipc_shutdown, 827 .pru_sockaddr = uipc_sockaddr, 828 .pru_sosend = sosend, 829 .pru_soreceive = soreceive 830 }; 831 832 void 833 uipc_ctloutput(netmsg_t msg) 834 { 835 struct socket *so; 836 struct sockopt *sopt; 837 struct unpcb *unp; 838 int error = 0; 839 840 so = msg->base.nm_so; 841 sopt = msg->ctloutput.nm_sopt; 842 843 lwkt_gettoken(&unp_token); 844 unp = unp_getsocktoken(so); 845 846 if (!UNP_ISATTACHED(unp)) { 847 error = EINVAL; 848 goto done; 849 } 850 851 switch (sopt->sopt_dir) { 852 case SOPT_GET: 853 switch (sopt->sopt_name) { 854 case LOCAL_PEERCRED: 855 if (unp->unp_flags & UNP_HAVEPC) 856 soopt_from_kbuf(sopt, &unp->unp_peercred, 857 sizeof(unp->unp_peercred)); 858 else { 859 if (so->so_type == SOCK_STREAM) 860 error = ENOTCONN; 861 else if (so->so_type == SOCK_SEQPACKET) 862 error = ENOTCONN; 863 else 864 error = EINVAL; 865 } 866 break; 867 default: 868 error = EOPNOTSUPP; 869 break; 870 } 871 break; 872 case SOPT_SET: 873 default: 874 error = EOPNOTSUPP; 875 break; 876 } 877 878 done: 879 unp_reltoken(unp); 880 lwkt_reltoken(&unp_token); 881 882 lwkt_replymsg(&msg->lmsg, error); 883 } 884 885 /* 886 * Both send and receive buffers are allocated PIPSIZ bytes of buffering 887 * for stream sockets, although the total for sender and receiver is 888 * actually only PIPSIZ. 889 * 890 * Datagram sockets really use the sendspace as the maximum datagram size, 891 * and don't really want to reserve the sendspace. Their recvspace should 892 * be large enough for at least one max-size datagram plus address. 893 * 894 * We want the local send/recv space to be significant larger then lo0's 895 * mtu of 16384. 896 */ 897 #ifndef PIPSIZ 898 #define PIPSIZ 57344 899 #endif 900 static u_long unpst_sendspace = PIPSIZ; 901 static u_long unpst_recvspace = PIPSIZ; 902 static u_long unpdg_sendspace = 2*1024; /* really max datagram size */ 903 static u_long unpdg_recvspace = 4*1024; 904 905 SYSCTL_DECL(_net_local_seqpacket); 906 SYSCTL_DECL(_net_local_stream); 907 SYSCTL_INT(_net_local_stream, OID_AUTO, sendspace, CTLFLAG_RW, 908 &unpst_sendspace, 0, "Size of stream socket send buffer"); 909 SYSCTL_INT(_net_local_stream, OID_AUTO, recvspace, CTLFLAG_RW, 910 &unpst_recvspace, 0, "Size of stream socket receive buffer"); 911 912 SYSCTL_DECL(_net_local_dgram); 913 SYSCTL_INT(_net_local_dgram, OID_AUTO, maxdgram, CTLFLAG_RW, 914 &unpdg_sendspace, 0, "Max datagram socket size"); 915 SYSCTL_INT(_net_local_dgram, OID_AUTO, recvspace, CTLFLAG_RW, 916 &unpdg_recvspace, 0, "Size of datagram socket receive buffer"); 917 918 static int 919 unp_attach(struct socket *so, struct pru_attach_info *ai) 920 { 921 struct unp_global_head *head; 922 struct unpcb *unp; 923 int error; 924 925 lwkt_gettoken(&unp_token); 926 927 if (so->so_snd.ssb_hiwat == 0 || so->so_rcv.ssb_hiwat == 0) { 928 switch (so->so_type) { 929 case SOCK_STREAM: 930 case SOCK_SEQPACKET: 931 error = soreserve(so, unpst_sendspace, unpst_recvspace, 932 ai->sb_rlimit); 933 break; 934 935 case SOCK_DGRAM: 936 error = soreserve(so, unpdg_sendspace, unpdg_recvspace, 937 ai->sb_rlimit); 938 break; 939 940 default: 941 panic("unp_attach"); 942 } 943 if (error) 944 goto failed; 945 } 946 947 /* 948 * In order to support sendfile we have to set either SSB_STOPSUPP 949 * or SSB_PREALLOC. Unix domain sockets use the SSB_STOP flow 950 * control mechanism. 951 */ 952 if (so->so_type == SOCK_STREAM) { 953 atomic_set_int(&so->so_rcv.ssb_flags, SSB_STOPSUPP); 954 atomic_set_int(&so->so_snd.ssb_flags, SSB_STOPSUPP); 955 } 956 957 unp = kmalloc(sizeof(*unp), M_UNPCB, M_WAITOK | M_ZERO | M_NULLOK); 958 if (unp == NULL) { 959 error = ENOBUFS; 960 goto failed; 961 } 962 unp->unp_refcnt = 1; 963 unp->unp_gencnt = ++unp_gencnt; 964 LIST_INIT(&unp->unp_refs); 965 unp->unp_socket = so; 966 unp->unp_rvnode = ai->fd_rdir; /* jail cruft XXX JH */ 967 so->so_pcb = (caddr_t)unp; 968 soreference(so); 969 970 head = unp_globalhead(so->so_type); 971 TAILQ_INSERT_TAIL(&head->list, unp, unp_link); 972 head->count++; 973 error = 0; 974 failed: 975 lwkt_reltoken(&unp_token); 976 return error; 977 } 978 979 static void 980 unp_detach(struct unpcb *unp) 981 { 982 struct socket *so; 983 984 lwkt_gettoken(&unp_token); 985 lwkt_getpooltoken(unp); 986 987 so = unp->unp_socket; 988 989 unp->unp_gencnt = ++unp_gencnt; 990 if (unp->unp_vnode) { 991 unp->unp_vnode->v_socket = NULL; 992 vrele(unp->unp_vnode); 993 unp->unp_vnode = NULL; 994 } 995 soisdisconnected(so); 996 KKASSERT(so->so_pcb == unp); 997 so->so_pcb = NULL; /* both tokens required */ 998 unp->unp_socket = NULL; 999 1000 lwkt_relpooltoken(unp); 1001 lwkt_reltoken(&unp_token); 1002 1003 sofree(so); 1004 1005 KASSERT(unp->unp_conn == NULL, ("unp is still connected")); 1006 KASSERT(LIST_EMPTY(&unp->unp_refs), ("unp still has references")); 1007 1008 if (unp->unp_addr) 1009 kfree(unp->unp_addr, M_SONAME); 1010 kfree(unp, M_UNPCB); 1011 1012 if (unp_rights) 1013 taskqueue_enqueue(unp_taskqueue, &unp_gc_task); 1014 } 1015 1016 static int 1017 unp_bind(struct unpcb *unp, struct sockaddr *nam, struct thread *td) 1018 { 1019 struct proc *p = td->td_proc; 1020 struct sockaddr_un *soun = (struct sockaddr_un *)nam; 1021 struct vnode *vp; 1022 struct vattr vattr; 1023 int error, namelen; 1024 struct nlookupdata nd; 1025 char buf[SOCK_MAXADDRLEN]; 1026 1027 ASSERT_LWKT_TOKEN_HELD(&unp_token); 1028 UNP_ASSERT_TOKEN_HELD(unp); 1029 1030 if (unp->unp_vnode != NULL) 1031 return EINVAL; 1032 1033 namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path); 1034 if (namelen <= 0) 1035 return EINVAL; 1036 strncpy(buf, soun->sun_path, namelen); 1037 buf[namelen] = 0; /* null-terminate the string */ 1038 error = nlookup_init(&nd, buf, UIO_SYSSPACE, 1039 NLC_LOCKVP | NLC_CREATE | NLC_REFDVP); 1040 if (error == 0) 1041 error = nlookup(&nd); 1042 if (error == 0 && nd.nl_nch.ncp->nc_vp != NULL) 1043 error = EADDRINUSE; 1044 if (error) 1045 goto done; 1046 1047 VATTR_NULL(&vattr); 1048 vattr.va_type = VSOCK; 1049 vattr.va_mode = (ACCESSPERMS & ~p->p_fd->fd_cmask); 1050 error = VOP_NCREATE(&nd.nl_nch, nd.nl_dvp, &vp, nd.nl_cred, &vattr); 1051 if (error == 0) { 1052 if (unp->unp_vnode == NULL) { 1053 vp->v_socket = unp->unp_socket; 1054 unp->unp_vnode = vp; 1055 unp->unp_addr = (struct sockaddr_un *)dup_sockaddr(nam); 1056 vn_unlock(vp); 1057 } else { 1058 vput(vp); /* late race */ 1059 error = EINVAL; 1060 } 1061 } 1062 done: 1063 nlookup_done(&nd); 1064 return (error); 1065 } 1066 1067 static int 1068 unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 1069 { 1070 struct unpcb *unp, *unp2; 1071 int error, flags = 0; 1072 1073 lwkt_gettoken(&unp_token); 1074 1075 unp = unp_getsocktoken(so); 1076 if (!UNP_ISATTACHED(unp)) { 1077 error = EINVAL; 1078 goto failed; 1079 } 1080 1081 if ((unp->unp_flags & UNP_CONNECTING) || unp->unp_conn != NULL) { 1082 error = EISCONN; 1083 goto failed; 1084 } 1085 1086 flags = UNP_CONNECTING; 1087 unp_setflags(unp, flags); 1088 1089 error = unp_find_lockref(nam, td, so->so_type, &unp2); 1090 if (error) 1091 goto failed; 1092 /* 1093 * NOTE: 1094 * unp2 is locked and referenced. 1095 */ 1096 1097 if (so->so_proto->pr_flags & PR_CONNREQUIRED) { 1098 struct socket *so2, *so3; 1099 struct unpcb *unp3; 1100 1101 so2 = unp2->unp_socket; 1102 if (!(so2->so_options & SO_ACCEPTCONN) || 1103 (so3 = sonewconn_faddr(so2, 0, NULL, 1104 TRUE /* keep ref */)) == NULL) { 1105 error = ECONNREFUSED; 1106 goto done; 1107 } 1108 /* so3 has a socket reference. */ 1109 1110 unp3 = unp_getsocktoken(so3); 1111 if (!UNP_ISATTACHED(unp3)) { 1112 unp_reltoken(unp3); 1113 /* 1114 * Already aborted; we only need to drop the 1115 * socket reference held by sonewconn_faddr(). 1116 */ 1117 sofree(so3); 1118 error = ECONNREFUSED; 1119 goto done; 1120 } 1121 unp_reference(unp3); 1122 /* 1123 * NOTE: 1124 * unp3 is locked and referenced. 1125 */ 1126 1127 /* 1128 * Release so3 socket reference held by sonewconn_faddr(). 1129 * Since we have referenced unp3, neither unp3 nor so3 will 1130 * be destroyed here. 1131 */ 1132 sofree(so3); 1133 1134 if (unp2->unp_addr != NULL) { 1135 unp3->unp_addr = (struct sockaddr_un *) 1136 dup_sockaddr((struct sockaddr *)unp2->unp_addr); 1137 } 1138 1139 /* 1140 * unp_peercred management: 1141 * 1142 * The connecter's (client's) credentials are copied 1143 * from its process structure at the time of connect() 1144 * (which is now). 1145 */ 1146 cru2x(td->td_proc->p_ucred, &unp3->unp_peercred); 1147 unp_setflags(unp3, UNP_HAVEPC); 1148 /* 1149 * The receiver's (server's) credentials are copied 1150 * from the unp_peercred member of socket on which the 1151 * former called listen(); unp_listen() cached that 1152 * process's credentials at that time so we can use 1153 * them now. 1154 */ 1155 KASSERT(unp2->unp_flags & UNP_HAVEPCCACHED, 1156 ("unp_connect: listener without cached peercred")); 1157 memcpy(&unp->unp_peercred, &unp2->unp_peercred, 1158 sizeof(unp->unp_peercred)); 1159 unp_setflags(unp, UNP_HAVEPC); 1160 1161 error = unp_connect_pair(unp, unp3); 1162 if (error) 1163 soabort_direct(so3); 1164 1165 /* Done with unp3 */ 1166 unp_free(unp3); 1167 unp_reltoken(unp3); 1168 } else { 1169 error = unp_connect_pair(unp, unp2); 1170 } 1171 done: 1172 unp_free(unp2); 1173 unp_reltoken(unp2); 1174 failed: 1175 if (flags) 1176 unp_clrflags(unp, flags); 1177 unp_reltoken(unp); 1178 1179 lwkt_reltoken(&unp_token); 1180 return (error); 1181 } 1182 1183 /* 1184 * Connect two unix domain sockets together. 1185 * 1186 * NOTE: Semantics for any change to unp_conn requires that the per-unp 1187 * pool token also be held. 1188 */ 1189 int 1190 unp_connect2(struct socket *so, struct socket *so2) 1191 { 1192 struct unpcb *unp, *unp2; 1193 int error; 1194 1195 lwkt_gettoken(&unp_token); 1196 if (so2->so_type != so->so_type) { 1197 lwkt_reltoken(&unp_token); 1198 return (EPROTOTYPE); 1199 } 1200 unp = unp_getsocktoken(so); 1201 unp2 = unp_getsocktoken(so2); 1202 1203 if (!UNP_ISATTACHED(unp)) { 1204 error = EINVAL; 1205 goto done; 1206 } 1207 if (!UNP_ISATTACHED(unp2)) { 1208 error = ECONNREFUSED; 1209 goto done; 1210 } 1211 1212 if (unp->unp_conn != NULL) { 1213 error = EISCONN; 1214 goto done; 1215 } 1216 if ((so->so_type == SOCK_STREAM || so->so_type == SOCK_SEQPACKET) && 1217 unp2->unp_conn != NULL) { 1218 error = EISCONN; 1219 goto done; 1220 } 1221 1222 error = unp_connect_pair(unp, unp2); 1223 done: 1224 unp_reltoken(unp2); 1225 unp_reltoken(unp); 1226 lwkt_reltoken(&unp_token); 1227 return (error); 1228 } 1229 1230 /* 1231 * Disconnect a unix domain socket pair. 1232 * 1233 * NOTE: Semantics for any change to unp_conn requires that the per-unp 1234 * pool token also be held. 1235 */ 1236 static void 1237 unp_disconnect(struct unpcb *unp, int error) 1238 { 1239 struct socket *so = unp->unp_socket; 1240 struct unpcb *unp2; 1241 1242 ASSERT_LWKT_TOKEN_HELD(&unp_token); 1243 UNP_ASSERT_TOKEN_HELD(unp); 1244 1245 if (error) 1246 so->so_error = error; 1247 1248 while ((unp2 = unp->unp_conn) != NULL) { 1249 lwkt_getpooltoken(unp2); 1250 if (unp2 == unp->unp_conn) 1251 break; 1252 lwkt_relpooltoken(unp2); 1253 } 1254 if (unp2 == NULL) 1255 return; 1256 /* unp2 is locked. */ 1257 1258 KASSERT((unp2->unp_flags & UNP_DROPPED) == 0, ("unp2 was dropped")); 1259 1260 unp->unp_conn = NULL; 1261 1262 switch (so->so_type) { 1263 case SOCK_DGRAM: 1264 LIST_REMOVE(unp, unp_reflink); 1265 soclrstate(so, SS_ISCONNECTED); 1266 break; 1267 1268 case SOCK_STREAM: 1269 case SOCK_SEQPACKET: 1270 /* 1271 * Keep a reference before clearing the unp_conn 1272 * to avoid racing uipc_detach()/uipc_abort() in 1273 * other thread. 1274 */ 1275 unp_reference(unp2); 1276 KASSERT(unp2->unp_conn == unp, ("unp_conn mismatch")); 1277 unp2->unp_conn = NULL; 1278 1279 soisdisconnected(so); 1280 soisdisconnected(unp2->unp_socket); 1281 1282 unp_free(unp2); 1283 break; 1284 } 1285 1286 lwkt_relpooltoken(unp2); 1287 } 1288 1289 #ifdef notdef 1290 void 1291 unp_abort(struct unpcb *unp) 1292 { 1293 lwkt_gettoken(&unp_token); 1294 unp_free(unp); 1295 lwkt_reltoken(&unp_token); 1296 } 1297 #endif 1298 1299 static int 1300 prison_unpcb(struct thread *td, struct unpcb *unp) 1301 { 1302 struct proc *p; 1303 1304 if (td == NULL) 1305 return (0); 1306 if ((p = td->td_proc) == NULL) 1307 return (0); 1308 if (!p->p_ucred->cr_prison) 1309 return (0); 1310 if (p->p_fd->fd_rdir == unp->unp_rvnode) 1311 return (0); 1312 return (1); 1313 } 1314 1315 static int 1316 unp_pcblist(SYSCTL_HANDLER_ARGS) 1317 { 1318 struct unp_global_head *head = arg1; 1319 int error, i, n; 1320 struct unpcb *unp, *marker; 1321 1322 KKASSERT(curproc != NULL); 1323 1324 /* 1325 * The process of preparing the PCB list is too time-consuming and 1326 * resource-intensive to repeat twice on every request. 1327 */ 1328 if (req->oldptr == NULL) { 1329 n = head->count; 1330 req->oldidx = (n + n/8) * sizeof(struct xunpcb); 1331 return 0; 1332 } 1333 1334 if (req->newptr != NULL) 1335 return EPERM; 1336 1337 marker = kmalloc(sizeof(*marker), M_UNPCB, M_WAITOK | M_ZERO); 1338 marker->unp_flags |= UNP_MARKER; 1339 1340 lwkt_gettoken(&unp_token); 1341 1342 n = head->count; 1343 i = 0; 1344 error = 0; 1345 1346 TAILQ_INSERT_HEAD(&head->list, marker, unp_link); 1347 while ((unp = TAILQ_NEXT(marker, unp_link)) != NULL && i < n) { 1348 struct xunpcb xu; 1349 1350 TAILQ_REMOVE(&head->list, marker, unp_link); 1351 TAILQ_INSERT_AFTER(&head->list, unp, marker, unp_link); 1352 1353 if (unp->unp_flags & UNP_MARKER) 1354 continue; 1355 if (prison_unpcb(req->td, unp)) 1356 continue; 1357 1358 xu.xu_len = sizeof(xu); 1359 xu.xu_unpp = unp; 1360 1361 /* 1362 * NOTE: 1363 * unp->unp_addr and unp->unp_conn are protected by 1364 * unp_token. So if we want to get rid of unp_token 1365 * or reduce the coverage of unp_token, care must be 1366 * taken. 1367 */ 1368 if (unp->unp_addr) { 1369 bcopy(unp->unp_addr, &xu.xu_addr, 1370 unp->unp_addr->sun_len); 1371 } 1372 if (unp->unp_conn && unp->unp_conn->unp_addr) { 1373 bcopy(unp->unp_conn->unp_addr, 1374 &xu.xu_caddr, 1375 unp->unp_conn->unp_addr->sun_len); 1376 } 1377 bcopy(unp, &xu.xu_unp, sizeof(*unp)); 1378 sotoxsocket(unp->unp_socket, &xu.xu_socket); 1379 1380 /* NOTE: This could block and temporarily release unp_token */ 1381 error = SYSCTL_OUT(req, &xu, sizeof(xu)); 1382 if (error) 1383 break; 1384 ++i; 1385 } 1386 TAILQ_REMOVE(&head->list, marker, unp_link); 1387 1388 lwkt_reltoken(&unp_token); 1389 1390 kfree(marker, M_UNPCB); 1391 return error; 1392 } 1393 1394 SYSCTL_PROC(_net_local_dgram, OID_AUTO, pcblist, CTLFLAG_RD, 1395 &unp_dgram_head, 0, unp_pcblist, "S,xunpcb", 1396 "List of active local datagram sockets"); 1397 SYSCTL_PROC(_net_local_stream, OID_AUTO, pcblist, CTLFLAG_RD, 1398 &unp_stream_head, 0, unp_pcblist, "S,xunpcb", 1399 "List of active local stream sockets"); 1400 SYSCTL_PROC(_net_local_seqpacket, OID_AUTO, pcblist, CTLFLAG_RD, 1401 &unp_seqpkt_head, 0, unp_pcblist, "S,xunpcb", 1402 "List of active local seqpacket sockets"); 1403 1404 static void 1405 unp_shutdown(struct unpcb *unp) 1406 { 1407 struct socket *so; 1408 1409 if ((unp->unp_socket->so_type == SOCK_STREAM || 1410 unp->unp_socket->so_type == SOCK_SEQPACKET) && 1411 unp->unp_conn != NULL && (so = unp->unp_conn->unp_socket)) { 1412 socantrcvmore(so); 1413 } 1414 } 1415 1416 #ifdef notdef 1417 void 1418 unp_drain(void) 1419 { 1420 lwkt_gettoken(&unp_token); 1421 lwkt_reltoken(&unp_token); 1422 } 1423 #endif 1424 1425 int 1426 unp_externalize(struct mbuf *rights, int flags) 1427 { 1428 struct thread *td = curthread; 1429 struct proc *p = td->td_proc; /* XXX */ 1430 struct lwp *lp = td->td_lwp; 1431 struct cmsghdr *cm = mtod(rights, struct cmsghdr *); 1432 int *fdp; 1433 int i; 1434 struct file **rp; 1435 struct file *fp; 1436 int newfds = (cm->cmsg_len - (CMSG_DATA(cm) - (u_char *)cm)) 1437 / sizeof(struct file *); 1438 int f; 1439 1440 lwkt_gettoken(&unp_rights_token); 1441 1442 /* 1443 * if the new FD's will not fit, then we free them all 1444 */ 1445 if (!fdavail(p, newfds)) { 1446 rp = (struct file **)CMSG_DATA(cm); 1447 for (i = 0; i < newfds; i++) { 1448 fp = *rp; 1449 /* 1450 * zero the pointer before calling unp_discard, 1451 * since it may end up in unp_gc().. 1452 */ 1453 *rp++ = NULL; 1454 unp_discard(fp, NULL); 1455 } 1456 lwkt_reltoken(&unp_rights_token); 1457 return (EMSGSIZE); 1458 } 1459 1460 /* 1461 * now change each pointer to an fd in the global table to 1462 * an integer that is the index to the local fd table entry 1463 * that we set up to point to the global one we are transferring. 1464 * Since the sizeof(struct file *) is bigger than or equal to 1465 * the sizeof(int), we do it in forward order. In that case, 1466 * an integer will always come in the same place or before its 1467 * corresponding struct file pointer. 1468 * 1469 * Hold revoke_token in 'shared' mode, so that we won't miss 1470 * the FREVOKED update on fps being externalized (fsetfd). 1471 */ 1472 lwkt_gettoken_shared(&revoke_token); 1473 fdp = (int *)CMSG_DATA(cm); 1474 rp = (struct file **)CMSG_DATA(cm); 1475 for (i = 0; i < newfds; i++) { 1476 if (fdalloc(p, 0, &f)) { 1477 int j; 1478 1479 /* 1480 * Previous fdavail() can't garantee 1481 * fdalloc() success due to SMP race. 1482 * Just clean up and return the same 1483 * error value as if fdavail() failed. 1484 */ 1485 lwkt_reltoken(&revoke_token); 1486 1487 /* Close externalized files */ 1488 for (j = 0; j < i; j++) 1489 kern_close(fdp[j]); 1490 /* Discard the rest of internal files */ 1491 for (; i < newfds; i++) 1492 unp_discard(rp[i], NULL); 1493 /* Wipe out the control message */ 1494 for (i = 0; i < newfds; i++) 1495 rp[i] = NULL; 1496 1497 lwkt_reltoken(&unp_rights_token); 1498 return (EMSGSIZE); 1499 } 1500 fp = rp[i]; 1501 unp_fp_externalize(lp, fp, f, flags); 1502 fdp[i] = f; 1503 } 1504 lwkt_reltoken(&revoke_token); 1505 1506 lwkt_reltoken(&unp_rights_token); 1507 1508 /* 1509 * Adjust length, in case sizeof(struct file *) and sizeof(int) 1510 * differs. 1511 */ 1512 cm->cmsg_len = CMSG_LEN(newfds * sizeof(int)); 1513 rights->m_len = cm->cmsg_len; 1514 1515 return (0); 1516 } 1517 1518 static void 1519 unp_fp_externalize(struct lwp *lp, struct file *fp, int fd, int flags) 1520 { 1521 if (lp) { 1522 struct filedesc *fdp = lp->lwp_proc->p_fd; 1523 1524 KKASSERT(fd >= 0); 1525 if (fp->f_flag & FREVOKED) { 1526 struct file *fx; 1527 int error; 1528 1529 kprintf("Warning: revoked fp exiting unix socket\n"); 1530 error = falloc(lp, &fx, NULL); 1531 if (error == 0) { 1532 if (flags & MSG_CMSG_CLOEXEC) 1533 fdp->fd_files[fd].fileflags |= UF_EXCLOSE; 1534 fsetfd(fdp, fx, fd); 1535 fdrop(fx); 1536 } else { 1537 fsetfd(fdp, NULL, fd); 1538 } 1539 } else { 1540 if (flags & MSG_CMSG_CLOEXEC) 1541 fdp->fd_files[fd].fileflags |= UF_EXCLOSE; 1542 fsetfd(fdp, fp, fd); 1543 } 1544 } 1545 unp_del_right(fp); 1546 fdrop(fp); 1547 } 1548 1549 void 1550 unp_init(void) 1551 { 1552 TAILQ_INIT(&unp_stream_head.list); 1553 TAILQ_INIT(&unp_dgram_head.list); 1554 TAILQ_INIT(&unp_seqpkt_head.list); 1555 1556 SLIST_INIT(&unp_defdiscard_head); 1557 spin_init(&unp_defdiscard_spin, "unpdisc"); 1558 TASK_INIT(&unp_defdiscard_task, 0, unp_defdiscard_taskfunc, NULL); 1559 1560 /* 1561 * This implies that only one gc can be in-progress at any 1562 * given moment. 1563 */ 1564 TASK_INIT(&unp_gc_task, 0, unp_gc, NULL); 1565 1566 /* 1567 * Create taskqueue for defered discard, and stick it to 1568 * the last CPU. 1569 */ 1570 unp_taskqueue = taskqueue_create("unp_taskq", M_WAITOK, 1571 taskqueue_thread_enqueue, &unp_taskqueue); 1572 taskqueue_start_threads(&unp_taskqueue, 1, TDPRI_KERN_DAEMON, 1573 ncpus - 1, "unp taskq"); 1574 } 1575 1576 static int 1577 unp_internalize(struct mbuf *control, struct thread *td) 1578 { 1579 struct proc *p = td->td_proc; 1580 struct filedesc *fdescp; 1581 struct cmsghdr *cm = mtod(control, struct cmsghdr *); 1582 struct file **rp; 1583 struct file *fp; 1584 int i, fd, *fdp; 1585 struct cmsgcred *cmcred; 1586 int oldfds; 1587 u_int newlen; 1588 int error; 1589 1590 KKASSERT(p); 1591 1592 if ((cm->cmsg_type != SCM_RIGHTS && cm->cmsg_type != SCM_CREDS) || 1593 cm->cmsg_level != SOL_SOCKET || 1594 CMSG_ALIGN(cm->cmsg_len) != control->m_len) 1595 return EINVAL; 1596 1597 /* 1598 * Fill in credential information. 1599 */ 1600 if (cm->cmsg_type == SCM_CREDS) { 1601 cmcred = (struct cmsgcred *)CMSG_DATA(cm); 1602 cmcred->cmcred_pid = p->p_pid; 1603 cmcred->cmcred_uid = p->p_ucred->cr_ruid; 1604 cmcred->cmcred_gid = p->p_ucred->cr_rgid; 1605 cmcred->cmcred_euid = p->p_ucred->cr_uid; 1606 cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups, 1607 CMGROUP_MAX); 1608 for (i = 0; i < cmcred->cmcred_ngroups; i++) 1609 cmcred->cmcred_groups[i] = p->p_ucred->cr_groups[i]; 1610 return 0; 1611 } 1612 1613 /* 1614 * cmsghdr may not be aligned, do not allow calculation(s) to 1615 * go negative. 1616 */ 1617 if (cm->cmsg_len < CMSG_LEN(0)) 1618 return EINVAL; 1619 1620 oldfds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int); 1621 1622 /* 1623 * Now replace the integer FDs with pointers to 1624 * the associated global file table entry.. 1625 * Allocate a bigger buffer as necessary. But if an cluster is not 1626 * enough, return E2BIG. 1627 */ 1628 newlen = CMSG_LEN(oldfds * sizeof(struct file *)); 1629 if (newlen > MCLBYTES) 1630 return E2BIG; 1631 if (newlen - control->m_len > M_TRAILINGSPACE(control)) { 1632 if (control->m_flags & M_EXT) 1633 return E2BIG; 1634 MCLGET(control, M_WAITOK); 1635 if (!(control->m_flags & M_EXT)) 1636 return ENOBUFS; 1637 1638 /* copy the data to the cluster */ 1639 memcpy(mtod(control, char *), cm, cm->cmsg_len); 1640 cm = mtod(control, struct cmsghdr *); 1641 } 1642 1643 lwkt_gettoken(&unp_rights_token); 1644 1645 fdescp = p->p_fd; 1646 spin_lock_shared(&fdescp->fd_spin); 1647 1648 /* 1649 * check that all the FDs passed in refer to legal OPEN files 1650 * If not, reject the entire operation. 1651 */ 1652 fdp = (int *)CMSG_DATA(cm); 1653 for (i = 0; i < oldfds; i++) { 1654 fd = *fdp++; 1655 if ((unsigned)fd >= fdescp->fd_nfiles || 1656 fdescp->fd_files[fd].fp == NULL) { 1657 error = EBADF; 1658 goto done; 1659 } 1660 if (fdescp->fd_files[fd].fp->f_type == DTYPE_KQUEUE) { 1661 error = EOPNOTSUPP; 1662 goto done; 1663 } 1664 } 1665 1666 /* 1667 * Adjust length, in case sizeof(struct file *) and sizeof(int) 1668 * differs. 1669 */ 1670 cm->cmsg_len = newlen; 1671 control->m_len = CMSG_ALIGN(newlen); 1672 1673 /* 1674 * Transform the file descriptors into struct file pointers. 1675 * Since the sizeof(struct file *) is bigger than or equal to 1676 * the sizeof(int), we do it in reverse order so that the int 1677 * won't get trashed until we're done. 1678 */ 1679 fdp = (int *)CMSG_DATA(cm) + oldfds - 1; 1680 rp = (struct file **)CMSG_DATA(cm) + oldfds - 1; 1681 for (i = 0; i < oldfds; i++) { 1682 fp = fdescp->fd_files[*fdp--].fp; 1683 *rp-- = fp; 1684 fhold(fp); 1685 unp_add_right(fp); 1686 } 1687 error = 0; 1688 done: 1689 spin_unlock_shared(&fdescp->fd_spin); 1690 lwkt_reltoken(&unp_rights_token); 1691 return error; 1692 } 1693 1694 /* 1695 * Garbage collect in-transit file descriptors that get lost due to 1696 * loops (i.e. when a socket is sent to another process over itself, 1697 * and more complex situations). 1698 * 1699 * NOT MPSAFE - TODO socket flush code and maybe fdrop. Rest is MPSAFE. 1700 */ 1701 1702 struct unp_gc_info { 1703 struct file **extra_ref; 1704 struct file *locked_fp; 1705 int defer; 1706 int index; 1707 int maxindex; 1708 }; 1709 1710 static void 1711 unp_gc(void *arg __unused, int pending __unused) 1712 { 1713 struct unp_gc_info info; 1714 struct file **fpp; 1715 int i; 1716 1717 lwkt_gettoken(&unp_rights_token); 1718 1719 /* 1720 * Before going through all this, set all FDs to be NOT defered 1721 * and NOT externally accessible (not marked). During the scan 1722 * a fd can be marked externally accessible but we may or may not 1723 * be able to immediately process it (controlled by FDEFER). 1724 * 1725 * If we loop sleep a bit. The complexity of the topology can cause 1726 * multiple loops. Also failure to acquire the socket's so_rcv 1727 * token can cause us to loop. 1728 */ 1729 allfiles_scan_exclusive(unp_gc_clearmarks, NULL); 1730 do { 1731 info.defer = 0; 1732 allfiles_scan_exclusive(unp_gc_checkmarks, &info); 1733 if (info.defer) 1734 tsleep(&info, 0, "gcagain", 1); 1735 } while (info.defer); 1736 1737 /* 1738 * We grab an extra reference to each of the file table entries 1739 * that are not otherwise accessible and then free the rights 1740 * that are stored in messages on them. 1741 * 1742 * The bug in the orginal code is a little tricky, so I'll describe 1743 * what's wrong with it here. 1744 * 1745 * It is incorrect to simply unp_discard each entry for f_msgcount 1746 * times -- consider the case of sockets A and B that contain 1747 * references to each other. On a last close of some other socket, 1748 * we trigger a gc since the number of outstanding rights (unp_rights) 1749 * is non-zero. If during the sweep phase the gc code unp_discards, 1750 * we end up doing a (full) fdrop on the descriptor. A fdrop on A 1751 * results in the following chain. Closef calls soo_close, which 1752 * calls soclose. Soclose calls first (through the switch 1753 * uipc_usrreq) unp_detach, which re-invokes unp_gc. Unp_gc simply 1754 * returns because the previous instance had set unp_gcing, and 1755 * we return all the way back to soclose, which marks the socket 1756 * with SS_NOFDREF, and then calls sofree. Sofree calls sorflush 1757 * to free up the rights that are queued in messages on the socket A, 1758 * i.e., the reference on B. The sorflush calls via the dom_dispose 1759 * switch unp_dispose, which unp_scans with unp_discard. This second 1760 * instance of unp_discard just calls fdrop on B. 1761 * 1762 * Well, a similar chain occurs on B, resulting in a sorflush on B, 1763 * which results in another fdrop on A. Unfortunately, A is already 1764 * being closed, and the descriptor has already been marked with 1765 * SS_NOFDREF, and soclose panics at this point. 1766 * 1767 * Here, we first take an extra reference to each inaccessible 1768 * descriptor. Then, we call sorflush ourself, since we know 1769 * it is a Unix domain socket anyhow. After we destroy all the 1770 * rights carried in messages, we do a last fdrop to get rid 1771 * of our extra reference. This is the last close, and the 1772 * unp_detach etc will shut down the socket. 1773 * 1774 * 91/09/19, bsy@cs.cmu.edu 1775 */ 1776 info.extra_ref = kmalloc(256 * sizeof(struct file *), M_FILE, M_WAITOK); 1777 info.maxindex = 256; 1778 1779 do { 1780 /* 1781 * Look for matches 1782 */ 1783 info.index = 0; 1784 allfiles_scan_exclusive(unp_gc_checkrefs, &info); 1785 1786 /* 1787 * For each FD on our hit list, do the following two things 1788 */ 1789 for (i = info.index, fpp = info.extra_ref; --i >= 0; ++fpp) { 1790 struct file *tfp = *fpp; 1791 if (tfp->f_type == DTYPE_SOCKET && tfp->f_data != NULL) 1792 sorflush((struct socket *)(tfp->f_data)); 1793 } 1794 for (i = info.index, fpp = info.extra_ref; --i >= 0; ++fpp) 1795 fdrop(*fpp); 1796 } while (info.index == info.maxindex); 1797 1798 kfree((caddr_t)info.extra_ref, M_FILE); 1799 1800 lwkt_reltoken(&unp_rights_token); 1801 } 1802 1803 /* 1804 * MPSAFE - NOTE: filehead list and file pointer spinlocked on entry 1805 */ 1806 static int 1807 unp_gc_checkrefs(struct file *fp, void *data) 1808 { 1809 struct unp_gc_info *info = data; 1810 1811 if (fp->f_count == 0) 1812 return(0); 1813 if (info->index == info->maxindex) 1814 return(-1); 1815 1816 /* 1817 * If all refs are from msgs, and it's not marked accessible 1818 * then it must be referenced from some unreachable cycle 1819 * of (shut-down) FDs, so include it in our 1820 * list of FDs to remove 1821 */ 1822 if (fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) { 1823 info->extra_ref[info->index++] = fp; 1824 fhold(fp); 1825 } 1826 return(0); 1827 } 1828 1829 /* 1830 * MPSAFE - NOTE: filehead list and file pointer spinlocked on entry 1831 */ 1832 static int 1833 unp_gc_clearmarks(struct file *fp, void *data __unused) 1834 { 1835 atomic_clear_int(&fp->f_flag, FMARK | FDEFER); 1836 return(0); 1837 } 1838 1839 /* 1840 * MPSAFE - NOTE: filehead list and file pointer spinlocked on entry 1841 */ 1842 static int 1843 unp_gc_checkmarks(struct file *fp, void *data) 1844 { 1845 struct unp_gc_info *info = data; 1846 struct socket *so; 1847 1848 /* 1849 * If the file is not open, skip it. Make sure it isn't marked 1850 * defered or we could loop forever, in case we somehow race 1851 * something. 1852 */ 1853 if (fp->f_count == 0) { 1854 if (fp->f_flag & FDEFER) 1855 atomic_clear_int(&fp->f_flag, FDEFER); 1856 return(0); 1857 } 1858 /* 1859 * If we already marked it as 'defer' in a 1860 * previous pass, then try process it this time 1861 * and un-mark it 1862 */ 1863 if (fp->f_flag & FDEFER) { 1864 atomic_clear_int(&fp->f_flag, FDEFER); 1865 } else { 1866 /* 1867 * if it's not defered, then check if it's 1868 * already marked.. if so skip it 1869 */ 1870 if (fp->f_flag & FMARK) 1871 return(0); 1872 /* 1873 * If all references are from messages 1874 * in transit, then skip it. it's not 1875 * externally accessible. 1876 */ 1877 if (fp->f_count == fp->f_msgcount) 1878 return(0); 1879 /* 1880 * If it got this far then it must be 1881 * externally accessible. 1882 */ 1883 atomic_set_int(&fp->f_flag, FMARK); 1884 } 1885 1886 /* 1887 * either it was defered, or it is externally 1888 * accessible and not already marked so. 1889 * Now check if it is possibly one of OUR sockets. 1890 */ 1891 if (fp->f_type != DTYPE_SOCKET || 1892 (so = (struct socket *)fp->f_data) == NULL) { 1893 return(0); 1894 } 1895 if (so->so_proto->pr_domain != &localdomain || 1896 !(so->so_proto->pr_flags & PR_RIGHTS)) { 1897 return(0); 1898 } 1899 1900 /* 1901 * So, Ok, it's one of our sockets and it IS externally accessible 1902 * (or was defered). Now we look to see if we hold any file 1903 * descriptors in its message buffers. Follow those links and mark 1904 * them as accessible too. 1905 * 1906 * We are holding multiple spinlocks here, if we cannot get the 1907 * token non-blocking defer until the next loop. 1908 */ 1909 info->locked_fp = fp; 1910 if (lwkt_trytoken(&so->so_rcv.ssb_token)) { 1911 unp_scan(so->so_rcv.ssb_mb, unp_mark, info); 1912 lwkt_reltoken(&so->so_rcv.ssb_token); 1913 } else { 1914 atomic_set_int(&fp->f_flag, FDEFER); 1915 ++info->defer; 1916 } 1917 return (0); 1918 } 1919 1920 /* 1921 * Dispose of the fp's stored in a mbuf. 1922 * 1923 * The dds loop can cause additional fps to be entered onto the 1924 * list while it is running, flattening out the operation and avoiding 1925 * a deep kernel stack recursion. 1926 */ 1927 void 1928 unp_dispose(struct mbuf *m) 1929 { 1930 lwkt_gettoken(&unp_rights_token); 1931 if (m) 1932 unp_scan(m, unp_discard, NULL); 1933 lwkt_reltoken(&unp_rights_token); 1934 } 1935 1936 static int 1937 unp_listen(struct unpcb *unp, struct thread *td) 1938 { 1939 struct proc *p = td->td_proc; 1940 1941 ASSERT_LWKT_TOKEN_HELD(&unp_token); 1942 UNP_ASSERT_TOKEN_HELD(unp); 1943 1944 KKASSERT(p); 1945 cru2x(p->p_ucred, &unp->unp_peercred); 1946 unp_setflags(unp, UNP_HAVEPCCACHED); 1947 return (0); 1948 } 1949 1950 static void 1951 unp_scan(struct mbuf *m0, void (*op)(struct file *, void *), void *data) 1952 { 1953 struct mbuf *m; 1954 struct file **rp; 1955 struct cmsghdr *cm; 1956 int i; 1957 int qfds; 1958 1959 while (m0) { 1960 for (m = m0; m; m = m->m_next) { 1961 if (m->m_type == MT_CONTROL && 1962 m->m_len >= sizeof(*cm)) { 1963 cm = mtod(m, struct cmsghdr *); 1964 if (cm->cmsg_level != SOL_SOCKET || 1965 cm->cmsg_type != SCM_RIGHTS) 1966 continue; 1967 qfds = (cm->cmsg_len - CMSG_LEN(0)) / 1968 sizeof(void *); 1969 rp = (struct file **)CMSG_DATA(cm); 1970 for (i = 0; i < qfds; i++) 1971 (*op)(*rp++, data); 1972 break; /* XXX, but saves time */ 1973 } 1974 } 1975 m0 = m0->m_nextpkt; 1976 } 1977 } 1978 1979 /* 1980 * Mark visibility. info->defer is recalculated on every pass. 1981 */ 1982 static void 1983 unp_mark(struct file *fp, void *data) 1984 { 1985 struct unp_gc_info *info = data; 1986 1987 if ((fp->f_flag & FMARK) == 0) { 1988 ++info->defer; 1989 atomic_set_int(&fp->f_flag, FMARK | FDEFER); 1990 } else if (fp->f_flag & FDEFER) { 1991 ++info->defer; 1992 } 1993 } 1994 1995 /* 1996 * Discard a fp previously held in a unix domain socket mbuf. To 1997 * avoid blowing out the kernel stack due to contrived chain-reactions 1998 * we may have to defer the operation to a higher procedural level. 1999 * 2000 * Caller holds unp_token 2001 */ 2002 static void 2003 unp_discard(struct file *fp, void *data __unused) 2004 { 2005 struct unp_defdiscard *d; 2006 2007 unp_del_right(fp); 2008 2009 d = kmalloc(sizeof(*d), M_UNPCB, M_WAITOK); 2010 d->fp = fp; 2011 2012 spin_lock(&unp_defdiscard_spin); 2013 SLIST_INSERT_HEAD(&unp_defdiscard_head, d, next); 2014 spin_unlock(&unp_defdiscard_spin); 2015 2016 taskqueue_enqueue(unp_taskqueue, &unp_defdiscard_task); 2017 } 2018 2019 /* 2020 * NOTE: 2021 * unp_token must be held before calling this function to avoid name 2022 * resolution and v_socket accessing races, especially racing against 2023 * the unp_detach(). 2024 * 2025 * NOTE: 2026 * For anyone caring about unconnected unix socket sending performance, 2027 * other approach could be taken... 2028 */ 2029 static int 2030 unp_find_lockref(struct sockaddr *nam, struct thread *td, short type, 2031 struct unpcb **unp_ret) 2032 { 2033 struct proc *p = td->td_proc; 2034 struct sockaddr_un *soun = (struct sockaddr_un *)nam; 2035 struct vnode *vp = NULL; 2036 struct socket *so; 2037 struct unpcb *unp; 2038 int error, len; 2039 struct nlookupdata nd; 2040 char buf[SOCK_MAXADDRLEN]; 2041 2042 ASSERT_LWKT_TOKEN_HELD(&unp_token); 2043 2044 *unp_ret = NULL; 2045 2046 len = nam->sa_len - offsetof(struct sockaddr_un, sun_path); 2047 if (len <= 0) { 2048 error = EINVAL; 2049 goto failed; 2050 } 2051 strncpy(buf, soun->sun_path, len); 2052 buf[len] = 0; 2053 2054 error = nlookup_init(&nd, buf, UIO_SYSSPACE, NLC_FOLLOW); 2055 if (error == 0) 2056 error = nlookup(&nd); 2057 if (error == 0) 2058 error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); 2059 nlookup_done(&nd); 2060 if (error) { 2061 vp = NULL; 2062 goto failed; 2063 } 2064 2065 if (vp->v_type != VSOCK) { 2066 error = ENOTSOCK; 2067 goto failed; 2068 } 2069 error = VOP_EACCESS(vp, VWRITE, p->p_ucred); 2070 if (error) 2071 goto failed; 2072 so = vp->v_socket; 2073 if (so == NULL) { 2074 error = ECONNREFUSED; 2075 goto failed; 2076 } 2077 if (so->so_type != type) { 2078 error = EPROTOTYPE; 2079 goto failed; 2080 } 2081 2082 /* Lock this unp. */ 2083 unp = unp_getsocktoken(so); 2084 if (!UNP_ISATTACHED(unp)) { 2085 unp_reltoken(unp); 2086 error = ECONNREFUSED; 2087 goto failed; 2088 } 2089 /* And keep this unp referenced. */ 2090 unp_reference(unp); 2091 2092 /* Done! */ 2093 *unp_ret = unp; 2094 error = 0; 2095 failed: 2096 if (vp != NULL) 2097 vput(vp); 2098 return error; 2099 } 2100 2101 static int 2102 unp_connect_pair(struct unpcb *unp, struct unpcb *unp2) 2103 { 2104 struct socket *so = unp->unp_socket; 2105 struct socket *so2 = unp2->unp_socket; 2106 2107 ASSERT_LWKT_TOKEN_HELD(&unp_token); 2108 UNP_ASSERT_TOKEN_HELD(unp); 2109 UNP_ASSERT_TOKEN_HELD(unp2); 2110 2111 KASSERT(so->so_type == so2->so_type, 2112 ("socket type mismatch, so %d, so2 %d", so->so_type, so2->so_type)); 2113 2114 if (!UNP_ISATTACHED(unp)) 2115 return EINVAL; 2116 if (!UNP_ISATTACHED(unp2)) 2117 return ECONNREFUSED; 2118 2119 KASSERT(unp->unp_conn == NULL, ("unp is already connected")); 2120 unp->unp_conn = unp2; 2121 2122 switch (so->so_type) { 2123 case SOCK_DGRAM: 2124 LIST_INSERT_HEAD(&unp2->unp_refs, unp, unp_reflink); 2125 soisconnected(so); 2126 break; 2127 2128 case SOCK_STREAM: 2129 case SOCK_SEQPACKET: 2130 KASSERT(unp2->unp_conn == NULL, ("unp2 is already connected")); 2131 unp2->unp_conn = unp; 2132 soisconnected(so); 2133 soisconnected(so2); 2134 break; 2135 2136 default: 2137 panic("unp_connect_pair: unknown socket type %d", so->so_type); 2138 } 2139 return 0; 2140 } 2141 2142 static void 2143 unp_drop(struct unpcb *unp, int error) 2144 { 2145 struct unp_global_head *head; 2146 struct unpcb *unp2; 2147 2148 ASSERT_LWKT_TOKEN_HELD(&unp_token); 2149 UNP_ASSERT_TOKEN_HELD(unp); 2150 2151 KASSERT((unp->unp_flags & (UNP_DETACHED | UNP_DROPPED)) == 0, 2152 ("unp is dropped")); 2153 2154 /* Mark this unp as detached. */ 2155 unp_setflags(unp, UNP_DETACHED); 2156 2157 /* Remove this unp from the global unp list. */ 2158 head = unp_globalhead(unp->unp_socket->so_type); 2159 KASSERT(head->count > 0, ("invalid unp count")); 2160 TAILQ_REMOVE(&head->list, unp, unp_link); 2161 head->count--; 2162 2163 /* Disconnect all. */ 2164 unp_disconnect(unp, error); 2165 while ((unp2 = LIST_FIRST(&unp->unp_refs)) != NULL) { 2166 lwkt_getpooltoken(unp2); 2167 unp_disconnect(unp2, ECONNRESET); 2168 lwkt_relpooltoken(unp2); 2169 } 2170 unp_setflags(unp, UNP_DROPPED); 2171 2172 /* Try freeing this unp. */ 2173 unp_free(unp); 2174 } 2175 2176 static void 2177 unp_defdiscard_taskfunc(void *arg __unused, int pending __unused) 2178 { 2179 struct unp_defdiscard *d; 2180 2181 spin_lock(&unp_defdiscard_spin); 2182 while ((d = SLIST_FIRST(&unp_defdiscard_head)) != NULL) { 2183 SLIST_REMOVE_HEAD(&unp_defdiscard_head, next); 2184 spin_unlock(&unp_defdiscard_spin); 2185 2186 fdrop(d->fp); 2187 kfree(d, M_UNPCB); 2188 2189 spin_lock(&unp_defdiscard_spin); 2190 } 2191 spin_unlock(&unp_defdiscard_spin); 2192 } 2193