]> err.no Git - linux-2.6/blobdiff - net/sctp/sm_sideeffect.c
[SCTP]: Fix kernel panic while received AUTH chunk while enabled auth
[linux-2.6] / net / sctp / sm_sideeffect.c
index d9fad4f6ffc3f592c7feed6af33b7bb49edb94e1..78d1a8a49bd05bf53f4f58426d6ad4c7b0d498a0 100644 (file)
@@ -453,6 +453,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
         * maximum value discussed in rule C7 above (RTO.max) may be
         * used to provide an upper bound to this doubling operation.
         */
+       transport->last_rto = transport->rto;
        transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
 }
 
@@ -1013,8 +1014,9 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
                break;
 
        case SCTP_DISPOSITION_VIOLATION:
-               printk(KERN_ERR "sctp protocol violation state %d "
-                      "chunkid %d\n", state, subtype.chunk);
+               if (net_ratelimit())
+                       printk(KERN_ERR "sctp protocol violation state %d "
+                              "chunkid %d\n", state, subtype.chunk);
                break;
 
        case SCTP_DISPOSITION_NOT_IMPL:
@@ -1130,6 +1132,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        /* Move the Cumulattive TSN Ack ahead. */
                        sctp_tsnmap_skip(&asoc->peer.tsn_map, cmd->obj.u32);
 
+                       /* purge the fragmentation queue */
+                       sctp_ulpq_reasm_flushtsn(&asoc->ulpq, cmd->obj.u32);
+
                        /* Abort any in progress partial delivery. */
                        sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
                        break;
@@ -1263,6 +1268,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        sctp_ootb_pkt_free(packet);
                        break;
 
+               case SCTP_CMD_T1_RETRAN:
+                       /* Mark a transport for retransmission.  */
+                       sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
+                                       SCTP_RTXR_T1_RTX);
+                       break;
+
                case SCTP_CMD_RETRAN:
                        /* Mark a transport for retransmission.  */
                        sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
@@ -1389,7 +1400,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        list_for_each(pos, &asoc->peer.transport_addr_list) {
                                t = list_entry(pos, struct sctp_transport,
                                               transports);
-                               sctp_retransmit_mark(&asoc->outqueue, t, 0);
+                               sctp_retransmit_mark(&asoc->outqueue, t,
+                                           SCTP_RTXR_T1_RTX);
                        }
 
                        sctp_add_cmd_sf(commands,
@@ -1520,6 +1532,11 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        sctp_cmd_adaptation_ind(commands, asoc);
                        break;
 
+               case SCTP_CMD_ASSOC_SHKEY:
+                       error = sctp_auth_asoc_init_active_key(asoc,
+                                               GFP_ATOMIC);
+                       break;
+
                default:
                        printk(KERN_WARNING "Impossible command: %u, %p\n",
                               cmd->verb, cmd->obj.ptr);