linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / sctp / sm_statefuns.c
index 5b5ae79..4e59a4e 100644 (file)
@@ -93,7 +93,7 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
 static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
 
 static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
-                                          __u16 error, int sk_err,
+                                          __u16 error,
                                           const struct sctp_association *asoc,
                                           struct sctp_transport *transport);
 
@@ -448,7 +448,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
        __u32 init_tag;
        struct sctp_chunk *err_chunk;
        struct sctp_packet *packet;
-       __u16 error;
+       sctp_disposition_t ret;
 
        if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -480,9 +480,11 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
                        goto nomem;
 
                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
-               return sctp_stop_t1_and_abort(commands, SCTP_ERROR_INV_PARAM,
-                                             ECONNREFUSED, asoc,
-                                             chunk->transport);
+               sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+                               SCTP_STATE(SCTP_STATE_CLOSED));
+               SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
+               sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
+               return SCTP_DISPOSITION_DELETE_TCB;
        }
 
        /* Verify the INIT chunk before processing it. */
@@ -509,16 +511,27 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
                                sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
                                                SCTP_PACKET(packet));
                                SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
-                               error = SCTP_ERROR_INV_PARAM;
+                               sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+                                               SCTP_STATE(SCTP_STATE_CLOSED));
+                               sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
+                                               SCTP_NULL());
+                               return SCTP_DISPOSITION_CONSUME;
                        } else {
-                               error = SCTP_ERROR_NO_RESOURCE;
+                               sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+                                               SCTP_STATE(SCTP_STATE_CLOSED));
+                               sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
+                                               SCTP_NULL());
+                               return SCTP_DISPOSITION_NOMEM;
                        }
                } else {
-                       sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
-                       error = SCTP_ERROR_INV_PARAM;
+                       ret = sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
+                                                  commands);
+                       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+                                       SCTP_STATE(SCTP_STATE_CLOSED));
+                       sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
+                                       SCTP_NULL());
+                       return ret;
                }
-               return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED,
-                                               asoc, chunk->transport);
        }
 
        /* Tag the variable length parameters.  Note that we never
@@ -846,7 +859,6 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
        hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t));
        hbinfo.daddr = transport->ipaddr;
        hbinfo.sent_at = jiffies;
-       hbinfo.hb_nonce = transport->hb_nonce;
 
        /* Send a heartbeat to our peer.  */
        paylen = sizeof(sctp_sender_hb_info_t);
@@ -874,8 +886,6 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
        struct sctp_transport *transport = (struct sctp_transport *) arg;
 
        if (asoc->overall_error_count >= asoc->max_retrans) {
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ETIMEDOUT));
                /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -1049,10 +1059,6 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
                return SCTP_DISPOSITION_DISCARD;
        }
 
-       /* Validate the 64-bit random nonce. */
-       if (hbinfo->hb_nonce != link->hb_nonce)
-               return SCTP_DISPOSITION_DISCARD;
-
        max_interval = link->hbinterval + link->rto;
 
        /* Check if the timestamp looks valid.  */
@@ -2126,8 +2132,6 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
        int attempts = asoc->init_err_counter + 1;
 
        if (attempts > asoc->max_init_attempts) {
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ETIMEDOUT));
                sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                                SCTP_U32(SCTP_ERROR_STALE_COOKIE));
                return SCTP_DISPOSITION_DELETE_TCB;
@@ -2264,7 +2268,6 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
        if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
                error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
        /* ASSOC_FAILED will DELETE_TCB. */
        sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error));
        SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -2309,8 +2312,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
        if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
                error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-       return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, asoc,
-                                     chunk->transport);
+       return sctp_stop_t1_and_abort(commands, error, asoc, chunk->transport);
 }
 
 /*
@@ -2322,8 +2324,7 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep
                                        void *arg,
                                        sctp_cmd_seq_t *commands)
 {
-       return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR,
-                                     ENOPROTOOPT, asoc,
+       return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, asoc,
                                      (struct sctp_transport *)arg);
 }
 
@@ -2348,7 +2349,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
  * This is common code called by several sctp_sf_*_abort() functions above.
  */
 static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
-                                          __u16 error, int sk_err,
+                                          __u16 error,
                                           const struct sctp_association *asoc,
                                           struct sctp_transport *transport)
 {
@@ -2358,7 +2359,6 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
        SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
-       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err));
        /* CMD_INIT_FAILED will DELETE_TCB. */
        sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                        SCTP_U32(error));
@@ -3342,8 +3342,6 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
                sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ECONNABORTED));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_ASCONF_ACK));
                SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -3370,8 +3368,6 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
                 * processing the rest of the chunks in the packet.
                 */
                sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ECONNABORTED));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_ASCONF_ACK));
                SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -3724,13 +3720,9 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
        if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ECONNREFUSED));
                sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                                SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
        } else {
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ECONNABORTED));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
                SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
@@ -4042,8 +4034,6 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
         * TCB.  This is a departure from our typical NOMEM handling.
         */
 
-       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                       SCTP_ERROR(ECONNABORTED));
        /* Delete the established association. */
        sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                        SCTP_U32(SCTP_ERROR_USER_ABORT));
@@ -4179,8 +4169,6 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
         * TCB.  This is a departure from our typical NOMEM handling.
         */
 
-       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                       SCTP_ERROR(ECONNREFUSED));
        /* Delete the established association. */
        sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                        SCTP_U32(SCTP_ERROR_USER_ABORT));
@@ -4549,8 +4537,6 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
        struct sctp_transport *transport = arg;
 
        if (asoc->overall_error_count >= asoc->max_retrans) {
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ETIMEDOUT));
                /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -4670,8 +4656,6 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
                SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d"
                                  " max_init_attempts: %d\n",
                                  attempts, asoc->max_init_attempts);
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ETIMEDOUT));
                sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
                return SCTP_DISPOSITION_DELETE_TCB;
@@ -4721,8 +4705,6 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep
 
                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
        } else {
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ETIMEDOUT));
                sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
                return SCTP_DISPOSITION_DELETE_TCB;
@@ -4754,8 +4736,6 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
 
        SCTP_DEBUG_PRINTK("Timer T2 expired.\n");
        if (asoc->overall_error_count >= asoc->max_retrans) {
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ETIMEDOUT));
                /* Note:  CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -4831,8 +4811,6 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
        if (asoc->overall_error_count >= asoc->max_retrans) {
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ETIMEDOUT));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
                SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -4886,8 +4864,6 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
                goto nomem;
 
        sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
-       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                       SCTP_ERROR(ETIMEDOUT));
        sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                        SCTP_U32(SCTP_ERROR_NO_ERROR));
 
@@ -5271,6 +5247,7 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        datalen -= sizeof(sctp_data_chunk_t);
 
        deliver = SCTP_CMD_CHUNK_ULP;
+       chunk->data_accepted = 1;
 
        /* Think about partial delivery. */
        if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
@@ -5334,8 +5311,6 @@ static int sctp_eat_data(const struct sctp_association *asoc,
                 * processing the rest of the chunks in the packet.
                 */
                sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
-                               SCTP_ERROR(ECONNABORTED));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_DATA));
                SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -5349,8 +5324,6 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        if (SCTP_CMD_CHUNK_ULP == deliver)
                sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
 
-       chunk->data_accepted = 1;
-
        /* Note: Some chunks may get overcounted (if we drop) or overcounted
         * if we renege and the chunk arrives again.
         */