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