AF_UNIX status report

Corinna Vinschen corinna-cygwin@cygwin.com
Thu Nov 5 17:21:40 GMT 2020


On Nov  5 09:23, Ken Brown via Cygwin-developers wrote:
> OK, here's how I imagine this working:
> 
> A process wants to send a file descriptor fd, so it creates a msghdr with an
> SCM_RIGHTS cmsghdr and calls sendmsg.  The latter creates and sends an admin
> packet A containing the fhandler for fd, and then it sends the original
> packet P.
> 
> At the receiving end, recvmsg sees packet A first (recvmsg is always
> checking for admin packets anyway whenever it's called).  It stores the
> fhandler somewhere.  When it then reads packet P, it retrieves the stored
> fhandler, fiddles with it (duplicating handles, etc.), and creates the new
> file descriptor.

Actually, this needs to be implemented in a source/dest-independent
manner.  Only the server of the named pipe can impersonate the client.
So the server side should do the job of duplicating the handles.  If the
sever is also the source of SCM_RIGHTS, it should send the fhandler with
already duplicated handles.

> Does this seem reasonable?  The main thing bothering me is the lack of
> atomicity.  I don't like the gap between the sending of the two packets A
> and P, and similarly for the receiving.  I thought about using the io_lock
> to at least make sure that the two packets are adjacent in the pipe, but I
> don't know if we want to tie up the io_lock for that long.
> 
> Also, the sending process might be sending several file descriptors at once,
> so that there would be several admin packets to be sent (unless we want to
> cram it all into one).

We can safely assume that pipe packets up to 64K are sent and received
atomically.

In most cases this shouldn't be much of a problem.  Most scenarios using
SCM_RIGHTS send no or only a minor payload.  Most scenarios share a
single or only a handful of descriptors.

Apart from that, Linux also defines SCM_MAX_FD, the max. number of
descriptors in a single sendmsg call.  If the number of descriptors
is larger, sendmsg returns EINVAL.  SCM_MAX_FD is 253 on Linux, but

What that means to us is, we can choose our own SCM_MAX_FD and just
return EINVAL if the number of descriptors is uncomfortably high.
The max. number of descriptors should be limited so that all descriptors
fit into 64K, or even 32K, just to leave space for payload.
Assuming a size of about 600 bytes per fhandler, 50 might be a good
candidate for SCM_MAX_FD.  I'd say even 32 would be sufficent for most
scenarios.

The idea would be to create the packet on the source side with all
fhandlers in the ancilliary data block, followed by the payload.
This should typically fit in a 64K package.  If not, only the
payload needs to be split into multiple packages.  Do we really
need atomicity there?  Not sure, but only then we'd need an io_lock.

Does that make sense?


Thanks,
Corinna


More information about the Cygwin-developers mailing list