]> err.no Git - linux-2.6/blobdiff - net/sctp/outqueue.c
[NetLabel]: correct improper handling of non-NetLabel peer contexts
[linux-2.6] / net / sctp / outqueue.c
index f148f9576dd226035b3b6c34d439d7558818ce4a..37074a39ecbbfb68939c9cc6b0679e21eba71bb1 100644 (file)
@@ -467,6 +467,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
 
        switch(reason) {
        case SCTP_RTXR_T3_RTX:
+               SCTP_INC_STATS(SCTP_MIB_T3_RETRANSMITS);
                sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
                /* Update the retran path if the T3-rtx timer has expired for
                 * the current retran path.
@@ -475,12 +476,15 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
                        sctp_assoc_update_retran_path(transport->asoc);
                break;
        case SCTP_RTXR_FAST_RTX:
+               SCTP_INC_STATS(SCTP_MIB_FAST_RETRANSMITS);
                sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
                fast_retransmit = 1;
                break;
        case SCTP_RTXR_PMTUD:
-       default:
+               SCTP_INC_STATS(SCTP_MIB_PMTUD_RETRANSMITS);
                break;
+       default:
+               BUG();
        }
 
        sctp_retransmit_mark(q, transport, fast_retransmit);
@@ -691,7 +695,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.
@@ -848,7 +853,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.  */
@@ -1262,6 +1268,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);
@@ -1463,7 +1470,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,