[zeromq-dev] [RFC] Passing file descriptors as endpoints in `zmq_connect` or `zmq_bind`

Ciprian Dorin Craciun ciprian.craciun at gmail.com
Wed Jul 24 14:59:47 CEST 2013


    Hello all!  I wanted to ask this for some time, but now I'm more
motivated by the fact that I actually need to use such a feature.
(Thus the motivation could go beyond just "asking", because I could
also provide the necessary patches.)


    == Summary ==

    Thus, as the subject says, is there any solution that would allow
a ZeroMQ socket to use an already existing file descriptor, in a
"connected" state, for example as an argument for `zmq_connect`,
instead of a textual endpoint.  And the same question for a file
descriptor, in an "accepting" state, say as an argument for
`zmq_bind`.

    I've searched for this topic in the mailing lists and the
documentation, but I didn't find such a feature.  Thus if my guess is
correct and there isn't such a solution already, would the community
accept patches that provide such a feature?  (In the details below I
try to start a discussion in such a direction.)


    == Details ==

    Having this feature would fit nicely in the following use-cases,
which are quite often encountered in the Linux world:


    (A) (for file descriptor in `zmq_bind`)  There is a trend for
daemons made to work on Linux, heavily pushed by systemd, which
(preferably) requires that systemd (or another manager) is the one
responsible to create and bind the listening socket, and then on the
first connection spawns the daemon and passes it the listening
socket's file descriptor (thus obtaining activation on demand of
daemons).  (Please note that I don't want to create a flame-war around
systemd, as it usually happens when it is referenced in public mailing
lists.  It seems most distributions push it as the new SysV init
replacement, thus good or bad, it would be nice to be "compatible"
with it.)

    (A.1)  A second, less likely use case, is when the user wants more
"control" over the various knobs of the underlying socket, such as the
newly introduced `SO_REUSEPORT` which allows multiple applications to
listen at the same time on the same TCP or UDP port (bound to the same
IP address).


    (B) (for file descriptor in `zmq_connect`)  The second use case
would be for a "master-slave" (or "dispatcher-worker") architecture
where the parent process (i.e. the "master") before spawning a child
creates an pair of UNIX sockets (by using `socketpair`) and uses one
for itself and passes the other to the child.

    (B.1) Another valid use-case would be the one in which the
application does it's own socket accepting, like via `inetd` systems.
One could imagine to exchange some messages to authenticate the other
party, and then just pass the socket to ZeroMQ.  (Of course this can't
replace SSL or equivalent.)

    (B.2) Going further with this, one could implement an in-process
`stunnel`-like solution that terminates the SSL connection (this is
easier than implementing message-based encryption), thus having a more
"conservative" solution for the SSL problem in the context of ZeroMQ.
(Although this is only a potential use-case and I don't want to focus
on the SSL issue in this thread.)


    The bottom line in all cases would be decoupling the way in which
the transport endpoint is created or obtained (i.e. the file
descriptor) from its actual usage (i.e. the part where ZeroMQ is
best).


    As technical details, in case such a feature doesn't already
exist, I would mention the following "requirements", which as said I
would be willing to provide patches for:

    * such a solution shouldn't require any change to the ZeroMQ
library except the part of "registering" these descriptors in the
system;  (thus only short-cutting the creation, and "connection" of
the sockets;)

    * the user should take care that the file descriptor is usable by
the library as expected (i.e. it's a "connected" socket for the
`zmq_connect` case, or a "listening" socket for the `zmq_bind`, and it
is of the right family (i.e. TCP or UNIX) or type (i.e. stream),
etc.);

    * reconnects won't work, and once the socket is closed by the
other party it's removed from ZeroMQ without trying to reconnect;


    As a potential interface, I would guess that adding a new
transport, say `fd:<number>`, to both `zmq_connect` or `zmq_bind`
would suffice.  Or if the implementation details differ from TCP and
UNIX, and this knowledge is required, one could add different
transports, say `tcp-fd:<number>`, or `ipc-fd:<number>`, etc.


    Sorry for the lengthy email, but I wanted to be as clear as
possible with regard of my proposed enhancement and its impacts on the
existing ZeroMQ library.

    Thanks,
    Ciprian.



More information about the zeromq-dev mailing list