Subject: kern/21088: unix domain SOCK_DGRAM socketpair broken
To: None <>
From: None <>
List: netbsd-bugs
Date: 04/10/2003 10:58:59
>Number:         21088
>Category:       kern
>Synopsis:       unix domain SOCK_DGRAM socketpair broken
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 10 11:00:01 PDT 2003
>Originator:     Jesse Off
>Release:        1.6.1
NetBSD angel 1.6.1_RC2 NetBSD 1.6.1_RC2 (DELL600SC) #3: Mon Mar 24 21:42:07 MST
2003     joff@buffy:/u/src/sys/arch/i386/compile/DELL600SC i386
When the receive buffer fills in one socket from a
socketpair(PF_LOCAL, SOCK_DGRAM), I've noticed that
subsequent write()s to the other socket will fail with
EINVAL.  Solaris and Linux seem to agree to block when the buffers fill, that would be ideal in my case, but I'd even settle for a better
return errno.  EINVAL leads me to believe I'm passing
bad pointers, which I'm not.  Here's the test code
that will fail the written assert():

#include <sys/socket.h>
#include <errno.h>
#include <assert.h>

int main(void)
  char buf[1024];
  int sk[2];
  int ret = 0;
  socketpair(PF_LOCAL, SOCK_DGRAM, 0, sk);

  while(ret != -1)
    ret = write(sk[0], buf, 1024);
  assert(errno != EINVAL);

I'm running this on 1.6.1, but based on a quick look
at the code in -current from cvs I'm guessing its
present in there to.  The culprit seems to
unp_output() in uipc_usrreq.c returning the EINVAL
when the sbappendaddr() to the buddy socket's receive
buffer returns 0.

I'm not sure what apps out there this affects, but I noticed it when trying to run usermode ppp "ppp -direct server" with one end of the above socketpair as stdin.  (usermode ppp understands how to send/recv ppp over datagram sockets) ppp would exit and disconnect with "phase: deflink: read (0): Invalid argment" error message during high traffic.
see C code snippet in description.