Merge gregkh@master.kernel.org:/home/rmk/linux-2.6-arm
[deliverable/linux.git] / net / sctp / outqueue.c
index efb72faba20cd50aec065d4fe498c85ecae8d4ae..30b710c54e6492aeb6733973790483472fed2076 100644 (file)
@@ -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;
                        }
                }
        }
@@ -689,7 +691,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 
                if (!new_transport) {
                        new_transport = asoc->peer.active_path;
-               } else if (new_transport->state == SCTP_INACTIVE) {
+               } else if ((new_transport->state == SCTP_INACTIVE) ||
+                          (new_transport->state == SCTP_UNCONFIRMED)) {
                        /* If the chunk is Heartbeat or Heartbeat Ack,
                         * send it to chunk->transport, even if it's
                         * inactive.
@@ -846,7 +849,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
                         */
                        new_transport = chunk->transport;
                        if (!new_transport ||
-                           new_transport->state == SCTP_INACTIVE)
+                           ((new_transport->state == SCTP_INACTIVE) ||
+                            (new_transport->state == SCTP_UNCONFIRMED)))
                                new_transport = asoc->peer.active_path;
 
                        /* Change packets if necessary.  */
@@ -1260,6 +1264,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
                                if (!tchunk->tsn_gap_acked &&
                                    !tchunk->resent &&
                                    tchunk->rtt_in_progress) {
+                                       tchunk->rtt_in_progress = 0;
                                        rtt = jiffies - tchunk->sent_at;
                                        sctp_transport_update_rto(transport,
                                                                  rtt);
@@ -1461,7 +1466,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
                        /* Mark the destination transport address as
                         * active if it is not so marked.
                         */
-                       if (transport->state == SCTP_INACTIVE) {
+                       if ((transport->state == SCTP_INACTIVE) ||
+                           (transport->state == SCTP_UNCONFIRMED)) {
                                sctp_assoc_control_transport(
                                        transport->asoc,
                                        transport,
@@ -1562,11 +1568,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;
                }
This page took 0.150167 seconds and 5 git commands to generate.