Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
[powerpc.git] / net / sctp / associola.c
index ee4b212..03158e3 100644 (file)
@@ -415,6 +415,9 @@ void sctp_association_free(struct sctp_association *asoc)
 
        /* Free peer's cached cookie. */
        kfree(asoc->peer.cookie);
+       kfree(asoc->peer.peer_random);
+       kfree(asoc->peer.peer_chunks);
+       kfree(asoc->peer.peer_hmacs);
 
        /* Release the transport structures. */
        list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
@@ -1008,6 +1011,16 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
                state = asoc->state;
                subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
 
+               /* SCTP-AUTH, Section 6.3:
+                *    The receiver has a list of chunk types which it expects
+                *    to be received only after an AUTH-chunk.  This list has
+                *    been sent to the peer during the association setup.  It
+                *    MUST silently discard these chunks if they are not placed
+                *    after an AUTH chunk in the packet.
+                */
+               if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
+                       continue;
+
                /* Remember where the last DATA chunk came from so we
                 * know where to send the SACK.
                 */
@@ -1145,7 +1158,23 @@ void sctp_assoc_update(struct sctp_association *asoc,
                }
        }
 
-       /* SCTP-AUTH: XXX something needs to be done here*/
+       /* SCTP-AUTH: Save the peer parameters from the new assocaitions
+        * and also move the association shared keys over
+        */
+       kfree(asoc->peer.peer_random);
+       asoc->peer.peer_random = new->peer.peer_random;
+       new->peer.peer_random = NULL;
+
+       kfree(asoc->peer.peer_chunks);
+       asoc->peer.peer_chunks = new->peer.peer_chunks;
+       new->peer.peer_chunks = NULL;
+
+       kfree(asoc->peer.peer_hmacs);
+       asoc->peer.peer_hmacs = new->peer.peer_hmacs;
+       new->peer.peer_hmacs = NULL;
+
+       sctp_auth_key_put(asoc->asoc_shared_key);
+       sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC);
 }
 
 /* Update the retran path for sending a retransmitted packet.