1 /* UNIX Domain Sockets - uds.c - socket management */ 2 3 #include "uds.h" 4 5 static struct udssock uds_array[NR_UDSSOCK]; 6 static TAILQ_HEAD(uds_freelist, udssock) uds_freelist; 7 static unsigned int uds_in_use; 8 static int uds_running; 9 10 static const struct sockevent_ops uds_ops; 11 12 static SLIST_HEAD(udshash, udssock) udshash[UDSHASH_SLOTS]; 13 14 /* 15 * Initialize file-to-socket hash table. 16 */ 17 static void 18 udshash_init(void) 19 { 20 unsigned int slot; 21 22 for (slot = 0; slot < __arraycount(udshash); slot++) 23 SLIST_INIT(&udshash[slot]); 24 } 25 26 /* 27 * Return a hash table slot number for the given <dev,ino> pair. 28 */ 29 static unsigned int 30 udshash_slot(dev_t dev, ino_t ino) 31 { 32 33 assert(dev != NO_DEV); 34 assert(ino != 0); 35 36 /* 37 * Effectively combining two 64-bit numbers into a single 6-or-so-bit 38 * hash is not too easy. This hash function is probably among the 39 * worst options. Then again it is not all that critical as we are not 40 * expecting that many bound UDS sockets in the system anyway. 41 */ 42 return (unsigned int)(dev ^ ino) % UDSHASH_SLOTS; 43 } 44 45 /* 46 * Look for a socket that is bound to the given <dev,ino> pair. Return a 47 * pointer to the socket if found, or NULL otherwise. 48 */ 49 static struct udssock * 50 udshash_get(dev_t dev, ino_t ino) 51 { 52 struct udssock *uds; 53 unsigned int slot; 54 55 slot = udshash_slot(dev, ino); 56 57 SLIST_FOREACH(uds, &udshash[slot], uds_hash) { 58 if (uds->uds_dev == dev && uds->uds_ino == ino) 59 return uds; 60 } 61 62 return NULL; 63 } 64 65 /* 66 * Add a socket to the file-to-socket hash table. The socket must have its 67 * device and inode fields set, and must not be in the hash table already. 68 */ 69 static void 70 udshash_add(struct udssock * uds) 71 { 72 unsigned int slot; 73 74 slot = udshash_slot(uds->uds_dev, uds->uds_ino); 75 76 SLIST_INSERT_HEAD(&udshash[slot], uds, uds_hash); 77 } 78 79 /* 80 * Remove a socket from the file-to-socket hash table. The socket must be in 81 * the hash table. 82 */ 83 static void 84 udshash_del(struct udssock * uds) 85 { 86 unsigned int slot; 87 88 slot = udshash_slot(uds->uds_dev, uds->uds_ino); 89 90 /* This macro is O(n). */ 91 SLIST_REMOVE(&udshash[slot], uds, udssock, uds_hash); 92 } 93 94 /* 95 * Return the socket identifier for the given UDS socket object. 96 */ 97 sockid_t 98 uds_get_id(struct udssock * uds) 99 { 100 101 return (sockid_t)(uds - uds_array); 102 } 103 104 /* 105 * Given either NULL or a previously returned socket, return the next in-use 106 * UDS socket of the given socket type, or NULL if there are no more matches. 107 * The sockets are returned in random order, but each matching socket is 108 * returned exactly once (until any socket is allocated or freed). 109 */ 110 struct udssock * 111 uds_enum(struct udssock * prev, int type) 112 { 113 sockid_t id; 114 115 if (prev != NULL) 116 id = uds_get_id(prev) + 1; 117 else 118 id = 0; 119 120 for (; id < NR_UDSSOCK; id++) 121 if ((uds_array[id].uds_flags & UDSF_IN_USE) && 122 uds_get_type(&uds_array[id]) == type) 123 return &uds_array[id]; 124 125 return NULL; 126 } 127 128 /* 129 * Invalidate credentials on the socket. 130 */ 131 static void 132 uds_clear_cred(struct udssock * uds) 133 { 134 135 uds->uds_cred.unp_pid = -1; 136 uds->uds_cred.unp_euid = -1; 137 uds->uds_cred.unp_egid = -1; 138 } 139 140 /* 141 * Obtain the credentials (process, user, and group ID) of the given user 142 * endpoint and associate them with the socket for later retrieval. It is 143 * important to note that this information is obtained once at connect time, 144 * and never updated later. The party receiving the credentials must take this 145 * into account. 146 */ 147 static void 148 uds_get_cred(struct udssock * uds, endpoint_t user_endpt) 149 { 150 int r; 151 152 if ((uds->uds_cred.unp_pid = r = getepinfo(user_endpt, 153 &uds->uds_cred.unp_euid, &uds->uds_cred.unp_egid)) < 0) { 154 printf("UDS: failed obtaining credentials of %d (%d)\n", 155 user_endpt, r); 156 157 uds_clear_cred(uds); 158 } 159 } 160 161 /* 162 * Allocate and initialize a UDS socket. On succes, return OK with a pointer 163 * to the new socket in 'udsp'. On failure, return a negative error code. 164 */ 165 static int 166 uds_alloc(struct udssock ** udsp) 167 { 168 struct udssock *uds; 169 int r; 170 171 /* Allocate, initialize, and return a UNIX domain socket object. */ 172 if (TAILQ_EMPTY(&uds_freelist)) 173 return ENOBUFS; 174 175 uds = TAILQ_FIRST(&uds_freelist); 176 177 uds->uds_conn = NULL; /* not connected */ 178 uds->uds_link = NULL; /* not connecting or linked */ 179 uds->uds_queued = 0; 180 uds->uds_flags = UDSF_IN_USE; /* may be found through enumeration */ 181 uds->uds_pathlen = 0; /* not bound: no path */ 182 uds->uds_dev = NO_DEV; /* not hashed: no socket file device */ 183 uds->uds_ino = 0; /* not hashed: no socket file inode */ 184 uds_clear_cred(uds); /* no bind/connect-time credentials */ 185 TAILQ_INIT(&uds->uds_queue); /* an empty queue */ 186 187 if ((r = uds_io_setup(uds)) != OK) 188 return r; 189 190 TAILQ_REMOVE(&uds_freelist, uds, uds_next); 191 192 assert(uds_in_use < NR_UDSSOCK); 193 uds_in_use++; 194 195 *udsp = uds; 196 return OK; 197 } 198 199 /* 200 * Free a previously allocated socket. 201 */ 202 static void 203 uds_free(struct sock * sock) 204 { 205 struct udssock *uds = (struct udssock *)sock; 206 207 uds_io_cleanup(uds); 208 209 uds->uds_flags = 0; /* no longer in use */ 210 211 TAILQ_INSERT_HEAD(&uds_freelist, uds, uds_next); 212 213 assert(uds_in_use > 0); 214 if (--uds_in_use == 0 && uds_running == FALSE) 215 sef_cancel(); 216 } 217 218 /* 219 * Create a new socket. 220 */ 221 static sockid_t 222 uds_socket(int domain, int type, int protocol, endpoint_t user_endpt __unused, 223 struct sock ** sockp, const struct sockevent_ops ** ops) 224 { 225 struct udssock *uds; 226 int r; 227 228 dprintf(("UDS: socket(%d,%d,%d)\n", domain, type, protocol)); 229 230 if (domain != PF_UNIX) { 231 /* This means the service was configured incorrectly. */ 232 printf("UDS: got request for domain %d\n", domain); 233 234 return EAFNOSUPPORT; 235 } 236 237 /* We support the following three socket types. */ 238 switch (type) { 239 case SOCK_STREAM: 240 case SOCK_SEQPACKET: 241 case SOCK_DGRAM: 242 break; 243 default: 244 return EPROTOTYPE; 245 } 246 247 /* 248 * The PF_UNIX domain does not support particular protocols, so the 249 * given protocol must be zero (= anything that matches). 250 */ 251 if (protocol != UDSPROTO_UDS) 252 return EPROTONOSUPPORT; 253 254 if ((r = uds_alloc(&uds)) != OK) 255 return r; 256 257 dprintf(("UDS: socket returns %d\n", uds_get_id(uds))); 258 259 *sockp = &uds->uds_sock; 260 *ops = &uds_ops; 261 return uds_get_id(uds); 262 } 263 264 /* 265 * Connect a pair of sockets. 266 */ 267 static int 268 uds_pair(struct sock * sock1, struct sock * sock2, endpoint_t user_endpt) 269 { 270 struct udssock *uds1 = (struct udssock *)sock1; 271 struct udssock *uds2 = (struct udssock *)sock2; 272 273 dprintf(("UDS: pair(%d,%d)\n", uds_get_id(uds1), uds_get_id(uds2))); 274 275 /* Only connection-oriented types are acceptable. */ 276 if (uds_get_type(uds1) == SOCK_DGRAM) 277 return EOPNOTSUPP; 278 279 /* Connect the sockets. */ 280 uds1->uds_conn = uds2; 281 uds2->uds_conn = uds1; 282 uds1->uds_flags |= UDSF_CONNECTED; 283 uds2->uds_flags |= UDSF_CONNECTED; 284 285 /* Obtain the (same) credentials for both sides of the connection. */ 286 uds_get_cred(uds1, user_endpt); 287 memcpy(&uds2->uds_cred, &uds1->uds_cred, sizeof(uds2->uds_cred)); 288 289 return OK; 290 } 291 292 /* 293 * Disconnect a UDS socket, notifying or freeing up the other end of the 294 * connection depending on whether the socket was linked, that is, on the 295 * accept queue of a listening socket. 296 */ 297 static void 298 uds_disconnect(struct udssock * uds, int was_linked) 299 { 300 struct udssock *conn; 301 302 assert(uds_is_connected(uds)); 303 assert(uds_has_conn(uds)); 304 305 conn = uds->uds_conn; 306 307 assert(uds_is_connected(conn)); 308 assert(uds_has_conn(conn)); 309 assert(!uds_has_link(conn)); 310 assert(conn->uds_conn == uds); 311 312 /* Disconnect the sockets. */ 313 uds->uds_conn = NULL; 314 conn->uds_conn = NULL; 315 316 /* 317 * If the given socket is linked, then it is a connected socket for 318 * which the other end has been created but not yet accepted. In that 319 * case, the other end ('conn') will have to be freed up. Otherwise, 320 * it is a regular user-created socket and we must properly transition 321 * it into disconnected state. 322 */ 323 if (!was_linked) { 324 sockevent_raise(&conn->uds_sock, SEV_SEND | SEV_RECV); 325 326 /* 327 * Clear the peer credentials so that they will not be mistaken 328 * for having been obtained at bind time. 329 */ 330 uds_clear_cred(conn); 331 } else 332 sockevent_raise(&conn->uds_sock, SEV_CLOSE); 333 } 334 335 /* 336 * Add the socket 'link' to the queue of the socket 'uds'. This also implies 337 * that 'link's link socket is set to 'uds'. 338 */ 339 static void 340 uds_add_queue(struct udssock * uds, struct udssock * link) 341 { 342 343 dprintf(("UDS: add_queue(%d,%d)\n", 344 uds_get_id(uds), uds_get_id(link))); 345 346 TAILQ_INSERT_TAIL(&uds->uds_queue, link, uds_next); 347 348 uds->uds_queued++; 349 assert(uds->uds_queued != 0); 350 351 link->uds_link = uds; 352 } 353 354 /* 355 * Remove the socket 'link' from the queue of the socket 'uds'. This also 356 * reset 'link's link to NULL. 357 */ 358 static void 359 uds_del_queue(struct udssock * uds, struct udssock * link) 360 { 361 362 dprintf(("UDS: del_queue(%d,%d)\n", 363 uds_get_id(uds), uds_get_id(link))); 364 365 assert(link->uds_link == uds); 366 367 TAILQ_REMOVE(&uds->uds_queue, link, uds_next); 368 369 assert(uds->uds_queued > 0); 370 uds->uds_queued--; 371 372 link->uds_link = NULL; 373 } 374 375 /* 376 * Remove all sockets from the queue of the socket 'uds', with the exception of 377 * 'except' if non-NULL. Raise an ECONNRESET error on all removed sockets that 378 * are not equal to 'uds'. 379 */ 380 static void 381 uds_clear_queue(struct udssock * uds, struct udssock * except) 382 { 383 struct udssock *link, *tmp; 384 int found; 385 386 dprintf(("UDS: clear_queue(%d,%d)\n", 387 uds_get_id(uds), (except != NULL) ? uds_get_id(except) : -1)); 388 389 found = 0; 390 391 /* 392 * Abort all connecting sockets queued on this socket, except for the 393 * given exception, which may be NULL. 394 */ 395 TAILQ_FOREACH_SAFE(link, &uds->uds_queue, uds_next, tmp) { 396 if (link == except) { 397 found++; 398 399 continue; 400 } 401 402 dprintf(("UDS: clear_queue removes %d\n", uds_get_id(link))); 403 404 assert(uds_get_type(link) == SOCK_DGRAM || 405 uds_is_connecting(link) || uds_is_connected(link)); 406 407 uds_del_queue(uds, link); 408 409 /* 410 * Generate an error only if the socket was not linked to 411 * itself (only datagram sockets can be linked to themselves). 412 * The error is not helpful for applications in that case. 413 */ 414 if (uds != link) 415 sockevent_set_error(&link->uds_sock, ECONNRESET); 416 417 /* 418 * If this is a listening socket, disconnect the connecting or 419 * connected end. If a connected peer was already created for 420 * the queued socket, dispose of that peer. 421 * 422 * Clear credentials obtained when starting to connect (in 423 * which case the socket is always a connection-oriented 424 * socket), so that they will not be mistaken for credentials 425 * obtained at bind time. 426 */ 427 if (uds_get_type(link) != SOCK_DGRAM) { 428 if (uds_is_connected(link)) 429 uds_disconnect(link, TRUE /*was_linked*/); 430 else 431 uds_clear_cred(link); 432 } 433 } 434 435 assert(uds->uds_queued == found); 436 } 437 438 /* 439 * Check whether the socket address given in 'addr', with length 'addr_len', is 440 * a valid UNIX domain socket address (including a path to a socket file). On 441 * success, return the (non-zero) length of the socket file's path, minus the 442 * null terminator which may in fact not be present. The caller is responsible 443 * for copying and terminating the path as needed. A pointer to the path as 444 * stored in 'addr' is returned in 'pathp'. On failure, return an error code. 445 */ 446 static int 447 uds_check_addr(const struct sockaddr * addr, socklen_t addr_len, 448 const char ** pathp) 449 { 450 const char *p; 451 size_t len; 452 453 /* 454 * We could cast to a sockaddr_un structure pointer first, but that 455 * would not provide any benefits here. Instead, we use sa_data as the 456 * generic equivalent of sun_path. 457 */ 458 if (addr_len < offsetof(struct sockaddr, sa_data)) 459 return EINVAL; 460 461 if (addr->sa_family != AF_UNIX) 462 return EAFNOSUPPORT; 463 464 len = (size_t)addr_len - offsetof(struct sockaddr, sa_data); 465 if (len > 0 && (p = memchr(addr->sa_data, '\0', len)) != NULL) 466 len = (size_t)(p - addr->sa_data); 467 468 /* The given path name must not be an empty string. */ 469 if (len == 0) 470 return ENOENT; 471 472 /* This check should be redundant but better safe than sorry. */ 473 if (len >= UDS_PATH_MAX) 474 return EINVAL; 475 476 *pathp = (const char *)addr->sa_data; 477 return len; 478 } 479 480 /* 481 * Given the socket file path given as 'path' with length 'path_len' (not 482 * necessarily null terminated), store a socket address with the path in 483 * 'addr', and return the socket address length in 'addr_len'. The calling 484 * libraries (libsockdriver, libsockevent) and the static assert in uds.h 485 * guarantee that 'addr' is sufficiently large to store any address we generate 486 * here. The libraries may subsequently copy out only a part of it to the user 487 * process. This function always succeeds. 488 */ 489 void 490 uds_make_addr(const char * path, size_t len, struct sockaddr * addr, 491 socklen_t * addr_len) 492 { 493 494 /* 495 * Generate the address. The stored length (sa_len/sun_len) does not 496 * include a null terminator. The entire structure does include a null 497 * terminator, but only if the socket is bound. 498 */ 499 addr->sa_len = offsetof(struct sockaddr, sa_data) + len; 500 addr->sa_family = AF_UNIX; 501 if (len > 0) { 502 /* This call may (intentionally) overrun the sa_data size. */ 503 memcpy((char *)addr->sa_data, path, len); 504 ((char *)addr->sa_data)[len] = '\0'; 505 506 /* The socket is bound, so include the null terminator. */ 507 len++; 508 assert(len <= UDS_PATH_MAX); 509 } 510 511 /* Note that this length may be different from sa_len/sun_len now. */ 512 *addr_len = offsetof(struct sockaddr, sa_data) + len; 513 } 514 515 /* 516 * Bind a socket to a local address. 517 */ 518 static int 519 uds_bind(struct sock * sock, const struct sockaddr * addr, socklen_t addr_len, 520 endpoint_t user_endpt) 521 { 522 struct udssock *uds = (struct udssock *)sock; 523 struct udssock *uds2; 524 const char *path; 525 size_t len; 526 dev_t dev; 527 ino_t ino; 528 int r; 529 530 dprintf(("UDS: bind(%d)\n", uds_get_id(uds))); 531 532 /* A socket may be bound at any time, but only once. */ 533 if (uds_is_bound(uds)) 534 return EINVAL; 535 536 /* Verify that the user gave us an acceptable address. */ 537 if ((r = uds_check_addr(addr, addr_len, &path)) < 0) 538 return r; 539 len = (size_t)r; 540 541 /* Attempt to create the socket file on the file system. */ 542 r = socketpath(user_endpt, path, len, SPATH_CREATE, &dev, &ino); 543 if (r != OK) 544 return r; 545 assert(dev != NO_DEV && ino != 0); 546 547 /* 548 * It is possible that a socket file of a previously bound socket was 549 * unlinked, and due to inode number reuse, a new socket file has now 550 * been created with the same <dev,ino> pair. In that case, we must 551 * unbind the old socket, because it must no longer be found. The old 552 * socket will still have a path (and behave as though it is bound) but 553 * no longer be found through hash lookups. 554 */ 555 if ((uds2 = udshash_get(dev, ino)) != NULL) { 556 udshash_del(uds2); 557 558 uds2->uds_dev = NO_DEV; 559 uds2->uds_ino = 0; 560 } 561 562 /* 563 * Obtain credentials for the socket, unless the socket is already 564 * connecting or connected, in which case we must not replace the 565 * credentials we obtained already. We later clear those credentials 566 * upon a connection failure or disconnect, so that if the socket is 567 * then put in listening mode, we know there are no bind-time 568 * credentials. Not ideal, but we really need two separate sets of 569 * credentials if we want to get this right, which is a waste of memory 570 * as no sane application writer would ever rely on credential passing 571 * after recycling a socket.. 572 */ 573 if (uds_get_type(uds) != SOCK_DGRAM && !uds_is_connecting(uds) && 574 !uds_is_connected(uds)) 575 uds_get_cred(uds, user_endpt); 576 577 /* Asssign the address to the socket. */ 578 uds->uds_pathlen = len; 579 memcpy(&uds->uds_path, path, len); 580 uds->uds_dev = dev; 581 uds->uds_ino = ino; 582 583 udshash_add(uds); 584 585 return OK; 586 } 587 588 /* 589 * Look up a UDS socket based on a user-given address. If a socket exists for 590 * the address, check if it is type-compatible with the given UDS socket. 591 * On succes, return OK, with 'peerp' set to the socket that was found. On 592 * failure, return a negative error code. 593 */ 594 int 595 uds_lookup(struct udssock * uds, const struct sockaddr * addr, 596 socklen_t addr_len, endpoint_t user_endpt, struct udssock ** peerp) 597 { 598 struct udssock *peer; 599 const char *path; 600 size_t len; 601 dev_t dev; 602 ino_t ino; 603 int r; 604 605 /* Verify that the user gave us an acceptable address. */ 606 if ((r = uds_check_addr(addr, addr_len, &path)) < 0) 607 return r; 608 len = (size_t)r; 609 610 /* Attempt to look up the socket file on the file system. */ 611 r = socketpath(user_endpt, path, len, SPATH_CHECK, &dev, &ino); 612 if (r != OK) 613 return r; 614 assert(dev != NO_DEV && ino != 0); 615 616 if ((peer = udshash_get(dev, ino)) == NULL) 617 return ECONNREFUSED; 618 if (uds_get_type(peer) != uds_get_type(uds)) 619 return EPROTOTYPE; 620 621 *peerp = peer; 622 return OK; 623 } 624 625 /* 626 * Given the listening socket 'uds', and the socket 'link' that is calling or 627 * has called connect(2) and is or will be linked to the listening socket's 628 * queue, create a new socket and connect it to 'link', putting both sockets in 629 * the connected state. The given link socket may be in unconnected, 630 * connecting, or disconnected state prior to the call. Return OK or an error 631 * code. The link state of the link socket remains unchanged in any case. 632 */ 633 static int 634 uds_attach(struct udssock * uds, struct udssock * link) 635 { 636 struct udssock *conn; 637 int r; 638 639 /* 640 * Allocate a new socket to use as peer socket for the connection that 641 * is about to be established. The new socket is not yet known by 642 * libsockevent. 643 */ 644 if ((r = uds_alloc(&conn)) != OK) 645 return r; 646 647 /* 648 * Ask libsockevent to clone the sock object in the new UDS socket from 649 * the listening socket. This adds the sock object to libsockevent's 650 * data structures and ensures that we can safely use the socket 651 * despite the fact that it has not yet been accepted (and thus 652 * returned to libsockevent). From this moment on, we must either 653 * return the socket's ID (but not a pointer to it!) from uds_accept() 654 * or raise SEV_CLOSE on it. 655 */ 656 sockevent_clone(&uds->uds_sock, &conn->uds_sock, uds_get_id(conn)); 657 658 /* Connect the link socket to the new socket. */ 659 link->uds_conn = conn; 660 link->uds_flags |= UDSF_CONNECTED; 661 662 /* 663 * Connect the new socket to the link socket as well. The child 664 * socket should also inherit pretty much all settings from the 665 * listening socket, including the bind path and the listening socket's 666 * bind-time credentials. 667 */ 668 conn->uds_conn = link; 669 conn->uds_flags = uds->uds_flags & (UDSF_PASSCRED | UDSF_CONNWAIT); 670 conn->uds_flags |= UDSF_CONNECTED; 671 conn->uds_pathlen = uds->uds_pathlen; 672 memcpy(conn->uds_path, uds->uds_path, (size_t)uds->uds_pathlen); 673 memcpy(&conn->uds_cred, &uds->uds_cred, sizeof(conn->uds_cred)); 674 675 return OK; 676 } 677 678 /* 679 * Connect a socket to a remote address. 680 */ 681 static int 682 uds_connect(struct sock * sock, const struct sockaddr * addr, 683 socklen_t addr_len, endpoint_t user_endpt) 684 { 685 struct udssock *uds = (struct udssock *)sock; 686 struct udssock *link; 687 int r; 688 689 dprintf(("UDS: connect(%d)\n", uds_get_id(uds))); 690 691 /* For connection-oriented sockets, several state checks apply. */ 692 if (uds_get_type(uds) != SOCK_DGRAM) { 693 if (uds_is_listening(uds)) 694 return EOPNOTSUPP; 695 if (uds_is_connecting(uds)) 696 return EALREADY; 697 if (uds_is_connected(uds)) 698 return EISCONN; 699 /* Disconnected sockets may be reconnected, see below. */ 700 } else { 701 /* 702 * Connectionless sockets may be unconnected by providing an 703 * address with family AF_UNSPEC. Handle this case first here. 704 */ 705 if (addr_len >= offsetof(struct sockaddr, sa_data) && 706 addr->sa_family == AF_UNSPEC) { 707 /* 708 * Reset this socket's previous connection to another 709 * socket, if any. Unconnecting has no effect on other 710 * sockets connected to this socket, though. 711 */ 712 if (uds_has_link(uds)) 713 uds_del_queue(uds->uds_link, uds); 714 715 return OK; 716 } 717 } 718 719 /* 720 * Find the socket identified by the given address. If it exists at 721 * all, see if it is a proper match. 722 */ 723 if ((r = uds_lookup(uds, addr, addr_len, user_endpt, &link)) != OK) 724 return r; 725 726 /* 727 * Handle connectionless sockets first, in which case a connect links 728 * the socket to a send target and limits receipt to datagrams from 729 * that target. We actually point the socket to the peer socket, 730 * through uds_link. That also means that if the target socket 731 * disappears, we have to reset any sockets connected to it, in which 732 * case we return them to the unconnected state. In order to allow 733 * finding all sockets connected to a particular socket, we put all 734 * those sockets on their target's queue, hence why we use uds_link and 735 * not uds_conn. As mentioned before, we allow reconnecting without 736 * restrictions. 737 * TODO: see if reconnecting should clear a pending ECONNRESET. 738 * 739 * An important note: 'uds' and 'link' may actually be the same socket, 740 * if the caller chooses to connect a socket with itself! 741 */ 742 if (uds_get_type(uds) == SOCK_DGRAM) { 743 /* Reconnecting to the same socket has no effect. */ 744 if (uds_has_link(uds) && uds->uds_link == link) 745 return OK; 746 747 /* 748 * If the intended target is linked to another socket, we 749 * refuse linking to it. Sending or receiving would never work 750 * anyway. Do allow a socket to link to itself after being 751 * linked to another socket. The error code is the same as in 752 * the sending code, borrowed from Linux. 753 */ 754 if (uds != link && uds_has_link(link) && link->uds_link != uds) 755 return EPERM; 756 757 /* 758 * Reset this socket's previous link to another socket, if any. 759 */ 760 if (uds_has_link(uds)) 761 uds_del_queue(uds->uds_link, uds); 762 763 /* 764 * Reset any links to this socket, except for the one by 765 * the intended target. Sending or receiving would no longer 766 * work anyway. If the socket was linked to itself, clear its 767 * self-link without generating an ECONNRESET. If the socket 768 * is relinking to itself, reestablish the link after first 769 * clearing it. 770 */ 771 uds_clear_queue(uds, (uds != link) ? link : NULL); 772 773 uds_add_queue(link, uds); 774 775 return OK; 776 } 777 778 /* 779 * For connection-oriented sockets there is more to do. First, make 780 * sure that the peer is a listening socket, that it has not been shut 781 * down, and that its backlog is not already at the configured maximum. 782 */ 783 if (!uds_is_listening(link)) 784 return ECONNREFUSED; 785 786 if (uds_is_shutdown(link, SFL_SHUT_RD | SFL_SHUT_WR)) 787 return ECONNREFUSED; 788 789 if (link->uds_queued >= link->uds_backlog) 790 return ECONNREFUSED; 791 792 /* 793 * The behavior of connect(2) now depends on whether LOCAL_CONNWAIT is 794 * set on either the connecting or the listening socket. If it is not, 795 * the socket will be connected to a new as-yet invisible socket, which 796 * will be the one returned from accept(2) later. If it was, the 797 * socket will be put in the connecting state. 798 */ 799 if (!((uds->uds_flags | link->uds_flags) & UDSF_CONNWAIT)) { 800 if ((r = uds_attach(link, uds)) != OK) 801 return r; 802 803 assert(uds_is_connected(uds)); 804 } else { 805 /* 806 * Disconnected sockets now stop being connected. Any pending 807 * data can still be received, though. 808 */ 809 uds->uds_flags &= ~UDSF_CONNECTED; 810 811 r = SUSPEND; 812 } 813 814 /* Obtain credentials for the socket. */ 815 uds_get_cred(uds, user_endpt); 816 817 /* Add the socket at the end of the listening socket's queue. */ 818 uds_add_queue(link, uds); 819 820 assert(r != SUSPEND || uds_is_connecting(uds)); 821 822 /* 823 * Let an accept call handle the rest, which will in turn resume this 824 * connect call. The sockevent library ensures that this works even if 825 * the call is non-blocking. 826 */ 827 sockevent_raise(&link->uds_sock, SEV_ACCEPT); 828 829 return r; 830 } 831 832 /* 833 * Put a socket in listening mode. 834 */ 835 static int 836 uds_listen(struct sock * sock, int backlog) 837 { 838 struct udssock *uds = (struct udssock *)sock; 839 840 /* The maximum backlog value must not exceed its field size. */ 841 assert(SOMAXCONN <= USHRT_MAX); 842 843 dprintf(("UDS: listen(%d)\n", uds_get_id(uds))); 844 845 /* Only connection-oriented types may be put in listening mode. */ 846 if (uds_get_type(uds) == SOCK_DGRAM) 847 return EOPNOTSUPP; 848 849 /* A connecting or connected socket may not listen. */ 850 if (uds_is_connecting(uds) || uds_is_connected(uds)) 851 return EINVAL; 852 853 /* POSIX says that this is now the appropriate error code here. */ 854 if (!uds_is_bound(uds)) 855 return EDESTADDRREQ; 856 857 /* 858 * The socket is now entering the listening state. If it was 859 * previously disconnected, clear the connection flag. 860 */ 861 uds->uds_flags &= ~UDSF_CONNECTED; 862 863 /* 864 * We do not remove sockets from the backlog if it is now being dropped 865 * below the current number of queued sockets. We only refuse newly 866 * connecting sockets beyond the backlog size. 867 */ 868 uds->uds_backlog = backlog; 869 870 return OK; 871 } 872 873 /* 874 * Test whether an accept request would block. Return OK if a socket could be 875 * accepted, an appropriate error code if an accept call would fail instantly, 876 * or SUSPEND if the accept request would block waiting for a connection. 877 */ 878 static int 879 uds_test_accept(struct sock * sock) 880 { 881 struct udssock *uds = (struct udssock *)sock; 882 883 /* 884 * Ensure that the socket is in listening mode. If not, we must return 885 * the error code that is appropriate for this socket type. 886 */ 887 if (uds_get_type(uds) == SOCK_DGRAM) 888 return EOPNOTSUPP; 889 if (!uds_is_listening(uds)) 890 return EINVAL; 891 892 /* 893 * If the socket has been shut down, new connections are no longer 894 * accepted and accept calls no longer block. This is not a POSIX 895 * requirement, but rather an application convenience feature. 896 */ 897 if (uds->uds_queued == 0) { 898 if (uds_is_shutdown(uds, SFL_SHUT_RD | SFL_SHUT_WR)) 899 return ECONNABORTED; 900 901 return SUSPEND; 902 } 903 904 return OK; 905 } 906 907 /* 908 * Accept a connection on a listening socket, creating a new socket. On 909 * success, return the new socket identifier, with the new socket stored in 910 * 'newsockp'. Otherwise, return an error code. 911 */ 912 static sockid_t 913 uds_accept(struct sock * sock, struct sockaddr * addr, socklen_t * addr_len, 914 endpoint_t user_endpt __unused, struct sock ** newsockp) 915 { 916 struct udssock *uds = (struct udssock *)sock; 917 struct udssock *link, *conn; 918 sockid_t r; 919 920 dprintf(("UDS: accept(%d)\n", uds_get_id(uds))); 921 922 if ((r = uds_test_accept(sock)) != OK) 923 return r; 924 925 /* 926 * Take the first connecting socket off the listening queue. 927 */ 928 assert(!TAILQ_EMPTY(&uds->uds_queue)); 929 930 link = TAILQ_FIRST(&uds->uds_queue); 931 932 /* 933 * Depending on the LOCAL_CONNWAIT setting at the time of connect(2), 934 * the socket may be connecting or connected. In the latter case, its 935 * attached socket is the socket we will return now. Otherwise we have 936 * to attach a socket first. 937 */ 938 assert(uds_is_connecting(link) || uds_is_connected(link)); 939 940 if (uds_is_connecting(link)) { 941 /* 942 * Attach a new socket. If this fails, return the error but 943 * leave the connecting socket on the listening queue. 944 */ 945 if ((r = uds_attach(uds, link)) != OK) 946 return r; 947 948 assert(uds_is_connected(link)); 949 950 /* 951 * Wake up blocked (connect, send, select) calls on the peer 952 * socket. 953 */ 954 sockevent_raise(&link->uds_sock, SEV_CONNECT); 955 } 956 957 uds_del_queue(uds, link); 958 959 /* Return the peer socket's address to the caller. */ 960 uds_make_addr(link->uds_path, link->uds_pathlen, addr, addr_len); 961 962 conn = link->uds_conn; 963 964 dprintf(("UDS: accept returns %d\n", uds_get_id(conn))); 965 966 /* 967 * We already cloned the sock object, so return its ID but not a 968 * pointer to it. That tells libsockevent not to reinitialize it. 969 */ 970 *newsockp = NULL; 971 return uds_get_id(conn); 972 } 973 974 /* 975 * Set socket options. 976 */ 977 static int 978 uds_setsockopt(struct sock * sock, int level, int name, 979 const struct sockdriver_data * data, socklen_t len) 980 { 981 struct udssock *uds = (struct udssock *)sock; 982 int r, val; 983 984 dprintf(("UDS: setsockopt(%d,%d,%d)\n", uds_get_id(uds), level, name)); 985 986 switch (level) { 987 case SOL_SOCKET: 988 switch (name) { 989 case SO_SNDBUF: 990 case SO_RCVBUF: 991 /* 992 * The send buffer size may not be changed because the 993 * buffer is the same as the other side's receive 994 * buffer, and what the other side is may vary from 995 * send call to send call. Changing the receive buffer 996 * size would disallow us from even accurately guessing 997 * the send buffer size in getsockopt calls. Therefore 998 * both are hardcoded and cannot actually be changed. 999 * In order to support applications that want at least 1000 * a certain minimum, we do accept requests to shrink 1001 * either buffer, but we ignore the given size. 1002 */ 1003 if ((r = sockdriver_copyin_opt(data, &val, sizeof(val), 1004 len)) != OK) 1005 return r; 1006 1007 if (val <= 0 || (size_t)val > uds_io_buflen()) 1008 return EINVAL; 1009 1010 return OK; /* ignore new value */ 1011 } 1012 1013 break; 1014 1015 case UDSPROTO_UDS: 1016 switch (name) { 1017 case LOCAL_CREDS: 1018 if ((r = sockdriver_copyin_opt(data, &val, sizeof(val), 1019 len)) != OK) 1020 return r; 1021 1022 if (val) 1023 uds->uds_flags |= UDSF_PASSCRED; 1024 else 1025 uds->uds_flags &= ~UDSF_PASSCRED; 1026 1027 /* 1028 * In incredibly rare cases, disabling this flag may 1029 * allow blocked sends to be resumed, because suddenly 1030 * no room for the credentials is needed in the receive 1031 * buffer anymore. 1032 */ 1033 if (!val) 1034 sockevent_raise(&uds->uds_sock, SEV_SEND); 1035 1036 return OK; 1037 1038 case LOCAL_CONNWAIT: 1039 if ((r = sockdriver_copyin_opt(data, &val, sizeof(val), 1040 len)) != OK) 1041 return r; 1042 1043 if (val) 1044 uds->uds_flags |= UDSF_CONNWAIT; 1045 else 1046 uds->uds_flags &= ~UDSF_CONNWAIT; 1047 1048 /* 1049 * Changing the setting does not affect sockets that 1050 * are currently pending to be accepted. Therefore, 1051 * uds_accept() may have to deal with either case on a 1052 * socket-by-socket basis. 1053 */ 1054 return OK; 1055 1056 case LOCAL_PEEREID: 1057 /* This option may be retrieved but not set. */ 1058 return ENOPROTOOPT; 1059 } 1060 1061 break; 1062 } 1063 1064 return ENOPROTOOPT; 1065 } 1066 1067 /* 1068 * Retrieve socket options. 1069 */ 1070 static int 1071 uds_getsockopt(struct sock * sock, int level, int name, 1072 const struct sockdriver_data * data, socklen_t * len) 1073 { 1074 struct udssock *uds = (struct udssock *)sock; 1075 int val; 1076 1077 dprintf(("UDS: getsockopt(%d,%d,%d)\n", uds_get_id(uds), level, name)); 1078 1079 switch (level) { 1080 case SOL_SOCKET: 1081 switch (name) { 1082 case SO_SNDBUF: 1083 case SO_RCVBUF: 1084 /* See uds_setsockopt() for why this is static. */ 1085 val = (int)uds_io_buflen(); 1086 1087 return sockdriver_copyout_opt(data, &val, sizeof(val), 1088 len); 1089 } 1090 1091 break; 1092 1093 case UDSPROTO_UDS: 1094 switch (name) { 1095 case LOCAL_CREDS: 1096 val = !!(uds->uds_flags & UDSF_PASSCRED); 1097 1098 return sockdriver_copyout_opt(data, &val, sizeof(val), 1099 len); 1100 1101 case LOCAL_CONNWAIT: 1102 val = !!(uds->uds_flags & UDSF_CONNWAIT); 1103 1104 return sockdriver_copyout_opt(data, &val, sizeof(val), 1105 len); 1106 1107 case LOCAL_PEEREID: 1108 /* getpeereid(3) documents these error codes. */ 1109 if (uds_get_type(uds) == SOCK_DGRAM) 1110 return EINVAL; 1111 if (!uds_is_connected(uds)) 1112 return ENOTCONN; 1113 1114 /* 1115 * This is a custom MINIX3 error, indicating that there 1116 * are no credentials to return. This could be due to 1117 * a failure to obtain them (which *should* not happen) 1118 * but also if the socket was bound while connected, 1119 * disconnected, and then reused as listening socket. 1120 */ 1121 if (uds->uds_conn->uds_cred.unp_pid == -1) 1122 return EINVAL; 1123 1124 return sockdriver_copyout_opt(data, 1125 &uds->uds_conn->uds_cred, 1126 sizeof(uds->uds_conn->uds_cred), len); 1127 } 1128 1129 break; 1130 } 1131 1132 return ENOPROTOOPT; 1133 } 1134 1135 /* 1136 * Retrieve a socket's local address. 1137 */ 1138 static int 1139 uds_getsockname(struct sock * sock, struct sockaddr * addr, 1140 socklen_t * addr_len) 1141 { 1142 struct udssock *uds = (struct udssock *)sock; 1143 1144 dprintf(("UDS: getsockname(%d)\n", uds_get_id(uds))); 1145 1146 uds_make_addr(uds->uds_path, uds->uds_pathlen, addr, addr_len); 1147 1148 return OK; 1149 } 1150 1151 /* 1152 * Retrieve a socket's remote address. 1153 */ 1154 static int 1155 uds_getpeername(struct sock * sock, struct sockaddr * addr, 1156 socklen_t * addr_len) 1157 { 1158 struct udssock *uds = (struct udssock *)sock; 1159 struct udssock *peer; 1160 1161 dprintf(("UDS: getpeername(%d)\n", uds_get_id(uds))); 1162 1163 /* 1164 * For disconnected sockets, we no longer have a peer socket and thus 1165 * also no peer address. Too bad, but NetBSD does the same. 1166 * 1167 * For connecting sockets we could in fact return a peer address, but 1168 * POSIX says (and other platforms agree) that we should deny the call. 1169 */ 1170 peer = uds_get_peer(uds); 1171 1172 if (peer == NULL || uds_is_connecting(uds)) 1173 return ENOTCONN; 1174 1175 uds_make_addr(peer->uds_path, peer->uds_pathlen, addr, addr_len); 1176 1177 return OK; 1178 } 1179 1180 /* 1181 * Shut down socket send and receive operations. Note that 'flags' is a 1182 * bitwise mask with libsockevent's SFL_SHUT_{RD,WR} flags rather than the set 1183 * of SHUT_{RD,WR,RDWR} values from userland. 1184 */ 1185 static int 1186 uds_shutdown(struct sock * sock, unsigned int flags) 1187 { 1188 struct udssock *uds = (struct udssock *)sock; 1189 struct udssock *conn; 1190 unsigned int mask; 1191 1192 dprintf(("UDS: shutdown(%d,0x%x)\n", uds_get_id(uds), flags)); 1193 1194 /* 1195 * If we are shutting down the socket for reading, we can already close 1196 * any in-flight file descriptors associated with this socket. 1197 */ 1198 if (flags & SFL_SHUT_RD) 1199 uds_io_reset(uds); 1200 1201 /* 1202 * A shutdown on this side of a connection may have an effect on 1203 * ongoing operations on the other side. Fire appropriate events. 1204 */ 1205 if (uds_is_connected(uds)) { 1206 assert(uds_get_type(uds) != SOCK_DGRAM); 1207 1208 conn = uds->uds_conn; 1209 1210 mask = 0; 1211 if (flags & SFL_SHUT_RD) 1212 mask |= SEV_SEND; 1213 if (flags & SFL_SHUT_WR) 1214 mask |= SEV_RECV; 1215 1216 sockevent_raise(&conn->uds_sock, mask); 1217 } 1218 1219 return OK; 1220 } 1221 1222 /* 1223 * Close a socket. 1224 * 1225 * The 'force' flag is unused because we need never wait for data to be sent, 1226 * since we keep all in-flight data on the receiver side. 1227 */ 1228 static int 1229 uds_close(struct sock * sock, int force __unused) 1230 { 1231 struct udssock *uds = (struct udssock *)sock; 1232 1233 dprintf(("UDS: close(%d)\n", uds_get_id(uds))); 1234 1235 if (uds_get_type(uds) == SOCK_DGRAM) { 1236 /* If this socket is linked to a target, disconnect it. */ 1237 if (uds_has_link(uds)) 1238 uds_del_queue(uds->uds_link, uds); 1239 1240 /* Reset all sockets linked to this socket as a target. */ 1241 uds_clear_queue(uds, NULL); 1242 } else if (uds_is_listening(uds)) { 1243 /* 1244 * Abort all connecting sockets queued on this socket, and 1245 * break all connections for connected sockets queued on this 1246 * socket, freeing their peers. 1247 */ 1248 uds_clear_queue(uds, NULL); 1249 } else if (uds_has_link(uds)) { 1250 /* 1251 * This socket is connecting or connected while the other side 1252 * has not been accepted yet. Remove the socket from the 1253 * listening socket's queue, and if it was connected, get rid 1254 * of its peer socket altogether. 1255 */ 1256 assert(uds_is_listening(uds->uds_link)); 1257 1258 uds_del_queue(uds->uds_link, uds); 1259 1260 if (uds_is_connected(uds)) 1261 uds_disconnect(uds, TRUE /*was_linked*/); 1262 } else if (uds_is_connected(uds)) { 1263 /* 1264 * Decouple the peer socket from this socket, and possibly wake 1265 * up any pending operations on it. The socket remains marked 1266 * as connected, but will now be disconnected. 1267 */ 1268 uds_disconnect(uds, FALSE /*was_linked*/); 1269 } 1270 1271 if (uds_is_hashed(uds)) 1272 udshash_del(uds); 1273 1274 return OK; 1275 } 1276 1277 static const struct sockevent_ops uds_ops = { 1278 .sop_pair = uds_pair, 1279 .sop_bind = uds_bind, 1280 .sop_connect = uds_connect, 1281 .sop_listen = uds_listen, 1282 .sop_accept = uds_accept, 1283 .sop_test_accept = uds_test_accept, 1284 .sop_pre_send = uds_pre_send, 1285 .sop_send = uds_send, 1286 .sop_test_send = uds_test_send, 1287 .sop_pre_recv = uds_pre_recv, 1288 .sop_recv = uds_recv, 1289 .sop_test_recv = uds_test_recv, 1290 .sop_setsockopt = uds_setsockopt, 1291 .sop_getsockopt = uds_getsockopt, 1292 .sop_getsockname = uds_getsockname, 1293 .sop_getpeername = uds_getpeername, 1294 .sop_shutdown = uds_shutdown, 1295 .sop_close = uds_close, 1296 .sop_free = uds_free 1297 }; 1298 1299 /* 1300 * Initialize the service. 1301 */ 1302 static int 1303 uds_init(int type __unused, sef_init_info_t * info __unused) 1304 { 1305 unsigned int i; 1306 1307 /* Initialize the list of free sockets. */ 1308 TAILQ_INIT(&uds_freelist); 1309 1310 for (i = 0; i < __arraycount(uds_array); i++) { 1311 uds_array[i].uds_flags = 0; 1312 1313 TAILQ_INSERT_TAIL(&uds_freelist, &uds_array[i], uds_next); 1314 } 1315 1316 /* Initialize the file-to-socket hash table. */ 1317 udshash_init(); 1318 1319 /* Initialize the input/output module. */ 1320 uds_io_init(); 1321 1322 /* Initialize the status module. */ 1323 uds_stat_init(); 1324 1325 /* Initialize the sockevent library. */ 1326 sockevent_init(uds_socket); 1327 1328 uds_in_use = 0; 1329 uds_running = TRUE; 1330 1331 return OK; 1332 } 1333 1334 /* 1335 * Clean up before shutdown. 1336 */ 1337 static void 1338 uds_cleanup(void) 1339 { 1340 1341 /* Tell the status module to clean up. */ 1342 uds_stat_cleanup(); 1343 } 1344 1345 /* 1346 * The service has received a signal. 1347 */ 1348 static void 1349 uds_signal(int signo) 1350 { 1351 1352 /* Only check for the termination signal. Ignore anything else. */ 1353 if (signo != SIGTERM) 1354 return; 1355 1356 /* Exit only once all sockets have been closed. */ 1357 uds_running = FALSE; 1358 1359 if (uds_in_use == 0) 1360 sef_cancel(); 1361 } 1362 1363 /* 1364 * Perform initialization using the System Event Framework (SEF). 1365 */ 1366 static void 1367 uds_startup(void) 1368 { 1369 1370 /* Register initialization callbacks. */ 1371 sef_setcb_init_fresh(uds_init); 1372 1373 /* Register signal callback. */ 1374 sef_setcb_signal_handler(uds_signal); 1375 1376 /* Let SEF perform startup. */ 1377 sef_startup(); 1378 } 1379 1380 /* 1381 * The UNIX Domain Sockets driver. 1382 */ 1383 int 1384 main(void) 1385 { 1386 message m; 1387 int r, ipc_status; 1388 1389 /* Initialize the service. */ 1390 uds_startup(); 1391 1392 /* Loop receiving and processing messages until instructed to stop. */ 1393 while (uds_running || uds_in_use > 0) { 1394 if ((r = sef_receive_status(ANY, &m, &ipc_status)) != OK) { 1395 if (r == EINTR) 1396 continue; /* sef_cancel() was called */ 1397 1398 panic("UDS: sef_receive_status failed: %d", r); 1399 } 1400 1401 /* 1402 * Messages from the MIB service are (ultimately) for the 1403 * status module. Everything else is assumed to be a socket 1404 * request and passed to libsockevent, which will ignore 1405 * anything it does not recognize. 1406 */ 1407 if (m.m_source == MIB_PROC_NR) 1408 rmib_process(&m, ipc_status); 1409 else 1410 sockevent_process(&m, ipc_status); 1411 } 1412 1413 /* Clean up before graceful shutdown. */ 1414 uds_cleanup(); 1415 1416 return EXIT_SUCCESS; 1417 } 1418