public inbox for cygwin-developers@cygwin.com
 help / color / mirror / Atom feed
From: Ken Brown <kbrown@cornell.edu>
To: cygwin-developers@cygwin.com
Subject: Re: Problems with the (new) implementation of AF_UNIX datagram sockets
Date: Thu, 15 Apr 2021 09:16:56 -0400	[thread overview]
Message-ID: <af4fd19e-a849-cb2e-7327-7ffc5647c11a@cornell.edu> (raw)
In-Reply-To: <YHgoNmvIL8uljnnl@calimero.vinschen.de>

On 4/15/2021 7:49 AM, Corinna Vinschen wrote:
> Hi Ken,
> 
> On Apr 14 12:15, Ken Brown wrote:
>> Hi Corinna,
>>
>> This is a follow-up to
>>
>>    https://cygwin.com/pipermail/cygwin/2021-April/248284.html
>>
>> I don't know if you've been following that thread, but two serious problems
>> with datagram sockets (on the topic/af_unix branch) have shown up.
>>
>> 1. Writing will block until a connection to the peer's pipe can be made.  In
>> particular, if there are two consecutive writes with the same peer, the
>> second one will block until the peer reads the first message.  This happens
>> because the peer's pipe is not available for the second connection until the
>> peer disconnects the first connection.  This is currently done in recvmsg,
>> and I don't see a straightforward way to do it anywhere else.
> 
> I'm a bit puzzeled.  The idea for datagrams was to call open/send/close
> in each invocation of sendmsg.  Therefore the pipe should become
> available as soon as the other peer has sent it's data block.  The time
> a sendmsg has to wait for the pipe being available should be quite short!

Unfortunately, the pipe isn't available until the server disconnects.  I 
observed this in practice, and it's also documented at

https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-disconnectnamedpipe

"The server process must call DisconnectNamedPipe to disconnect a pipe handle 
from its previous client before the handle can be connected to another client by 
using the ConnectNamedPipe function."

>> 2. There's no way for select to test whether a datagram socket is ready for
>> writing.  That's because we can't know whether a connection to a
>> hypothetical peer's pipe will be possible.  According to Stevens, the issue
>> *should* be whether there's space in the socket's send buffer.  But our
>> sockets don't have a send buffer until they connect to a pipe.
> 
> Even then, there's no guarantee a send will succeed, given that
> select/send are not running atomically.  However, we *could* for a start
> always return success from select for this scenario.  If we have a
> nonblocking socket, it should fail opening the pipe and return EGAIN,
> which is perfectly fine.  If we have a blocking socket, it could block
> on send, which is perfectly valid, too, because of the non-atomicity.
> 
> Or am I missing something?

No, I was missing the non-atomicity.  So maybe that's OK.

>> I think the solution to both problems is for Cygwin to maintain a send
>> buffer for datagram sockets.  Does that seem right, or do you have another
>> idea?
> 
> In theory the send buffer should be a shared buffer between all peers,
> so this could be constructed as a shared ring buffer, accessible from
> af_unix_shmem_t.  But then again, this introduces a security problem,
> so that's not a good idea.  So, process-local buffers.
> 
> But you also have the problem how to empty the buffer.  Do you start a
> new thread which checks if the pipe is getting available and if so,
> sends the buffer content?  In which process?  And what do you do if
> there's still data in the send buffer when the process exits?  This is
> annoyingly complicated and error-prone.

Agreed.

> Another idea might be to implement send/recv on a DGRAM socket a bit
> like accept.  Rather than creating a single_instance socket, we create a
> max_instance socket as for STREAM socket listeners.  The server side
> accepts the connection at recv and immediately opens another pipe
> instance, so we always have at least one dangling instance for the next
> peer.

I thought about that, but you would still have the problem (as in 1 above) that 
the pipe instance isn't available until recv is called.

> 
> Corinna
> 
> 
> P.S.: Idle musings...
> 
> The only other implementation of AF_UNIX sockets using named pipes on
> Windows I know of (U/WIN) implements the gory details as part of their
> priviledged server process, i. e., their equivalent of cygserver.  The
> difference is that the entire system is based on this server process, so
> the U/WIN processes don't run at all if that service isn't running,
> quite unlike Cygwin.  Requiring a server running just to allow AF_UNIX
> sockets to work seems a bit off for us...
> 
> Having said that, maybe the idea to implement AF_UNIX sockets as named
> pipes is... outdated?  Roughly 90% of our users are running a W10
> version supporting AF_UNIX sockets natively (albeit missing native
> SOCK_DGRAM support).  Perhaps it's time to switch...?

Maybe so.

Ken

  reply	other threads:[~2021-04-15 13:17 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-14 16:15 Ken Brown
2021-04-15 11:49 ` Corinna Vinschen
2021-04-15 13:16   ` Ken Brown [this message]
2021-04-15 13:58     ` Corinna Vinschen
2021-04-15 14:53       ` Ken Brown
2021-04-15 23:50         ` Mark Geisert
2021-04-16  9:37           ` Corinna Vinschen
2021-04-17  2:54             ` Mark Geisert
2021-04-17 16:05               ` Ken Brown
2021-04-19  8:48                 ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=af4fd19e-a849-cb2e-7327-7ffc5647c11a@cornell.edu \
    --to=kbrown@cornell.edu \
    --cc=cygwin-developers@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).