Subject: Re: soisdisconnected/soisconnected & EPIPE
To: Iain Hibbert <plunky@rya-online.net>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 11/16/2005 15:32:33
--tsOsTdHNUZQcU9Ye
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Wed, Nov 16, 2005 at 08:01:54PM +0000, Iain Hibbert wrote:
> Hi,
> not sure if this should be tech-net but I think here is good.
>=20
> 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:
>=20
> s =3D socket(..)
>=20
> connect(s, ...)
> send(s, ....)
>=20
> connect(s, ...)
> send(s, ...)
>=20
> close(s)
>=20
> which is permitted on some sockets according to the manpage, then how this
> translates into the protocol usrreq is:
>=20
> user usrreq action
>=20
> socket PRU_ATTACH
>=20
> connect PRU_CONNECT soisconnected()
> send PRU_SEND ..
>=20
> connect PRU_DISCONNECT soisdisconnected()
> PRU_CONNECT soisconnected()
>=20
> send PRU_SEND ..
>=20
> close PRU_DISCONNECT soisdisconnected()
> PRU_DETACH
>=20
> which seems normal until the second send happens, and we get EPIPE
> (broken pipe) back (actually before it gets to usrreq)
>=20
> 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
>=20
> how to get around this:
>=20
> a) dont do it, use sendto() instead..
>=20
> b) for PRU_DISCONNECT, dont actually call soisdisconnected(), just
> so->so_state &=3D ~SS_ISCONNECTED
>=20
> c) for PRU_CONNECT make sure the bits are cleared
>=20
> d) change soisconnected() to clear those bits.
>=20
> e) other
>=20
> if anybody has an opinion then let it out..
If the manpages really indicate what you mention should work, then I think=
=20
we want either (c) or (d). My guess is (d) is best; soisdisconnected() set=
=20
the flags, so let soisconnected() clear them.
Take care,
Bill
--tsOsTdHNUZQcU9Ye
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (NetBSD)
iD8DBQFDe8GRWz+3JHUci9cRAnWhAJ0aqYRk+7Vu/7q2VAXrDm7MFSJn5wCeMnNR
rHRuaR8ofTti+vm0WcTyKCA=
=Her9
-----END PGP SIGNATURE-----
--tsOsTdHNUZQcU9Ye--