| 1496 | } |
| 1497 | |
| 1498 | static int |
| 1499 | unp_connectat(int fd, struct socket *so, struct sockaddr *nam, |
| 1500 | struct thread *td) |
| 1501 | { |
| 1502 | struct mtx *vplock; |
| 1503 | struct sockaddr_un *soun; |
| 1504 | struct vnode *vp; |
| 1505 | struct socket *so2; |
| 1506 | struct unpcb *unp, *unp2, *unp3; |
| 1507 | struct nameidata nd; |
| 1508 | char buf[SOCK_MAXADDRLEN]; |
| 1509 | struct sockaddr *sa; |
| 1510 | cap_rights_t rights; |
| 1511 | int error, len; |
| 1512 | bool connreq; |
| 1513 | |
| 1514 | if (nam->sa_family != AF_UNIX) |
| 1515 | return (EAFNOSUPPORT); |
| 1516 | if (nam->sa_len > sizeof(struct sockaddr_un)) |
| 1517 | return (EINVAL); |
| 1518 | len = nam->sa_len - offsetof(struct sockaddr_un, sun_path); |
| 1519 | if (len <= 0) |
| 1520 | return (EINVAL); |
| 1521 | soun = (struct sockaddr_un *)nam; |
| 1522 | bcopy(soun->sun_path, buf, len); |
| 1523 | buf[len] = 0; |
| 1524 | |
| 1525 | unp = sotounpcb(so); |
| 1526 | UNP_PCB_LOCK(unp); |
| 1527 | for (;;) { |
| 1528 | /* |
| 1529 | * Wait for connection state to stabilize. If a connection |
| 1530 | * already exists, give up. For datagram sockets, which permit |
| 1531 | * multiple consecutive connect(2) calls, upper layers are |
| 1532 | * responsible for disconnecting in advance of a subsequent |
| 1533 | * connect(2), but this is not synchronized with PCB connection |
| 1534 | * state. |
| 1535 | * |
| 1536 | * Also make sure that no threads are currently attempting to |
| 1537 | * lock the peer socket, to ensure that unp_conn cannot |
| 1538 | * transition between two valid sockets while locks are dropped. |
| 1539 | */ |
| 1540 | if (unp->unp_conn != NULL) { |
| 1541 | UNP_PCB_UNLOCK(unp); |
| 1542 | return (EISCONN); |
| 1543 | } |
| 1544 | if ((unp->unp_flags & UNP_CONNECTING) != 0) { |
| 1545 | UNP_PCB_UNLOCK(unp); |
| 1546 | return (EALREADY); |
| 1547 | } |
| 1548 | if (unp->unp_pairbusy > 0) { |
| 1549 | unp->unp_flags |= UNP_WAITING; |
| 1550 | mtx_sleep(unp, UNP_PCB_LOCKPTR(unp), 0, "unpeer", 0); |
| 1551 | continue; |
| 1552 | } |
| 1553 | break; |
| 1554 | } |
| 1555 | unp->unp_flags |= UNP_CONNECTING; |
no test coverage detected