summaryrefslogtreecommitdiffstats
path: root/net/sctp/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/stream.c')
-rw-r--r--net/sctp/stream.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index c91d97e5d590..dda53a293986 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -529,12 +529,21 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
__u16 i;
request_seq = ntohl(tsnreq->request_seq);
- if (request_seq > asoc->strreset_inseq) {
+ if (TSN_lt(asoc->strreset_inseq, request_seq) ||
+ TSN_lt(request_seq, asoc->strreset_inseq - 2)) {
result = SCTP_STRRESET_ERR_BAD_SEQNO;
- goto out;
- } else if (request_seq == asoc->strreset_inseq) {
- asoc->strreset_inseq++;
+ goto err;
+ } else if (TSN_lt(request_seq, asoc->strreset_inseq)) {
+ i = asoc->strreset_inseq - request_seq - 1;
+ result = asoc->strreset_result[i];
+ if (result == SCTP_STRRESET_PERFORMED) {
+ next_tsn = asoc->next_tsn;
+ init_tsn =
+ sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1;
+ }
+ goto err;
}
+ asoc->strreset_inseq++;
if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ))
goto out;
@@ -591,6 +600,8 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
next_tsn, GFP_ATOMIC);
out:
+ sctp_update_strreset_result(asoc, result);
+err:
return sctp_make_strreset_tsnresp(asoc, result, request_seq,
next_tsn, init_tsn);
}