X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fsctp%2Fsocket.c;h=49f9305710305f90d2f584111f5b31888857c2d9;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=5b1c8375c52113ecadf3c577a4286ebea0ff72c0;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 5b1c8375c..49f930571 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1057,7 +1057,6 @@ static int __sctp_connect(struct sock* sk, inet_sk(sk)->dport = htons(asoc->peer.port); af = sctp_get_af_specific(to.sa.sa_family); af->to_sk_daddr(&to, sk); - sk->sk_err = 0; timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); err = sctp_wait_for_connect(asoc, &timeo); @@ -1229,7 +1228,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) ep = sctp_sk(sk)->ep; - /* Walk all associations on an endpoint. */ + /* Walk all associations on a socket, not on an endpoint. */ list_for_each_safe(pos, temp, &ep->asocs) { asoc = list_entry(pos, struct sctp_association, asocs); @@ -1242,16 +1241,16 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) if (sctp_state(asoc, CLOSED)) { sctp_unhash_established(asoc); sctp_association_free(asoc); - continue; - } - } - if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { - struct sctp_chunk *chunk; + } else if (sock_flag(sk, SOCK_LINGER) && + !sk->sk_lingertime) { + struct sctp_chunk *chunk; - chunk = sctp_make_abort_user(asoc, NULL, 0); - if (chunk) - sctp_primitive_ABORT(asoc, chunk); + chunk = sctp_make_abort_user(asoc, NULL, 0); + if (chunk) + sctp_primitive_ABORT(asoc, chunk); + } else + sctp_primitive_SHUTDOWN(asoc, NULL); } else sctp_primitive_SHUTDOWN(asoc, NULL); } @@ -4931,8 +4930,6 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) /* Is there any exceptional events? */ if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; - if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; @@ -5354,7 +5351,6 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, */ sctp_release_sock(sk); current_timeo = schedule_timeout(current_timeo); - BUG_ON(sk != asoc->base.sk); sctp_lock_sock(sk); *timeo_p = current_timeo; @@ -5642,14 +5638,12 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, */ newsp->type = type; - /* Mark the new socket "in-use" by the user so that any packets - * that may arrive on the association after we've moved it are - * queued to the backlog. This prevents a potential race between - * backlog processing on the old socket and new-packet processing - * on the new socket. - */ - sctp_lock_sock(newsk); + spin_lock_bh(&oldsk->sk_lock.slock); + /* Migrate the backlog from oldsk to newsk. */ + sctp_backlog_migrate(assoc, oldsk, newsk); + /* Migrate the association to the new socket. */ sctp_assoc_migrate(assoc, newsk); + spin_unlock_bh(&oldsk->sk_lock.slock); /* If the association on the newsk is already closed before accept() * is called, set RCV_SHUTDOWN flag. @@ -5658,7 +5652,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, newsk->sk_shutdown |= RCV_SHUTDOWN; newsk->sk_state = SCTP_SS_ESTABLISHED; - sctp_release_sock(newsk); } /* This proto struct describes the ULP interface for SCTP. */