[8488] in bugtraq

home help back first fref pref prev next nref lref last post

Re: Sendmail, lynx, Netscape, sshd, Linux kernel (twice)

daemon@ATHENA.MIT.EDU (Andi Kleen)
Tue Nov 10 16:14:35 1998

Date: 	Tue, 10 Nov 1998 21:02:38 +0100
Reply-To: Andi Kleen <ak@MUC.DE>
From: Andi Kleen <ak@MUC.DE>
X-To:         Wietse Venema <wietse@PORCUPINE.ORG>
To: BUGTRAQ@NETSPACE.ORG
In-Reply-To:  Wietse Venema's message of "Mon, 9 Nov 1998 14:05:42 -0500"

In article <19981109190542.BE4EA4587E@spike.porcupine.org>,
Wietse Venema <wietse@PORCUPINE.ORG> writes:
> With regard to LINUX accept() returning benign error results other
> than the usual suspects (EAGAIN or EINTR), Todor Tuparov asked:

>> Is there a solution?
>> Very simple question.

> I understand that with LINUX 2.1.x the accept() call will not wake
> up before the TCP three-way handshake is complete.

> But for now, it is up to the programmer to deal with benign error
> returns such as: ECONNREFUSED, ECONNRESET, EHOSTDOWN, EHOSTUNREACH,
> ENETDOWN, ENETUNREACH, ENOTCONN, and to treat them just like EAGAIN.

I'm sorry that is not the full story. In some cases Linux 2.1 TCP
accept may still return network errors. This patch against 2.1.127
should fix it (and also fixes another bug). If an asynchronous error
occurs now after the 3way handshake completion it will be returned on
the first socket operation after accept.

Index: linux/net/ipv4/tcp.c
===================================================================
RCS file: /vger/u4/cvs/linux/net/ipv4/tcp.c,v
retrieving revision 1.131
diff -u -u -r1.131 tcp.c
--- tcp.c       1998/11/08 11:17:05     1.131
+++ tcp.c       1998/11/10 19:47:21
@@ -1630,10 +1626,12 @@
         * here - you'll have to check for sk->zapped as set by the ICMP handler then.
         */

-       error = 0;
-out:
        release_sock(sk);
+       return newsk;
+
+out:
        sk->err = error;
+       release_sock(sk);
        return newsk;
 }

Index: linux/net/ipv4/af_inet.c
===================================================================
RCS file: /vger/u4/cvs/linux/net/ipv4/af_inet.c,v
retrieving revision 1.80
diff -u -u -r1.80 af_inet.c
--- af_inet.c   1998/11/08 11:17:03     1.80
+++ af_inet.c   1998/11/10 19:47:23
@@ -703,22 +722,20 @@

        if(sk2->state == TCP_ESTABLISHED)
                goto do_full_success;
-       if(sk2->err > 0)
-               goto do_connect_err;
        err = -ECONNABORTED;
        if (sk2->state == TCP_CLOSE)
                goto do_bad_connection;
 do_full_success:
+       newsk->prot->unhash(newsk);
        destroy_sock(newsk);
        newsock->state = SS_CONNECTED;
        return 0;

 do_half_success:
+       newsk->prot->unhash(newsk);
        destroy_sock(newsk);
        return(0);

-do_connect_err:
-       err = sock_error(sk2);
 do_bad_connection:
        sk2->sleep = NULL;
        sk2->socket = NULL;

-Andi

home help back first fref pref prev next nref lref last post