Pass an open socket to another process????

Keith Sklower sklower at sequoia.Berkeley.EDU.berkeley.edu
Fri Feb 12 08:37:10 AEST 1988


In article <633 at eden.quintus.UUCP> jbeard at quintus.UUCP (Jeff Beard) writes:
>
>
>Your problem is of interest to anyone concerned with nested servers.
>I for one would appreciate a posting of the summary of your findings.
>
>Tnx.

4.2 and 4.3 BSD provide a means of passing an open file descriptor
of any sort (including sockets) between two co-operating processes
by means of the sendmsg system call.

In fact, I am presently engaged in reducing the latency in providing
XNS courier services under UNIX by use of this mechanism.  The Courier
RPC protocol imbeds requests for services as part of the data of a stream,
so one would like to pass the stream between processes, and fork + exec
is a relatively slow way to do it.

For greatest speed, you want to establish an additional UNIX-domain
socket connection between the two processes prior to when the "passing
of the baton" will occur.  You can do this with either a stream or datagram
connection (but if you use a datagram connection you must be careful
to check that the sendmsg system call doesn't fail due to lack of buffer
space; if it does, don't close the socket you are handing off, but try
the sendmsg() system call over again later).

Here is a code fragment to send the file descriptor:
(You can pass data in addition to the socket, like any excess
data you may have drained from it by mistake).

pass_fd_rights(s, fd, buf, buflen)
        int s, fd, buflen;
        char *buf;
{
        static struct   msghdr msg;
        static struct   iovec iov[1];

        iov->iov_base = buf;
        iov->iov_len = buflen;
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
        msg.msg_accrights = (caddr_t)&fd;
        msg.msg_accrightslen = sizeof (fd);
        sendmsg(s, &msg, 0);
}

recvmsg() is the system call you use to collect the passed file descriptor.



More information about the Comp.unix.questions mailing list