Skip to content

Commit

Permalink
Improve handling of SHUTDOWN and SHUTDOWN ACK chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
tuexen committed Aug 23, 2023
1 parent a3a535e commit f4d3996
Showing 1 changed file with 41 additions and 10 deletions.
51 changes: 41 additions & 10 deletions usrsctplib/netinet/sctp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,38 @@ sctp_start_net_timers(struct sctp_tcb *stcb)
}
}

static void
sctp_check_data_from_peer(struct sctp_tcb *stcb, int *abort_flag)
{
char msg[SCTP_DIAG_INFO_LEN];
struct sctp_association *asoc;
struct mbuf *op_err;
unsigned int i;

*abort_flag = 0;
asoc = &stcb->asoc;
if (SCTP_TSN_GT(asoc->highest_tsn_inside_map, asoc->cumulative_tsn) ||
SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn)) {
SCTP_SNPRINTF(msg, sizeof(msg), "Missing TSN");
*abort_flag = 1;
}
if (!*abort_flag) {
for (i = 0; i < asoc->streamincnt; i++) {
if (!TAILQ_EMPTY(&asoc->strmin[i].inqueue) ||
!TAILQ_EMPTY(&asoc->strmin[i].uno_inqueue)) {
SCTP_SNPRINTF(msg, sizeof(msg), "Missing user data");
*abort_flag = 1;
break;
}
}
}
if (*abort_flag) {
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INPUT + SCTP_LOC_9;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
}
}

static void
sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
struct sctp_tcb *stcb, struct sctp_nets *net, int *abort_flag)
Expand All @@ -931,11 +963,10 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
if (*abort_flag) {
return;
}
/*
* FIXME MT: Handle the case where there are still incomplete received
* user messages or known missing user messages from the peer.
* One way to handle this is to abort the associations in this case.
*/
sctp_check_data_from_peer(stcb, abort_flag);
if (*abort_flag) {
return;
}
if (stcb->sctp_socket) {
if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
(SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT) &&
Expand Down Expand Up @@ -989,6 +1020,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
struct sctp_tcb *stcb,
struct sctp_nets *net)
{
int abort_flag;
#if defined(__APPLE__) && !defined(__Userspace__)
struct socket *so;

Expand All @@ -1014,11 +1046,10 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
SCTP_TCB_UNLOCK(stcb);
return;
}
/*
* FIXME MT: Handle the case where there are still incomplete received
* user messages or known missing user messages from the peer.
* One way to handle this is to abort the associations in this case.
*/
sctp_check_data_from_peer(stcb, &abort_flag);
if (abort_flag) {
return;
}
#ifdef INVARIANTS
if (!TAILQ_EMPTY(&stcb->asoc.send_queue) ||
!TAILQ_EMPTY(&stcb->asoc.sent_queue) ||
Expand Down

0 comments on commit f4d3996

Please sign in to comment.