aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2006-02-02 16:57:31 -0800
committerDavid S. Miller <davem@davemloft.net>2006-02-02 16:57:31 -0800
commit27852c26baab8b95fc9a2b3e8a18770ecd553f10 (patch)
treef07d3c696598ce6e7181ee30344bce899971e062
parent4641e7a334adf6856300a98e7296dfc886c446af (diff)
[SCTP]: Fix 'fast retransmit' to send a TSN only once.
SCTP used to "fast retransmit" a TSN every time we hit the number of missing reports for the TSN. However the Implementers Guide specifies that we should only "fast retransmit" a given TSN once. Subsequent retransmits should be timeouts only. Also change the number of missing reports to 3 as per the latest IG(similar to TCP). Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/structs.h2
-rw-r--r--net/sctp/output.c2
-rw-r--r--net/sctp/outqueue.c12
3 files changed, 9 insertions, 7 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 8c522ae031b..072f407848a 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -700,7 +700,7 @@ struct sctp_chunk {
__u8 ecn_ce_done; /* Have we processed the ECN CE bit? */
__u8 pdiscard; /* Discard the whole packet now? */
__u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */
- __u8 fast_retransmit; /* Is this chunk fast retransmitted? */
+ __s8 fast_retransmit; /* Is this chunk fast retransmitted? */
__u8 tsn_missing_report; /* Data chunk missing counter. */
};
diff --git a/net/sctp/output.c b/net/sctp/output.c
index a40991ef72c..437cba7260a 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
* When a Fast Retransmit is being performed the sender SHOULD
* ignore the value of cwnd and SHOULD NOT delay retransmission.
*/
- if (!chunk->fast_retransmit)
+ if (chunk->fast_retransmit <= 0)
if (transport->flight_size >= transport->cwnd) {
retval = SCTP_XMIT_RWND_FULL;
goto finish;
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index efb72faba20..f148f9576dd 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
* chunks that are not yet acked should be added to the
* retransmit queue.
*/
- if ((fast_retransmit && chunk->fast_retransmit) ||
+ if ((fast_retransmit && (chunk->fast_retransmit > 0)) ||
(!fast_retransmit && !chunk->tsn_gap_acked)) {
/* RFC 2960 6.2.1 Processing a Received SACK
*
@@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
/* Mark the chunk as ineligible for fast retransmit
* after it is retransmitted.
*/
- chunk->fast_retransmit = 0;
+ if (chunk->fast_retransmit > 0)
+ chunk->fast_retransmit = -1;
*start_timer = 1;
q->empty = 0;
@@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
list_for_each(lchunk1, lqueue) {
chunk1 = list_entry(lchunk1, struct sctp_chunk,
transmitted_list);
- chunk1->fast_retransmit = 0;
+ if (chunk1->fast_retransmit > 0)
+ chunk1->fast_retransmit = -1;
}
}
}
@@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q,
/*
* M4) If any DATA chunk is found to have a
* 'TSN.Missing.Report'
- * value larger than or equal to 4, mark that chunk for
+ * value larger than or equal to 3, mark that chunk for
* retransmission and start the fast retransmit procedure.
*/
- if (chunk->tsn_missing_report >= 4) {
+ if (chunk->tsn_missing_report >= 3) {
chunk->fast_retransmit = 1;
do_fast_retransmit = 1;
}