* in_pcbdrop() removes an inpcb from hashed lists, releasing its address and * port reservation, and preventing it from being returned by inpcb lookups. * * It is used by TCP to mark an inpcb as unused and avoid future packet * delivery or event notification when a socket remains open but TCP has * closed. This might occur as a result of a shutdown()-initiated TCP close * or a RST on the wi
| 1900 | * in_pcbnotifyall() and in_pcbpurgeif0()? |
| 1901 | */ |
| 1902 | void |
| 1903 | in_pcbdrop(struct inpcb *inp) |
| 1904 | { |
| 1905 | |
| 1906 | INP_WLOCK_ASSERT(inp); |
| 1907 | #ifdef INVARIANTS |
| 1908 | if (inp->inp_socket != NULL && inp->inp_ppcb != NULL) |
| 1909 | MPASS(inp->inp_refcount > 1); |
| 1910 | #endif |
| 1911 | |
| 1912 | /* |
| 1913 | * XXXRW: Possibly we should protect the setting of INP_DROPPED with |
| 1914 | * the hash lock...? |
| 1915 | */ |
| 1916 | inp->inp_flags |= INP_DROPPED; |
| 1917 | if (inp->inp_flags & INP_INHASHLIST) { |
| 1918 | struct inpcbport *phd = inp->inp_phd; |
| 1919 | |
| 1920 | INP_HASH_WLOCK(inp->inp_pcbinfo); |
| 1921 | in_pcbremlbgrouphash(inp); |
| 1922 | CK_LIST_REMOVE(inp, inp_hash); |
| 1923 | CK_LIST_REMOVE(inp, inp_portlist); |
| 1924 | if (CK_LIST_FIRST(&phd->phd_pcblist) == NULL) { |
| 1925 | CK_LIST_REMOVE(phd, phd_hash); |
| 1926 | NET_EPOCH_CALL(inpcbport_free, &phd->phd_epoch_ctx); |
| 1927 | } |
| 1928 | INP_HASH_WUNLOCK(inp->inp_pcbinfo); |
| 1929 | inp->inp_flags &= ~INP_INHASHLIST; |
| 1930 | #ifdef PCBGROUP |
| 1931 | in_pcbgroup_remove(inp); |
| 1932 | #endif |
| 1933 | } |
| 1934 | } |
| 1935 | |
| 1936 | #ifdef INET |
| 1937 | /* |
no test coverage detected