Commit 8de8c873 authored by Sridhar Samudrala's avatar Sridhar Samudrala

[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: default avatarSridhar Samudrala <sri@us.ibm.com>
parent ee433530
...@@ -99,6 +99,7 @@ typedef enum { ...@@ -99,6 +99,7 @@ typedef enum {
SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */ SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */
SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */ SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */
SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */ SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */
SCTP_CMD_SET_SK_ERR, /* Set sk_err */
SCTP_CMD_LAST SCTP_CMD_LAST
} sctp_verb_t; } sctp_verb_t;
......
...@@ -412,7 +412,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, ...@@ -412,7 +412,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
union sctp_addr daddr; union sctp_addr daddr;
struct sctp_af *af; struct sctp_af *af;
struct sock *sk = NULL; struct sock *sk = NULL;
struct sctp_association *asoc = NULL; struct sctp_association *asoc;
struct sctp_transport *transport = NULL; struct sctp_transport *transport = NULL;
*app = NULL; *tpp = NULL; *app = NULL; *tpp = NULL;
...@@ -490,7 +490,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) ...@@ -490,7 +490,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
int type = skb->h.icmph->type; int type = skb->h.icmph->type;
int code = skb->h.icmph->code; int code = skb->h.icmph->code;
struct sock *sk; struct sock *sk;
struct sctp_association *asoc; struct sctp_association *asoc = NULL;
struct sctp_transport *transport; struct sctp_transport *transport;
struct inet_sock *inet; struct inet_sock *inet;
char *saveip, *savesctp; char *saveip, *savesctp;
......
...@@ -498,10 +498,6 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands, ...@@ -498,10 +498,6 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED)); SCTP_STATE(SCTP_STATE_CLOSED));
/* Set sk_err to ECONNRESET on a 1-1 style socket. */
if (!sctp_style(asoc->base.sk, UDP))
asoc->base.sk->sk_err = ECONNRESET;
/* SEND_FAILED sent later when cleaning up the association. */ /* SEND_FAILED sent later when cleaning up the association. */
asoc->outqueue.error = error; asoc->outqueue.error = error;
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); 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,6 +834,15 @@ static void sctp_cmd_del_non_primary(struct sctp_association *asoc)
return; return;
} }
/* Helper function to set sk_err on a 1-1 style socket. */
static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error)
{
struct sock *sk = asoc->base.sk;
if (!sctp_style(sk, UDP))
sk->sk_err = error;
}
/* These three macros allow us to pull the debugging code out of the /* These three macros allow us to pull the debugging code out of the
* main flow of sctp_do_sm() to keep attention focused on the real * main flow of sctp_do_sm() to keep attention focused on the real
* functionality there. * functionality there.
...@@ -1458,6 +1463,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, ...@@ -1458,6 +1463,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
local_cork = 0; local_cork = 0;
asoc->peer.retran_path = t; asoc->peer.retran_path = t;
break; break;
case SCTP_CMD_SET_SK_ERR:
sctp_cmd_set_sk_err(asoc, cmd->obj.error);
break;
default: default:
printk(KERN_WARNING "Impossible command: %u, %p\n", printk(KERN_WARNING "Impossible command: %u, %p\n",
cmd->verb, cmd->obj.ptr); cmd->verb, cmd->obj.ptr);
......
This diff is collapsed.
...@@ -1057,6 +1057,7 @@ static int __sctp_connect(struct sock* sk, ...@@ -1057,6 +1057,7 @@ static int __sctp_connect(struct sock* sk,
inet_sk(sk)->dport = htons(asoc->peer.port); inet_sk(sk)->dport = htons(asoc->peer.port);
af = sctp_get_af_specific(to.sa.sa_family); af = sctp_get_af_specific(to.sa.sa_family);
af->to_sk_daddr(&to, sk); af->to_sk_daddr(&to, sk);
sk->sk_err = 0;
timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
err = sctp_wait_for_connect(asoc, &timeo); err = sctp_wait_for_connect(asoc, &timeo);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment