Hello,

in recent 2.3 linux accept on unix-domain sockets  is broken. It immediatly returns 
ENOTCONN
when called on listening sockets with no connections pending, instead of waiting.
The reason is, that skb_recv_datagram is used get incoming connection requests, but 
this checks
if a SOCK_STREAM socket is in TCP_ESTABLISHED state before waiting.
Here is a patch, that fixes this problem by not using skb_recv_datagram. It may not be 
the right 
solution, but it fixes this problem.

Lars Heete
--- linux/net/unix/af_unix.c.bak        Thu Oct 28 18:25:11 1999
+++ linux/net/unix/af_unix.c    Thu Oct 28 19:06:58 1999
@@ -961,18 +961,26 @@
 
        /* If socket state is TCP_LISTEN it cannot change,
           so that no locks are necessary.
         */
 
-       skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
-       if (!skb)
-               goto out;
+        do {
+                if ((skb = skb_dequeue(&sk->receive_queue)) == NULL) {
+                        if (flags & O_NONBLOCK)
+                                return -EAGAIN;
+ 
+                        if (signal_pending(current))
+                                return -ERESTARTSYS;
+
+                        interruptible_sleep_on(sk->sleep);
+                }
+        } while (skb == NULL);
 
        tsk = skb->sk;
+       kfree_skb(skb);
        if (skb_queue_len(&sk->receive_queue) <= sk->max_ack_backlog/2)
                wake_up_interruptible(&sk->protinfo.af_unix.peer_wait);
-       skb_free_datagram(sk, skb);
 
        /* attach accepted sock to socket */
        unix_state_wlock(tsk);
        newsock->state = SS_CONNECTED;
        newsock->sk = tsk;

Reply via email to