Subject: accept(2) behaviour.
To: None <tech-net@netbsd.org>
From: Darren Reed <darrenr@reed.wattle.id.au>
List: tech-net
Date: 06/26/1999 14:05:18
Whilst playing with accept(2), it would appear that if there is a
pending connection waiting to be accepted and something in the calling
of accept(2) causes it to return an error, the connection is lost.
What's more, it would appear that the connection goes into an
ESTABLISHED TCP state and the fd allocated to the process but no valid
fd is returned.  I.e. the process has an fd which the application knows
nothing about.

As an example, consider the following from fstat:

# fstat -p 6883
USER     CMD          PID   FD MOUNT      INUM MODE         SZ|DV R/W
root     stest       6883   wd /usr      61758 drwx------    1536 r 
root     stest       6883    0 /          2005 crw--w----   ttyp0 rw
root     stest       6883    1 /          2005 crw--w----   ttyp0 rw
root     stest       6883    2 /          2005 crw--w----   ttyp0 rw
root     stest       6883    3* internet stream tcp f10d78f8 *:65503
root     stest       6883    4* internet stream tcp f10d7a40 127.0.0.1:65502 <-> 127.0.0.1:65503
root     stest       6883    5* internet stream tcp f10d7854 *:0
root     stest       6883    6* internet stream tcp f10d7ae4 127.0.0.1:65503 <-> 127.0.0.1:65502

From kdump:

  6879 stest    CALL  socket(0x2,0x1,0)
  6879 stest    RET   socket 3
       "accept on port 65505
  6879 stest    CALL  socket(0x2,0x1,0)
  6879 stest    RET   socket 4
  6879 stest    CALL  connect(0x4,0xefbfd6a8,0x10)
  6879 stest    RET   connect 0
  6879 stest    CALL  accept(0xff,0xefbfd6a8,0xefbfd6a0)
  6879 stest    RET   accept -1 errno 9 Bad file descriptor
  6879 stest    CALL  accept(0x5,0xefbfd6a8,0xefbfd6a0)
  6879 stest    RET   accept -1 errno 38 Socket operation on non-socket
  6879 stest    CALL  socket(0x2,0x2,0)
  6879 stest    RET   socket 5
  6879 stest    CALL  accept(0x5,0xefbfd6a8,0xefbfd6a0)
  6879 stest    RET   accept -1 errno 22 Invalid argument
       "45 accept check failed (22)
  6879 stest    CALL  socket(0x2,0x1,0)
  6879 stest    RET   socket 5
  6879 stest    CALL  accept(0x3,0xdeadbeaf,0xefbfd6a0)
  6879 stest    RET   accept -1 errno 14 Bad address
  6879 stest    CALL  accept(0x3,0x69a0,0xefbfd6a0)

an fd of 6 was never returned.

Does anyone want to say this is the `correct' behaviour ? :)  If not,
what should we do, put the connection back on the queue for the next
accept or dispose of the fd (and connection) as a result of the failure?

send-pr time perhaps? :-)

Darren