| 1726 | } |
| 1727 | |
| 1728 | static void |
| 1729 | unp_disconnect(struct unpcb *unp, struct unpcb *unp2) |
| 1730 | { |
| 1731 | struct socket *so, *so2; |
| 1732 | #ifdef INVARIANTS |
| 1733 | struct unpcb *unptmp; |
| 1734 | #endif |
| 1735 | |
| 1736 | UNP_PCB_LOCK_ASSERT(unp); |
| 1737 | UNP_PCB_LOCK_ASSERT(unp2); |
| 1738 | KASSERT(unp->unp_conn == unp2, |
| 1739 | ("%s: unpcb %p is not connected to %p", __func__, unp, unp2)); |
| 1740 | |
| 1741 | unp->unp_conn = NULL; |
| 1742 | so = unp->unp_socket; |
| 1743 | so2 = unp2->unp_socket; |
| 1744 | switch (unp->unp_socket->so_type) { |
| 1745 | case SOCK_DGRAM: |
| 1746 | UNP_REF_LIST_LOCK(); |
| 1747 | #ifdef INVARIANTS |
| 1748 | LIST_FOREACH(unptmp, &unp2->unp_refs, unp_reflink) { |
| 1749 | if (unptmp == unp) |
| 1750 | break; |
| 1751 | } |
| 1752 | KASSERT(unptmp != NULL, |
| 1753 | ("%s: %p not found in reflist of %p", __func__, unp, unp2)); |
| 1754 | #endif |
| 1755 | LIST_REMOVE(unp, unp_reflink); |
| 1756 | UNP_REF_LIST_UNLOCK(); |
| 1757 | if (so) { |
| 1758 | SOCK_LOCK(so); |
| 1759 | so->so_state &= ~SS_ISCONNECTED; |
| 1760 | SOCK_UNLOCK(so); |
| 1761 | } |
| 1762 | break; |
| 1763 | |
| 1764 | case SOCK_STREAM: |
| 1765 | case SOCK_SEQPACKET: |
| 1766 | if (so) |
| 1767 | soisdisconnected(so); |
| 1768 | MPASS(unp2->unp_conn == unp); |
| 1769 | unp2->unp_conn = NULL; |
| 1770 | if (so2) |
| 1771 | soisdisconnected(so2); |
| 1772 | break; |
| 1773 | } |
| 1774 | |
| 1775 | if (unp == unp2) { |
| 1776 | unp_pcb_rele_notlast(unp); |
| 1777 | if (!unp_pcb_rele(unp)) |
| 1778 | UNP_PCB_UNLOCK(unp); |
| 1779 | } else { |
| 1780 | if (!unp_pcb_rele(unp)) |
| 1781 | UNP_PCB_UNLOCK(unp); |
| 1782 | if (!unp_pcb_rele(unp2)) |
| 1783 | UNP_PCB_UNLOCK(unp2); |
| 1784 | } |
| 1785 | } |
no test coverage detected