aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSridhar Samudrala <sri@us.ibm.com>2006-05-19 13:58:12 -0400
committerSridhar Samudrala <sri@us.ibm.com>2006-05-19 13:58:12 -0400
commit8de8c8738086501bbe3057ed6f4b70dded657488 (patch)
treec8c5b4b5c3d3c35993368d0e462484cc62b006f4
parentee433530d96a7b0af24ab616e5b51f1d89f9ae38 (diff)
[SCTP]: Set sk_err so that poll wakes up after a non-blocking connect failure.
Also fix some other cases where sk_err is not set for 1-1 style sockets. Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
-rw-r--r--include/net/sctp/command.h1
-rw-r--r--net/sctp/input.c4
-rw-r--r--net/sctp/sm_sideeffect.c16
-rw-r--r--net/sctp/sm_statefuns.c75
-rw-r--r--net/sctp/socket.c1
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. */
838static 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,
93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); 93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
94 94
95static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 95static 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 */
2345static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 2339static 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);