Re: No connect timeout?

Andi Kleen (ak@muc.de)
Fri, 12 Mar 1999 22:24:48 +0100


On Fri, Mar 12, 1999 at 10:02:14PM +0100, Jason Gunthorpe wrote:
>
> On Fri, 12 Mar 1999, Andi Kleen wrote:
>
> > > SYN_SENT off (0.00/0)
> > > tcp 0 0 saens.debian.o:ftp-data ftp.ua.pt:2159
> > > SYN_SENT
> > >
> > > [.. about 10 more, many from ftp.ua.pt but not all]
> > >
> > > The first is not a stuck socket AFAIK, if I run the command again it will
> > > not be there. The rest all have disabled timers and are in the SYN_SENT
> > > state.
> >
> > When you run ps lax on the box (with correct System.map accessible for
> > ps), I guess the ftpds are hanging in inet_wait_for_connect. Is this correct?
>
> Okay..

I think I found it. There was a race in async ICMP error handling when a signal
occurred at the right time. After the system call was restarted there was
no check for an already pending error in the blocking case, after it went
to sleep it never woke up again because no one called sk->error_report again.

This patch should fix it.

Jason, Could you test it please?

David, Alexey, what do you think?

--- linux/net/ipv4/af_inet.c-o Fri Mar 12 22:14:56 1999
+++ linux/net/ipv4/af_inet.c Fri Mar 12 22:22:26 1999
@@ -53,6 +53,7 @@
* David S. Miller : New socket lookup architecture.
* Some other random speedups.
* Cyrus Durgin : Cleaned up file for kmod hacks.
+ * Andi Kleen : Fix inet_stream_connect TCP race.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -617,10 +618,13 @@
sock->state = SS_CONNECTED;
return 0;
}
- if(sk->protocol == IPPROTO_TCP && (flags & O_NONBLOCK)) {
- if(sk->err)
+ if(sk->protocol == IPPROTO_TCP) {
+ if (sk->zapped)
+ goto async_error;
+ if(sk->err)
return sock_error(sk);
- return -EALREADY;
+ if (flags & O_NONBLOCK)
+ return -EALREADY;
}
} else {
/* We may need to bind the socket. */
@@ -651,6 +655,7 @@
sock->state = SS_CONNECTED;
if ((sk->state != TCP_ESTABLISHED) && sk->err) {
/* This is ugly but needed to fix a race in the ICMP error handler */
+async_error:
if (sk->protocol == IPPROTO_TCP && sk->zapped) {
lock_sock(sk);
tcp_set_state(sk, TCP_CLOSE);

-Andi

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/