Skip to content

Commit

Permalink
sctp: Mark the tsn as received after all allocations finish
Browse files Browse the repository at this point in the history
If we don't have the buffer space or memory allocations fail,
the data chunk is dropped, but TSN is still reported as received.
This introduced a data loss that can't be recovered.  We should
only mark TSNs are received after memory allocations finish.
The one exception is the invalid stream identifier, but that's
due to user error and is reported back to the user.

This was noticed by Michael Tuexen.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vlad Yasevich authored and David S. Miller committed Jul 8, 2008
1 parent 6e43829 commit 3888e9e
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 6 deletions.
9 changes: 3 additions & 6 deletions net/sctp/sm_statefuns.c
Original file line number Diff line number Diff line change
Expand Up @@ -5899,12 +5899,6 @@ static int sctp_eat_data(const struct sctp_association *asoc,
return SCTP_IERROR_NO_DATA;
}

/* If definately accepting the DATA chunk, record its TSN, otherwise
* wait for renege processing.
*/
if (SCTP_CMD_CHUNK_ULP == deliver)
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));

chunk->data_accepted = 1;

/* Note: Some chunks may get overcounted (if we drop) or overcounted
Expand All @@ -5924,6 +5918,9 @@ static int sctp_eat_data(const struct sctp_association *asoc,
* and discard the DATA chunk.
*/
if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) {
/* Mark tsn as received even though we drop it */
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));

err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
&data_hdr->stream,
sizeof(data_hdr->stream));
Expand Down
5 changes: 5 additions & 0 deletions net/sctp/ulpevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
if (!skb)
goto fail;

/* Now that all memory allocations for this chunk succeeded, we
* can mark it as received so the tsn_map is updated correctly.
*/
sctp_tsnmap_mark(&asoc->peer.tsn_map, ntohl(chunk->subh.data_hdr->tsn));

/* First calculate the padding, so we don't inadvertently
* pass up the wrong length to the user.
*
Expand Down

0 comments on commit 3888e9e

Please sign in to comment.