]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/sctp/stream.c
sctp: process duplicated strreset asoc request correctly
[karo-tx-linux.git] / net / sctp / stream.c
index c91d97e5d590e1d9ef3eab22a84a877c9561500d..dda53a2939866d5bb7e3233a1ba0a90160ecf488 100644 (file)
@@ -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);
 }