Subject: soisdisconnected/soisconnected & EPIPE
To: None <tech-kern@netbsd.org>
From: Iain Hibbert <plunky@rya-online.net>
List: tech-kern
Date: 11/16/2005 20:01:54
Hi,
not sure if this should be tech-net but I think here is good.
in the socket code (uipc_socket2.c) there are two calls, soisconnected()
and soisdisconnected() which do the obvious thing. Except that, from a
userland point of view I'm not sure if something is amiss.. if a program
wants to do:
s = socket(..)
connect(s, ...)
send(s, ....)
connect(s, ...)
send(s, ...)
close(s)
which is permitted on some sockets according to the manpage, then how this
translates into the protocol usrreq is:
user usrreq action
socket PRU_ATTACH
connect PRU_CONNECT soisconnected()
send PRU_SEND ..
connect PRU_DISCONNECT soisdisconnected()
PRU_CONNECT soisconnected()
send PRU_SEND ..
close PRU_DISCONNECT soisdisconnected()
PRU_DETACH
which seems normal until the second send happens, and we get EPIPE
(broken pipe) back (actually before it gets to usrreq)
I investigated and found that this is because soisdisconnected() sets
SS_CANTSENDMORE & SS_CANTRCVMORE which would be fine but soisconnected()
does not clear them and thats what causes the broken pipe when you try to
send afterwards
how to get around this:
a) dont do it, use sendto() instead..
b) for PRU_DISCONNECT, dont actually call soisdisconnected(), just
so->so_state &= ~SS_ISCONNECTED
c) for PRU_CONNECT make sure the bits are cleared
d) change soisconnected() to clear those bits.
e) other
if anybody has an opinion then let it out..
iain