S6/UNIX domain super-server

s6 provides two programs, and, that together implement a UNIX domain super-server. A UNIX domain super-server creates a listening sream mode UNIX domain socket (i.e. a  socket for address family  ) and spawns a server program to handle each incoming connection after accepting it, so that from there on, the client communicates over the connection with the spawned server. This the UNIX domain equivalent of a TCP/IP super-server, such as xinetd or ipsvd.

This article Article description::describes [[s6's UNIX domain super-server and related tools]].

Environment variables

 * PROTO — Set by and  to the value 'IPC', as per the IPC UCSPI specification, and used by  and  to construct the names of other environment variables.
 * IPCREMOTEEUID — Set by to the effective user ID of the client, as per the IPC UCSPI specification, unless credentials lookups have been disabled. Read by  (if the value of PROTO is 'IPC') to decide whether to allow or refuse access to the server.
 * IPCREMOTEEGID — Set by to the effective group ID of the client, as per the IPC UCSPI specification, unless credentials lookups have been disabled. Read by  (if the value of PROTO is 'IPC') to decide whether to allow or refuse access to the server.
 * IPCCONNNUM — Set by to the number of connections originating from the same user (i.e. same user ID), and read by  (if the value of PROTO is 'IPC') to decide if the maximum number of connections originating from the same user will exceed the maximum allowed.
 * IPCCONNMAX — Maximum number of connections originating from the same client allowed by (if the value of PROTO is 'IPC').

s6-ipcserver-socketbinder and s6-ipcserverd
More specifically, what and  implement together is an IPC UCSPI super-server, i.e. a super-server that adheres to the server side of Daniel J. Bernstein's UNIX Client-Server Program Interface (UCSPI) and supports the IPC UCSPI protocol. The UCSPI defines an interface for client-server communications tools; UCSPI tools are executable programs that accept options, a protocol-specific address, an application name and its arguments. Tools can be either clients or servers, clients communicate with servers using a connection. If the UCSPI tool is a server, the application is invoked with the supplied arguments each time there is an incoming connection to the specified address, with file descriptor 0 opened for reading from the connection, file descriptor 1 opened for writing to the connection, and environment variables set to defined values. If the UCSPI tool is a client, a connection is made to the specified address and, if successful, the application is invoked with the supplied arguments, with file descriptor 6 opened for reading from the connection, file descriptor 7 opened for writing to the connection, and environment variables set to defined values. One of the application environment variables set by both UCSPI clients and servers is PROTO, with the name of the supported protocol as its value. The protocol implemented by the s6 programs is the IPC UCSPI protocol, for which the address specified to UCSPI tools is defined to be a UNIX domain socket pathname, and the value of PROTO is defined to be 'IPC'.

is a chain loading program that accepts options and a pathname. It creates a UNIX domain socket, binds it to the specified pathname and prepares it to accept connections with the POSIX  call. The next program in the chain will have its standard input connected to the listening socket, which will be non-blocking. The number of backlog connections, i.e. the number of outstanding connections in the socket's listen queue, can be set with the  option; additional connection attempts will be rejected by the kernel. If is invoked with a   option, the socket will be created but won't be listening, i.e.   won't be called. If it is invoked with the  option, the created socket will be a datagram mode socket, which also requires specifying a   option. If it is invoked without the  option, or with the   option, the created socket will be a stream mode socket.

is a program that must have its standard input redirected to a bound and listening stream mode UNIX domain socket, and accepts a program name and its arguments. For each connection made to the socket, executes the program with the supplied arguments as a child process, that has its file descriptors 0 and 1 redirected, on Gentoo, to the socket returned by a Linux   with the listening socket's file descriptor as an argument, and the following environment variables:


 * PROTO, IPCREMOTEEUID , IPCREMOTEEGID and IPCCONNNUM — set as specified in "Environment variables".
 * IPCREMOTEPATH — set to the pathname associated with the remote UNIX domain socket (on Gentoo, as contained in the  field of the   object filled by the   call), if any, as per the IPC UCSPI specification. Be aware that it may contain arbitrary characters.

On Gentoo, IPCREMOTEEUID and IPCREMOTEEGID are set with information obtained from a POSIX  call with the Linux   option; this is called credentials lookup. If is invoked with a   option, credentials lookup will be disabled, and IPCREMOTEEUID and IPCREMOTEEGID will be unset. If it is invoked without a  option, or with a   option, credentials lookup will be enabled. supports the s6 readiness protocol, and if it is invoked with a  option, it will turn readiness notification on, with file descriptor 1 (i.e. its standard output) as the notification channel's file descriptor.

If receives a   signal it will exit, but its children will continue running. If it receives a  signal, it will send its children a   signal followed by a   signal and then exit. If it receives a  signal, it will send its children a   signal and then exit. It is possible to make kill its children without exiting (with a   signal followed by a   signal), by sending it a   signal. ignores the  signal, so at program startup, every child process will ignore it as well.

is a helper program that accepts options, a UNIX domain socket pathname, a program name and its arguments, and invokes chained to, or  chained to , chained to , depending on the options. The socket pathname is passed to, and the program name and its arguments, to. options specify corresponding, and  options. The created socket is a stream mode socket.

For further information about, or  please consult the HTML documentation in the s6 package's  subdirectory.

s6-ipcclient
is an IPC UCSPI client. It is a chain loading program that accepts options and a UNIX domain socket pathname. It creates a stream mode socket, makes a connection to the socket specified by the supplied pathname, and executes the next program in the chain with file descriptors 6 and 7 redirected to the local connected socket, and the following environment variables:


 * PROTO — set as specified in "Environment variables".
 * IPCLOCALPATH — set to the pathname associated with the local UNIX domain socket it is using for the connection, as per the IPC UCSPI specification, with information obtained from a POSIX  call.

If is invoked with a   argument, it will bind the created socket to pathname (using the POSIX   call) before initiating the connection to the remote socket. If it is invoked with a  argument, it will set IPCLOCALPATH to value, instead of using.

For further information please consult the HTML documentation in the s6 package's subdirectory.

s6-ipcserver-access and rules files and directories
is an access control tool for UNIX domain sockets. It is a chain loading program that must be spawned by a UCSPI server (like ) that appropriately sets the PROTO, ${PROTO}REMOTEEUID and ${PROTO}REMOTEEGID environment variables, where ${PROTO} is the value of PROTO. It decides whether or not to execute the next program in the chain, or to execute a completely different program instead, based on either a rules directory or a rules file. The  option specifies the pathname of a rules directory and the   option specifies the pathname of a rules file.

If a rules directory R is specified with an  option:


 * 1)  will first search the  directory:
 * 2) (s6 version 2.8.0.0 or later) If it finds a subdirectory named, and the value of the ${PROTO}REMOTEEUID variable, which must be a numeric user ID, is equal to its effective user ID, and the subdirectory contains a file named ,  executes the next program in the chain. If the subdirectory does not contain a file named , but contains instead a file named , or if it does not contain any of those files,  exits with code 1, and the next program in the chain is not executed.
 * 3) Otherwise, if it finds a subdirectory with a name that matches the value of the ${PROTO}REMOTEEUID variable, and it contains a file named,  executes the next program in the chain. If the subdirectory does not contain a file named , but contains instead a file named , or if it does not contain any of those files,  exits with code 1, and the next program in the chain is not executed.
 * 4) If  search fails, or there is no such directory,  will then search the  directory:
 * 5) (s6 version 2.8.0.0 or later) If it finds a subdirectory named, and the value of the ${PROTO}REMOTEEGID variable, which must be a numeric group ID, is equal to its effective group ID, and the subdirectory contains a file named ,  executes the next program in the chain. If the subdirectory does not contain a file named , but contains instead a file named , or if it does not contain any of those files,  exits with code 1, and the next program in the chain is not executed.
 * 6) Otherwise, if it finds a subdirectory with a name that matches the value of the ${PROTO}REMOTEEGID variable, and it contains a file named,  executes the next program in the chain. If the subdirectory does not contain a file named , but contains instead a file named , or if it does not contain any of those files,  exits with code 1, and the next program in the chain is not executed.
 * 7) If  search fails, or there is no such directory,  will finally search for an  directory. If it contains a file named,  executes the next program in the chain. If the subdirectory does not contain a file named , but contains instead a file named , or if it does not contain any of those files,  exits with code 1, and the next program in the chain is not executed.
 * 8) If there is no  directory,  exits with code 1, and the next program in the chain is not executed.

If in any of these steps finds an  file in a matching directory M and executes the next program in the chain:


 * Unless it was invoked with an  option, it will add variable ${PROTO}LOCALPATH to the program's environment, set to the pathname associated with the local UNIX domain socket (the one its standard input and output read from and write to, respectively), as reported by the POSIX   call.
 * If it was invoked with an  option, it will remove variables PROTO, ${PROTO}REMOTEPATH , ${PROTO}REMOTEEUID , ${PROTO}REMOTEEGID and ${PROTO}CONNNUM from the program's environment.
 * If M contains a subdirectory named, will modify the program's environment as if an s6-envdir M/env command had been used.
 * If M contains a regular file named, will execute a different program instead of the one supplied as an argument, as if an execlineb -c contents command had been used, where contents is the contents of the  file (e.g. the name of a program that can be found via PATH search plus its arguments), passed to  as a single argument.  is the script parser and launcher from the execline package.

A rules file is a constant database (CDB) file created from a rules directory using the program. If a rules file is specified with an  option,  will behave as if the corresponding rules directory had been specified with an   option. A rules directory can be re-created from a rules CDB file using the program.

If is invoked with neither the   option nor the   option, it will execute the next program in the chain, i.e. it will unconditionally grant access.

For the full description of 's, 's and 's functionality please consult the HTML documentation in the s6 package's subdirectory. See also suidless privilege gain tools for usage examples.

s6-connlimit and s6-ioconnect
is a chain loading program that limits connections from the same client to an UCSPI server based on the PROTO, ${PROTO}CONNNUM , ${PROTO}CONNMAX environment variables (see environment variables), where ${PROTO} is the value of the PROTO variable.

is a program that performs data transmission from file descriptor 0 to file descriptor 7, and from file descriptor 6 to file descriptor 1, all of them assumed to be open at program startup. That is, performs full-duplex data transmission.

For the full description of 's and 's functionality please consult the HTML documentation in the s6 package's subdirectory.

Examples
The application reads from the open file descriptor supplied by the UCSPI server, expecting to receive a "Hello!" message from the client, and if it does, it sends a response that contains the application's process ID and the account database username corresponding to the client's user ID, supplied by the UCSPI server via the IPCREMOTEEUID environment variable. The application then waits for 10 seconds, and finally exits.

The application prints "Connecting to server..." to its standard output, sends a "Hello!" message to the server using the open file descriptor supplied by the UCSPI client, and waits for a reply, which is printed to its standard output. The application then exits.

Starting the UCSPI super-server:

This shows that a socket named has been created in the current working directory. Starting a UCSPI client to connect to the socket three times:

This shows that the super-server spawned three processes to handle each connection, and set the IPCREMOTEEUID environment variable to user1's user ID. s6-ipcserver test-socket ./test-server is equivalent to s6-ipcserver-socketbinder test-socket s6-ipcserverd ./test-server, but shorter. Starting a UCSPI client with effective user user2:

This shows that the super-server set the IPCREMOTEEUID environment variable to user2's user ID. Starting the super-server with the  option, and a client to connect to :

s6-ipcserver -P test-socket ./test-server is equivalent to s6-ipcserver-socketbinder test-socket s6-ipcserverd -P ./test-server, but shorter. This shows that since credentials lookup was disabled, environment variable IPCREMOTEEUID is unset, and displays "&lt;unavailable&gt;" in place of a username.