diff options
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r-- | net/sctp/sm_statefuns.c | 83 |
1 files changed, 49 insertions, 34 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index a297283154d5..49b847b00f99 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -4008,31 +4008,32 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep, | |||
4008 | auth_hdr = (struct sctp_authhdr *)chunk->skb->data; | 4008 | auth_hdr = (struct sctp_authhdr *)chunk->skb->data; |
4009 | error = sctp_sf_authenticate(ep, asoc, type, chunk); | 4009 | error = sctp_sf_authenticate(ep, asoc, type, chunk); |
4010 | switch (error) { | 4010 | switch (error) { |
4011 | case SCTP_IERROR_AUTH_BAD_HMAC: | 4011 | case SCTP_IERROR_AUTH_BAD_HMAC: |
4012 | /* Generate the ERROR chunk and discard the rest | 4012 | /* Generate the ERROR chunk and discard the rest |
4013 | * of the packet | 4013 | * of the packet |
4014 | */ | 4014 | */ |
4015 | err_chunk = sctp_make_op_error(asoc, chunk, | 4015 | err_chunk = sctp_make_op_error(asoc, chunk, |
4016 | SCTP_ERROR_UNSUP_HMAC, | 4016 | SCTP_ERROR_UNSUP_HMAC, |
4017 | &auth_hdr->hmac_id, | 4017 | &auth_hdr->hmac_id, |
4018 | sizeof(__u16), 0); | 4018 | sizeof(__u16), 0); |
4019 | if (err_chunk) { | 4019 | if (err_chunk) { |
4020 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 4020 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
4021 | SCTP_CHUNK(err_chunk)); | 4021 | SCTP_CHUNK(err_chunk)); |
4022 | } | 4022 | } |
4023 | /* Fall Through */ | 4023 | /* Fall Through */ |
4024 | case SCTP_IERROR_AUTH_BAD_KEYID: | 4024 | case SCTP_IERROR_AUTH_BAD_KEYID: |
4025 | case SCTP_IERROR_BAD_SIG: | 4025 | case SCTP_IERROR_BAD_SIG: |
4026 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 4026 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
4027 | break; | 4027 | |
4028 | case SCTP_IERROR_PROTO_VIOLATION: | 4028 | case SCTP_IERROR_PROTO_VIOLATION: |
4029 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | 4029 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, |
4030 | commands); | 4030 | commands); |
4031 | break; | 4031 | |
4032 | case SCTP_IERROR_NOMEM: | 4032 | case SCTP_IERROR_NOMEM: |
4033 | return SCTP_DISPOSITION_NOMEM; | 4033 | return SCTP_DISPOSITION_NOMEM; |
4034 | default: | 4034 | |
4035 | break; | 4035 | default: /* Prevent gcc warnings */ |
4036 | break; | ||
4036 | } | 4037 | } |
4037 | 4038 | ||
4038 | if (asoc->active_key_id != ntohs(auth_hdr->shkey_id)) { | 4039 | if (asoc->active_key_id != ntohs(auth_hdr->shkey_id)) { |
@@ -5154,7 +5155,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( | |||
5154 | * The sender of the SHUTDOWN MAY also start an overall guard timer | 5155 | * The sender of the SHUTDOWN MAY also start an overall guard timer |
5155 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. | 5156 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. |
5156 | */ | 5157 | */ |
5157 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 5158 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
5158 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 5159 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
5159 | 5160 | ||
5160 | if (asoc->autoclose) | 5161 | if (asoc->autoclose) |
@@ -5299,14 +5300,28 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep, | |||
5299 | SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS); | 5300 | SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS); |
5300 | 5301 | ||
5301 | if (asoc->overall_error_count >= asoc->max_retrans) { | 5302 | if (asoc->overall_error_count >= asoc->max_retrans) { |
5302 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | 5303 | if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) { |
5303 | SCTP_ERROR(ETIMEDOUT)); | 5304 | /* |
5304 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | 5305 | * We are here likely because the receiver had its rwnd |
5305 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 5306 | * closed for a while and we have not been able to |
5306 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); | 5307 | * transmit the locally queued data within the maximum |
5307 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 5308 | * retransmission attempts limit. Start the T5 |
5308 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | 5309 | * shutdown guard timer to give the receiver one last |
5309 | return SCTP_DISPOSITION_DELETE_TCB; | 5310 | * chance and some additional time to recover before |
5311 | * aborting. | ||
5312 | */ | ||
5313 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START_ONCE, | ||
5314 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | ||
5315 | } else { | ||
5316 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
5317 | SCTP_ERROR(ETIMEDOUT)); | ||
5318 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | ||
5319 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | ||
5320 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); | ||
5321 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | ||
5322 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | ||
5323 | return SCTP_DISPOSITION_DELETE_TCB; | ||
5324 | } | ||
5310 | } | 5325 | } |
5311 | 5326 | ||
5312 | /* E1) For the destination address for which the timer | 5327 | /* E1) For the destination address for which the timer |