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--