sctp: implement the sender side for SACK-IMMEDIATELY extension
authorWei Yongjun <yjwei@cn.fujitsu.com>
Mon, 23 Nov 2009 20:53:56 +0000 (15:53 -0500)
committerVlad Yasevich <vladislav.yasevich@hp.com>
Mon, 23 Nov 2009 20:53:56 +0000 (15:53 -0500)
This patch implement the sender side for SACK-IMMEDIATELY
extension.

  Section 4.1.  Sender Side Considerations

  Whenever the sender of a DATA chunk can benefit from the
  corresponding SACK chunk being sent back without delay, the sender
  MAY set the I-bit in the DATA chunk header.

  Reasons for setting the I-bit include

  o  The sender is in the SHUTDOWN-PENDING state.

  o  The application requests to set the I-bit of the last DATA chunk
     of a user message when providing the user message to the SCTP
     implementation.

Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
include/net/sctp/user.h
net/sctp/chunk.c
net/sctp/outqueue.c

index be2334a..50b2431 100644 (file)
@@ -206,6 +206,7 @@ enum sctp_sinfo_flags {
        SCTP_UNORDERED = 1,  /* Send/receive message unordered. */
        SCTP_ADDR_OVER = 2,  /* Override the primary destination. */
        SCTP_ABORT=4,        /* Send an ABORT message to the peer. */
+       SCTP_SACK_IMMEDIATELY = 8,      /* SACK should be sent without delay */
        SCTP_EOF=MSG_FIN,    /* Initiate graceful shutdown process. */  
 };
 
index acf7c4d..8e43200 100644 (file)
@@ -263,9 +263,18 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                if (0 == i)
                        frag |= SCTP_DATA_FIRST_FRAG;
 
-               if ((i == (whole - 1)) && !over)
+               if ((i == (whole - 1)) && !over) {
                        frag |= SCTP_DATA_LAST_FRAG;
 
+                       /* The application requests to set the I-bit of the
+                        * last DATA chunk of a user message when providing
+                        * the user message to the SCTP implementation.
+                        */
+                       if ((sinfo->sinfo_flags & SCTP_EOF) ||
+                           (sinfo->sinfo_flags & SCTP_SACK_IMMEDIATELY))
+                               frag |= SCTP_DATA_SACK_IMM;
+               }
+
                chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
 
                if (!chunk)
@@ -297,6 +306,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                else
                        frag = SCTP_DATA_LAST_FRAG;
 
+               if ((sinfo->sinfo_flags & SCTP_EOF) ||
+                   (sinfo->sinfo_flags & SCTP_SACK_IMMEDIATELY))
+                       frag |= SCTP_DATA_SACK_IMM;
+
                chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
 
                if (!chunk)
index c9f20e2..5732661 100644 (file)
@@ -1011,6 +1011,13 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
                                break;
 
                        case SCTP_XMIT_OK:
+                               /* The sender is in the SHUTDOWN-PENDING state,
+                                * The sender MAY set the I-bit in the DATA
+                                * chunk header.
+                                */
+                               if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING)
+                                       chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM;
+
                                break;
 
                        default: