Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ab3e5e7b65dde661f5eb86b445496c5967283333
Commit:     ab3e5e7b65dde661f5eb86b445496c5967283333
Parent:     ea2dfb3733d53ac98b17756435d1f99e25490357
Author:     Vlad Yasevich <[EMAIL PROTECTED]>
AuthorDate: Thu Aug 2 16:51:42 2007 -0400
Committer:  Vlad Yasevich <[EMAIL PROTECTED]>
CommitDate: Wed Aug 29 13:34:34 2007 -0400

    SCTP: Assign stream sequence numbers to the entire message
    
    Currently we only assign the sequence number to a packet that
    we are about to transmit.  This however breaks the Partial
    Reliability extensions, because it's possible for us to
    never transmit a packet, i.e. it expires before we get to send
    it.  In such cases, if the message contained multiple SCTP
    fragments, and we did manage to send the first part of the
    message, the Stream sequence numbers would get into invalid
    state and cause receiver to stall.
    
    Signed-off-by: Vlad Yasevich <[EMAIL PROTECTED]>
---
 net/sctp/sm_make_chunk.c |   35 +++++++++++++++++++++++------------
 1 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 51c4d7f..2b1129a 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1174,25 +1174,36 @@ out:
  */
 void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 {
+       struct sctp_datamsg *msg;
+       struct sctp_chunk *lchunk;
+       struct sctp_stream *stream;
        __u16 ssn;
        __u16 sid;
 
        if (chunk->has_ssn)
                return;
 
-       /* This is the last possible instant to assign a SSN. */
-       if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
-               ssn = 0;
-       } else {
-               sid = ntohs(chunk->subh.data_hdr->stream);
-               if (chunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
-                       ssn = sctp_ssn_next(&chunk->asoc->ssnmap->out, sid);
-               else
-                       ssn = sctp_ssn_peek(&chunk->asoc->ssnmap->out, sid);
-       }
+       /* All fragments will be on the same stream */
+       sid = ntohs(chunk->subh.data_hdr->stream);
+       stream = &chunk->asoc->ssnmap->out;
 
-       chunk->subh.data_hdr->ssn = htons(ssn);
-       chunk->has_ssn = 1;
+       /* Now assign the sequence number to the entire message.
+        * All fragments must have the same stream sequence number.
+        */
+       msg = chunk->msg;
+       list_for_each_entry(lchunk, &msg->chunks, frag_list) {
+               if (lchunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
+                       ssn = 0;
+               } else {
+                       if (lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
+                               ssn = sctp_ssn_next(stream, sid);
+                       else
+                               ssn = sctp_ssn_peek(stream, sid);
+               }
+
+               lchunk->subh.data_hdr->ssn = htons(ssn);
+               lchunk->has_ssn = 1;
+       }
 }
 
 /* Helper function to assign a TSN if needed.  This assumes that both
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to