Subject: Re: Missing EOF for socketpair() with SOCK_DGRAM
To: None <tech-net@NetBSD.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-net
Date: 11/01/2006 21:20:13
>>> -		unp->unp_socket->so_state &= ~SS_ISCONNECTED;
>>> +		soisdisconnected(unp->unp_socket);
>> This change looks correct to me.

It looks correct to me at first sight, but I think it's wrong.

In particular, soisdisconnected() sets SS_CANTRCVMORE and
SS_CANTSENDMORE.  For a socket type which can disconnect and then
reconnect (to the same or another socket), this is wrong, since
reconnecting doesn't clear SS_CANTRCVMORE and SS_CANTSENDMORE as far as
I can see (certainly soisconnected() doesn't).

If you just want the recv-breakout semantics (which I'm not convinced
are right either, though I think that's a lot more defensible), I'd
suggest trying adding the wakeup()/sowwakeup()/sorwakeup() calls from
soisdisconnected() to the SOCK_DGRAM case of unp_disconnect().

>> Btw: there is a similar issue in netinet/udp_usrreq.c - conveniently
>> marked /* XXX */ already.

Since one of the things there is a commented-out soisdisconnected()
call, I wouldn't want to change that without knowing why the author of
that code didn't use soisdisconnected().  (Without that, there's some
chance the author didn't know about it or didn't think of it.)  My
guess would be that it's because of the SS_CANT{RCV,SEND}MORE issue.

> Actually, UDP doesn't have this problem.  AF_LOCAL/socketpair have
> this problem because they are a pair intimately known only to each
> other.

Yes...but there is nothing in this code change which makes it work only
for socketpair-created sockets; it applies, as far as I can tell, to
any connected AF_LOCAL/SOCK_DGRAM socket.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B