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