diff options
-rw-r--r-- | include/net/sctp/command.h | 1 | ||||
-rw-r--r-- | net/sctp/input.c | 4 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 16 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 75 | ||||
-rw-r--r-- | net/sctp/socket.c | 1 |
5 files changed, 64 insertions, 33 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 34a1a09e5aef..807d6f1ef4b5 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
@@ -99,6 +99,7 @@ typedef enum { | |||
99 | SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */ | 99 | SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */ |
100 | SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */ | 100 | SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */ |
101 | SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */ | 101 | SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */ |
102 | SCTP_CMD_SET_SK_ERR, /* Set sk_err */ | ||
102 | SCTP_CMD_LAST | 103 | SCTP_CMD_LAST |
103 | } sctp_verb_t; | 104 | } sctp_verb_t; |
104 | 105 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index d117ebc75cf8..7523f4df2da6 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -412,7 +412,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
412 | union sctp_addr daddr; | 412 | union sctp_addr daddr; |
413 | struct sctp_af *af; | 413 | struct sctp_af *af; |
414 | struct sock *sk = NULL; | 414 | struct sock *sk = NULL; |
415 | struct sctp_association *asoc = NULL; | 415 | struct sctp_association *asoc; |
416 | struct sctp_transport *transport = NULL; | 416 | struct sctp_transport *transport = NULL; |
417 | 417 | ||
418 | *app = NULL; *tpp = NULL; | 418 | *app = NULL; *tpp = NULL; |
@@ -490,7 +490,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
490 | int type = skb->h.icmph->type; | 490 | int type = skb->h.icmph->type; |
491 | int code = skb->h.icmph->code; | 491 | int code = skb->h.icmph->code; |
492 | struct sock *sk; | 492 | struct sock *sk; |
493 | struct sctp_association *asoc; | 493 | struct sctp_association *asoc = NULL; |
494 | struct sctp_transport *transport; | 494 | struct sctp_transport *transport; |
495 | struct inet_sock *inet; | 495 | struct inet_sock *inet; |
496 | char *saveip, *savesctp; | 496 | char *saveip, *savesctp; |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 8d1dc24bab4c..c5beb2ad7ef7 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -498,10 +498,6 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands, | |||
498 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 498 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, |
499 | SCTP_STATE(SCTP_STATE_CLOSED)); | 499 | SCTP_STATE(SCTP_STATE_CLOSED)); |
500 | 500 | ||
501 | /* Set sk_err to ECONNRESET on a 1-1 style socket. */ | ||
502 | if (!sctp_style(asoc->base.sk, UDP)) | ||
503 | asoc->base.sk->sk_err = ECONNRESET; | ||
504 | |||
505 | /* SEND_FAILED sent later when cleaning up the association. */ | 501 | /* SEND_FAILED sent later when cleaning up the association. */ |
506 | asoc->outqueue.error = error; | 502 | asoc->outqueue.error = error; |
507 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); | 503 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); |
@@ -838,6 +834,15 @@ static void sctp_cmd_del_non_primary(struct sctp_association *asoc) | |||
838 | return; | 834 | return; |
839 | } | 835 | } |
840 | 836 | ||
837 | /* Helper function to set sk_err on a 1-1 style socket. */ | ||
838 | static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error) | ||
839 | { | ||
840 | struct sock *sk = asoc->base.sk; | ||
841 | |||
842 | if (!sctp_style(sk, UDP)) | ||
843 | sk->sk_err = error; | ||
844 | } | ||
845 | |||
841 | /* These three macros allow us to pull the debugging code out of the | 846 | /* These three macros allow us to pull the debugging code out of the |
842 | * main flow of sctp_do_sm() to keep attention focused on the real | 847 | * main flow of sctp_do_sm() to keep attention focused on the real |
843 | * functionality there. | 848 | * functionality there. |
@@ -1458,6 +1463,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1458 | local_cork = 0; | 1463 | local_cork = 0; |
1459 | asoc->peer.retran_path = t; | 1464 | asoc->peer.retran_path = t; |
1460 | break; | 1465 | break; |
1466 | case SCTP_CMD_SET_SK_ERR: | ||
1467 | sctp_cmd_set_sk_err(asoc, cmd->obj.error); | ||
1468 | break; | ||
1461 | default: | 1469 | default: |
1462 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1470 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
1463 | cmd->verb, cmd->obj.ptr); | 1471 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 8cdba51ec076..174f7a7c6cd1 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -93,7 +93,7 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, | |||
93 | static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); | 93 | static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); |
94 | 94 | ||
95 | static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | 95 | static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, |
96 | __u16 error, | 96 | __u16 error, int sk_err, |
97 | const struct sctp_association *asoc, | 97 | const struct sctp_association *asoc, |
98 | struct sctp_transport *transport); | 98 | struct sctp_transport *transport); |
99 | 99 | ||
@@ -448,7 +448,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, | |||
448 | __u32 init_tag; | 448 | __u32 init_tag; |
449 | struct sctp_chunk *err_chunk; | 449 | struct sctp_chunk *err_chunk; |
450 | struct sctp_packet *packet; | 450 | struct sctp_packet *packet; |
451 | sctp_disposition_t ret; | 451 | __u16 error; |
452 | 452 | ||
453 | if (!sctp_vtag_verify(chunk, asoc)) | 453 | if (!sctp_vtag_verify(chunk, asoc)) |
454 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 454 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
@@ -480,11 +480,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, | |||
480 | goto nomem; | 480 | goto nomem; |
481 | 481 | ||
482 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); | 482 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); |
483 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 483 | return sctp_stop_t1_and_abort(commands, SCTP_ERROR_INV_PARAM, |
484 | SCTP_STATE(SCTP_STATE_CLOSED)); | 484 | ECONNREFUSED, asoc, |
485 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 485 | chunk->transport); |
486 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); | ||
487 | return SCTP_DISPOSITION_DELETE_TCB; | ||
488 | } | 486 | } |
489 | 487 | ||
490 | /* Verify the INIT chunk before processing it. */ | 488 | /* Verify the INIT chunk before processing it. */ |
@@ -511,27 +509,16 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, | |||
511 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, | 509 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, |
512 | SCTP_PACKET(packet)); | 510 | SCTP_PACKET(packet)); |
513 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | 511 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); |
514 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 512 | error = SCTP_ERROR_INV_PARAM; |
515 | SCTP_STATE(SCTP_STATE_CLOSED)); | ||
516 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, | ||
517 | SCTP_NULL()); | ||
518 | return SCTP_DISPOSITION_CONSUME; | ||
519 | } else { | 513 | } else { |
520 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 514 | error = SCTP_ERROR_NO_RESOURCE; |
521 | SCTP_STATE(SCTP_STATE_CLOSED)); | ||
522 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, | ||
523 | SCTP_NULL()); | ||
524 | return SCTP_DISPOSITION_NOMEM; | ||
525 | } | 515 | } |
526 | } else { | 516 | } else { |
527 | ret = sctp_sf_tabort_8_4_8(ep, asoc, type, arg, | 517 | sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); |
528 | commands); | 518 | error = SCTP_ERROR_INV_PARAM; |
529 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | ||
530 | SCTP_STATE(SCTP_STATE_CLOSED)); | ||
531 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, | ||
532 | SCTP_NULL()); | ||
533 | return ret; | ||
534 | } | 519 | } |
520 | return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, | ||
521 | asoc, chunk->transport); | ||
535 | } | 522 | } |
536 | 523 | ||
537 | /* Tag the variable length parameters. Note that we never | 524 | /* Tag the variable length parameters. Note that we never |
@@ -886,6 +873,8 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep, | |||
886 | struct sctp_transport *transport = (struct sctp_transport *) arg; | 873 | struct sctp_transport *transport = (struct sctp_transport *) arg; |
887 | 874 | ||
888 | if (asoc->overall_error_count >= asoc->max_retrans) { | 875 | if (asoc->overall_error_count >= asoc->max_retrans) { |
876 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
877 | SCTP_ERROR(ETIMEDOUT)); | ||
889 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | 878 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ |
890 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 879 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
891 | SCTP_U32(SCTP_ERROR_NO_ERROR)); | 880 | SCTP_U32(SCTP_ERROR_NO_ERROR)); |
@@ -2126,6 +2115,8 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep, | |||
2126 | int attempts = asoc->init_err_counter + 1; | 2115 | int attempts = asoc->init_err_counter + 1; |
2127 | 2116 | ||
2128 | if (attempts > asoc->max_init_attempts) { | 2117 | if (attempts > asoc->max_init_attempts) { |
2118 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
2119 | SCTP_ERROR(ETIMEDOUT)); | ||
2129 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, | 2120 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, |
2130 | SCTP_U32(SCTP_ERROR_STALE_COOKIE)); | 2121 | SCTP_U32(SCTP_ERROR_STALE_COOKIE)); |
2131 | return SCTP_DISPOSITION_DELETE_TCB; | 2122 | return SCTP_DISPOSITION_DELETE_TCB; |
@@ -2262,6 +2253,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, | |||
2262 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) | 2253 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) |
2263 | error = ((sctp_errhdr_t *)chunk->skb->data)->cause; | 2254 | error = ((sctp_errhdr_t *)chunk->skb->data)->cause; |
2264 | 2255 | ||
2256 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); | ||
2265 | /* ASSOC_FAILED will DELETE_TCB. */ | 2257 | /* ASSOC_FAILED will DELETE_TCB. */ |
2266 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error)); | 2258 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error)); |
2267 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 2259 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
@@ -2306,7 +2298,8 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep, | |||
2306 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) | 2298 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) |
2307 | error = ((sctp_errhdr_t *)chunk->skb->data)->cause; | 2299 | error = ((sctp_errhdr_t *)chunk->skb->data)->cause; |
2308 | 2300 | ||
2309 | return sctp_stop_t1_and_abort(commands, error, asoc, chunk->transport); | 2301 | return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, asoc, |
2302 | chunk->transport); | ||
2310 | } | 2303 | } |
2311 | 2304 | ||
2312 | /* | 2305 | /* |
@@ -2318,7 +2311,8 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep | |||
2318 | void *arg, | 2311 | void *arg, |
2319 | sctp_cmd_seq_t *commands) | 2312 | sctp_cmd_seq_t *commands) |
2320 | { | 2313 | { |
2321 | return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, asoc, | 2314 | return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, |
2315 | ENOPROTOOPT, asoc, | ||
2322 | (struct sctp_transport *)arg); | 2316 | (struct sctp_transport *)arg); |
2323 | } | 2317 | } |
2324 | 2318 | ||
@@ -2343,7 +2337,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep, | |||
2343 | * This is common code called by several sctp_sf_*_abort() functions above. | 2337 | * This is common code called by several sctp_sf_*_abort() functions above. |
2344 | */ | 2338 | */ |
2345 | static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | 2339 | static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, |
2346 | __u16 error, | 2340 | __u16 error, int sk_err, |
2347 | const struct sctp_association *asoc, | 2341 | const struct sctp_association *asoc, |
2348 | struct sctp_transport *transport) | 2342 | struct sctp_transport *transport) |
2349 | { | 2343 | { |
@@ -2353,6 +2347,7 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | |||
2353 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 2347 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
2354 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 2348 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
2355 | SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); | 2349 | SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); |
2350 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err)); | ||
2356 | /* CMD_INIT_FAILED will DELETE_TCB. */ | 2351 | /* CMD_INIT_FAILED will DELETE_TCB. */ |
2357 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, | 2352 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, |
2358 | SCTP_U32(error)); | 2353 | SCTP_U32(error)); |
@@ -3336,6 +3331,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
3336 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 3331 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
3337 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | 3332 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); |
3338 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); | 3333 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); |
3334 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
3335 | SCTP_ERROR(ECONNABORTED)); | ||
3339 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 3336 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
3340 | SCTP_U32(SCTP_ERROR_ASCONF_ACK)); | 3337 | SCTP_U32(SCTP_ERROR_ASCONF_ACK)); |
3341 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 3338 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
@@ -3362,6 +3359,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
3362 | * processing the rest of the chunks in the packet. | 3359 | * processing the rest of the chunks in the packet. |
3363 | */ | 3360 | */ |
3364 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); | 3361 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); |
3362 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
3363 | SCTP_ERROR(ECONNABORTED)); | ||
3365 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 3364 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
3366 | SCTP_U32(SCTP_ERROR_ASCONF_ACK)); | 3365 | SCTP_U32(SCTP_ERROR_ASCONF_ACK)); |
3367 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 3366 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
@@ -3714,9 +3713,13 @@ static sctp_disposition_t sctp_sf_violation_chunklen( | |||
3714 | if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) { | 3713 | if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) { |
3715 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 3714 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
3716 | SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); | 3715 | SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); |
3716 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
3717 | SCTP_ERROR(ECONNREFUSED)); | ||
3717 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, | 3718 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, |
3718 | SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); | 3719 | SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); |
3719 | } else { | 3720 | } else { |
3721 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
3722 | SCTP_ERROR(ECONNABORTED)); | ||
3720 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 3723 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
3721 | SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); | 3724 | SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); |
3722 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | 3725 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); |
@@ -4034,6 +4037,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort( | |||
4034 | * TCB. This is a departure from our typical NOMEM handling. | 4037 | * TCB. This is a departure from our typical NOMEM handling. |
4035 | */ | 4038 | */ |
4036 | 4039 | ||
4040 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4041 | SCTP_ERROR(ECONNABORTED)); | ||
4037 | /* Delete the established association. */ | 4042 | /* Delete the established association. */ |
4038 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 4043 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
4039 | SCTP_U32(SCTP_ERROR_USER_ABORT)); | 4044 | SCTP_U32(SCTP_ERROR_USER_ABORT)); |
@@ -4175,6 +4180,8 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( | |||
4175 | * TCB. This is a departure from our typical NOMEM handling. | 4180 | * TCB. This is a departure from our typical NOMEM handling. |
4176 | */ | 4181 | */ |
4177 | 4182 | ||
4183 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4184 | SCTP_ERROR(ECONNREFUSED)); | ||
4178 | /* Delete the established association. */ | 4185 | /* Delete the established association. */ |
4179 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, | 4186 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, |
4180 | SCTP_U32(SCTP_ERROR_USER_ABORT)); | 4187 | SCTP_U32(SCTP_ERROR_USER_ABORT)); |
@@ -4543,6 +4550,8 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep, | |||
4543 | struct sctp_transport *transport = arg; | 4550 | struct sctp_transport *transport = arg; |
4544 | 4551 | ||
4545 | if (asoc->overall_error_count >= asoc->max_retrans) { | 4552 | if (asoc->overall_error_count >= asoc->max_retrans) { |
4553 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4554 | SCTP_ERROR(ETIMEDOUT)); | ||
4546 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | 4555 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ |
4547 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 4556 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
4548 | SCTP_U32(SCTP_ERROR_NO_ERROR)); | 4557 | SCTP_U32(SCTP_ERROR_NO_ERROR)); |
@@ -4662,6 +4671,8 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep, | |||
4662 | SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d" | 4671 | SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d" |
4663 | " max_init_attempts: %d\n", | 4672 | " max_init_attempts: %d\n", |
4664 | attempts, asoc->max_init_attempts); | 4673 | attempts, asoc->max_init_attempts); |
4674 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4675 | SCTP_ERROR(ETIMEDOUT)); | ||
4665 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, | 4676 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, |
4666 | SCTP_U32(SCTP_ERROR_NO_ERROR)); | 4677 | SCTP_U32(SCTP_ERROR_NO_ERROR)); |
4667 | return SCTP_DISPOSITION_DELETE_TCB; | 4678 | return SCTP_DISPOSITION_DELETE_TCB; |
@@ -4711,6 +4722,8 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep | |||
4711 | 4722 | ||
4712 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | 4723 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); |
4713 | } else { | 4724 | } else { |
4725 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4726 | SCTP_ERROR(ETIMEDOUT)); | ||
4714 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, | 4727 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, |
4715 | SCTP_U32(SCTP_ERROR_NO_ERROR)); | 4728 | SCTP_U32(SCTP_ERROR_NO_ERROR)); |
4716 | return SCTP_DISPOSITION_DELETE_TCB; | 4729 | return SCTP_DISPOSITION_DELETE_TCB; |
@@ -4742,6 +4755,8 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep, | |||
4742 | 4755 | ||
4743 | SCTP_DEBUG_PRINTK("Timer T2 expired.\n"); | 4756 | SCTP_DEBUG_PRINTK("Timer T2 expired.\n"); |
4744 | if (asoc->overall_error_count >= asoc->max_retrans) { | 4757 | if (asoc->overall_error_count >= asoc->max_retrans) { |
4758 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4759 | SCTP_ERROR(ETIMEDOUT)); | ||
4745 | /* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | 4760 | /* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ |
4746 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 4761 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
4747 | SCTP_U32(SCTP_ERROR_NO_ERROR)); | 4762 | SCTP_U32(SCTP_ERROR_NO_ERROR)); |
@@ -4817,6 +4832,8 @@ sctp_disposition_t sctp_sf_t4_timer_expire( | |||
4817 | if (asoc->overall_error_count >= asoc->max_retrans) { | 4832 | if (asoc->overall_error_count >= asoc->max_retrans) { |
4818 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 4833 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
4819 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | 4834 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); |
4835 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4836 | SCTP_ERROR(ETIMEDOUT)); | ||
4820 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 4837 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
4821 | SCTP_U32(SCTP_ERROR_NO_ERROR)); | 4838 | SCTP_U32(SCTP_ERROR_NO_ERROR)); |
4822 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 4839 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
@@ -4870,6 +4887,8 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep, | |||
4870 | goto nomem; | 4887 | goto nomem; |
4871 | 4888 | ||
4872 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); | 4889 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); |
4890 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4891 | SCTP_ERROR(ETIMEDOUT)); | ||
4873 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 4892 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
4874 | SCTP_U32(SCTP_ERROR_NO_ERROR)); | 4893 | SCTP_U32(SCTP_ERROR_NO_ERROR)); |
4875 | 4894 | ||
@@ -5309,6 +5328,8 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
5309 | * processing the rest of the chunks in the packet. | 5328 | * processing the rest of the chunks in the packet. |
5310 | */ | 5329 | */ |
5311 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); | 5330 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); |
5331 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
5332 | SCTP_ERROR(ECONNABORTED)); | ||
5312 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 5333 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
5313 | SCTP_U32(SCTP_ERROR_NO_DATA)); | 5334 | SCTP_U32(SCTP_ERROR_NO_DATA)); |
5314 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 5335 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b6e4b89539b3..90863307bcd9 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1057,6 +1057,7 @@ static int __sctp_connect(struct sock* sk, | |||
1057 | inet_sk(sk)->dport = htons(asoc->peer.port); | 1057 | inet_sk(sk)->dport = htons(asoc->peer.port); |
1058 | af = sctp_get_af_specific(to.sa.sa_family); | 1058 | af = sctp_get_af_specific(to.sa.sa_family); |
1059 | af->to_sk_daddr(&to, sk); | 1059 | af->to_sk_daddr(&to, sk); |
1060 | sk->sk_err = 0; | ||
1060 | 1061 | ||
1061 | timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); | 1062 | timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); |
1062 | err = sctp_wait_for_connect(asoc, &timeo); | 1063 | err = sctp_wait_for_connect(asoc, &timeo); |