Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_usrreq.c
Show First 20 Lines • Show All 695 Lines • ▼ Show 20 Lines | tcp_usr_disconnect(struct socket *so) | ||||
inp = sotoinpcb(so); | inp = sotoinpcb(so); | ||||
KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL")); | KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL")); | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
if (inp->inp_flags & INP_DROPPED) { | if (inp->inp_flags & INP_DROPPED) { | ||||
error = ECONNRESET; | error = ECONNRESET; | ||||
goto out; | goto out; | ||||
} | } | ||||
tp = intotcpcb(inp); | tp = intotcpcb(inp); | ||||
if (tp->t_state == TCPS_TIME_WAIT) | |||||
goto out; | |||||
TCPDEBUG1(); | TCPDEBUG1(); | ||||
tcp_disconnect(tp); | tcp_disconnect(tp); | ||||
out: | out: | ||||
TCPDEBUG2(PRU_DISCONNECT); | TCPDEBUG2(PRU_DISCONNECT); | ||||
TCP_PROBE2(debug__user, tp, PRU_DISCONNECT); | TCP_PROBE2(debug__user, tp, PRU_DISCONNECT); | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
return (error); | return (error); | ||||
▲ Show 20 Lines • Show All 605 Lines • ▼ Show 20 Lines | tcp_usr_close(struct socket *so) | ||||
KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL")); | KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL")); | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
KASSERT(inp->inp_socket != NULL, | KASSERT(inp->inp_socket != NULL, | ||||
("tcp_usr_close: inp_socket == NULL")); | ("tcp_usr_close: inp_socket == NULL")); | ||||
/* | /* | ||||
* If we still have full TCP state, and we're not dropped, initiate | * If we are still connected and we're not dropped, initiate | ||||
* a disconnect. | * a disconnect. | ||||
*/ | */ | ||||
if (!(inp->inp_flags & INP_DROPPED)) { | if (!(inp->inp_flags & INP_DROPPED)) { | ||||
jhb: I suppose actually if we were to check SS_* flags here we might not even the need the… | |||||
glebiusUnsubmitted Not Done Inline ActionsIdeally such check would require socket lock. glebius: Ideally such check would require socket lock. | |||||
jhbAuthorUnsubmitted Done Inline ActionsIf we always hold the INP lock when calling soisdisconnecting() or soisdisconnected() then it's fine to just hold the INP lock to read the flags. jhb: If we always hold the INP lock when calling soisdisconnecting() or soisdisconnected() then it's… | |||||
tp = intotcpcb(inp); | tp = intotcpcb(inp); | ||||
if (tp->t_state != TCPS_TIME_WAIT) { | |||||
tp->t_flags |= TF_CLOSED; | tp->t_flags |= TF_CLOSED; | ||||
TCPDEBUG1(); | TCPDEBUG1(); | ||||
tcp_disconnect(tp); | tcp_disconnect(tp); | ||||
TCPDEBUG2(PRU_CLOSE); | TCPDEBUG2(PRU_CLOSE); | ||||
TCP_PROBE2(debug__user, tp, PRU_CLOSE); | TCP_PROBE2(debug__user, tp, PRU_CLOSE); | ||||
} | |||||
} | } | ||||
if (!(inp->inp_flags & INP_DROPPED)) { | if (!(inp->inp_flags & INP_DROPPED)) { | ||||
soref(so); | soref(so); | ||||
inp->inp_flags |= INP_SOCKREF; | inp->inp_flags |= INP_SOCKREF; | ||||
} | } | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,836 Lines • Show Last 20 Lines |
I suppose actually if we were to check SS_* flags here we might not even the need the INP_DROPPED check as dropped sockets should always be marked SS_DISCONNECTED? That is, we could maybe replace this line with:
and would then not need the TCPS_TIME_WAIT check either.