varlink / libvarlink

C implementation of the Varlink protocol and command line tool
Apache License 2.0
87 stars 15 forks source link

Support Varlink connection on an existing, connected UNIX socket #64

Open polarina opened 3 months ago

polarina commented 3 months ago

The varlinkctl utility in systemd supports fork+execve'ing a process rather than utilizing the traditional method of connecting to an existing UNIX socket.

When invoking an executable in this manner, it creates a connected UNIX socket via socketpair and passes one end to the executable as file descriptor 3.

varlinkctl call ./a.out com.example.Method '{}'

Passing this file descriptor as listen_fd to varlink_service_new fails as the library attempts to call accept4 on the connected socket.

It would be great if varlink_service_new detects whether listen_fd is a connected UNIX socket, rather than a listening socket, and assumes it's an already accepted connection.

Systemd's Varlink services do roughly this to tell if the file descriptor is a listening socket passed by the service's corresponding .socket unit, or is directly invoked via varlinkctl:

int b;
socklen_t l = sizeof(b);
if (getsockopt(listen_fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0) {
    // TODO: errno
}
if (b) {
    // This is a listening socket
} else {
    // This is a connected socket
}