sctp: cleanup
In particular, don't use a socket level flag, use the inp level one. After adding appropriate locking, this will close a race condition. MFC after: 1 week
This commit is contained in:
parent
f0c8e8118d
commit
e40d16ad6e
|
@ -4054,14 +4054,14 @@ void
|
|||
sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
uint32_t error, void *data, int so_locked)
|
||||
{
|
||||
if ((stcb == NULL) ||
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
|
||||
/* If the socket is gone we are out of here */
|
||||
return;
|
||||
}
|
||||
if (stcb->sctp_socket->so_rcv.sb_state & SBS_CANTRCVMORE) {
|
||||
struct sctp_inpcb *inp;
|
||||
struct sctp_nets *net;
|
||||
|
||||
KASSERT(stcb != NULL, ("stcb == NULL"));
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
inp = stcb->sctp_ep;
|
||||
if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
|
||||
return;
|
||||
}
|
||||
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
|
@ -4073,6 +4073,12 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
|||
return;
|
||||
}
|
||||
}
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (notification) {
|
||||
case SCTP_NOTIFY_ASSOC_UP:
|
||||
if (stcb->asoc.assoc_up_sent == 0) {
|
||||
|
@ -4091,32 +4097,20 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
|||
sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, false, false, so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_INTERFACE_DOWN:
|
||||
{
|
||||
struct sctp_nets *net;
|
||||
|
||||
net = (struct sctp_nets *)data;
|
||||
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
|
||||
(struct sockaddr *)&net->ro._l_addr, error, so_locked);
|
||||
break;
|
||||
}
|
||||
net = (struct sctp_nets *)data;
|
||||
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
|
||||
&net->ro._l_addr.sa, error, so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_INTERFACE_UP:
|
||||
{
|
||||
struct sctp_nets *net;
|
||||
|
||||
net = (struct sctp_nets *)data;
|
||||
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
|
||||
(struct sockaddr *)&net->ro._l_addr, error, so_locked);
|
||||
break;
|
||||
}
|
||||
net = (struct sctp_nets *)data;
|
||||
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
|
||||
&net->ro._l_addr.sa, error, so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_INTERFACE_CONFIRMED:
|
||||
{
|
||||
struct sctp_nets *net;
|
||||
|
||||
net = (struct sctp_nets *)data;
|
||||
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
|
||||
(struct sockaddr *)&net->ro._l_addr, error, so_locked);
|
||||
break;
|
||||
}
|
||||
net = (struct sctp_nets *)data;
|
||||
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
|
||||
&net->ro._l_addr.sa, error, so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_SPECIAL_SP_FAIL:
|
||||
sctp_notify_send_failed2(stcb, error,
|
||||
(struct sctp_stream_queue_pending *)data, so_locked);
|
||||
|
@ -4227,7 +4221,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
|||
SCTPDBG(SCTP_DEBUG_UTIL1, "%s: unknown notification %xh (%u)\n",
|
||||
__func__, notification, notification);
|
||||
break;
|
||||
} /* end switch */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue
Block a user