The unreliability of AF_UNIX datagram sockets

Ken Brown kbrown@cornell.edu
Sat May 22 16:50:21 GMT 2021


On 5/22/2021 11:49 AM, Corinna Vinschen wrote:
> On May 21 17:54, Ken Brown wrote:
>> On 5/20/2021 3:25 PM, Corinna Vinschen wrote:
>>> On May 20 09:46, Ken Brown wrote:
>>>> On 4/29/2021 7:05 AM, Corinna Vinschen wrote:
>>>>> I think it should be possible to switch to STREAM sockets to emulate
>>>>> DGRAM semantics.  Our advantage is that this is all local.  For all
>>>>> practical purposes there's no chance data gets really lost.  Windows has
>>>>> an almost indefinite send buffer.
>>>>>
>>>>> If you look at the STREAM as a kind of tunneling layer for getting DGRAM
>>>>> messages over the (local) line, the DGRAM content could simply be
>>>>> encapsulated in a tunnel packet or frame, basically the same way the
>>>>> new, boring AF_UNIX code does it.  A DGRAM message encapsulated in a
>>>>> STREAM message always has a header which at least contains the length of
>>>>> the actual DGRAM message.  So when the peer reads from the socket, it
>>>>> always only reads the header until it's complete.  Then it knows how
>>>>> much payload is expected and then it reads until the payload has been
>>>>> received.
>>>>
>>>> I think I'd like to go ahead and try to do this DGRAM emulation in the
>>>> current (AF_LOCAL) code.  It shouldn't be too hard, and it would solve the
>>>> unreliability problem while we look for a better way to handle AF_UNIX
>>>> sockets.
>>>
>>> Yeah, sounds like the way to go for now.
>>
>> Unfortunately, I ran into a problem.  Trying to emulate DGRAM sockets in
>> STREAM sockets breaks the DGRAM send/recv semantics.  For example,
>> WSARecvFrom won't return the source address.
> 
> It doesn't anyway, does it?  I mean, this is entirely local and the
> source address is, basically, the same socket.

 From the Winsock point of view, the sending socket is an AF_INET socket, whose 
name is a struct sockaddr_in (the crucial data being the port number). 
fhandler_socket_local::recv_internal then converts the sockaddr_in of the sender 
to an abstract sockaddr_un that encodes the port number, so that the receiver 
can send back a reply.

Aside from this issue, there's also the fact that all the send/recv functions 
when applied to STREAM sockets expect the socket to be connected.  But if we're 
using STREAM sockets to emulate DGRAM sockets, they typically won't be 
connected.  (And "connected" means something different for DGRAMs anyway.)

Ken


More information about the Cygwin-developers mailing list