s6-dns: the skadnsd internal program
Keywords: s6-dns skadnsd asynchronous dns daemon

libskadns
s6-dns
Software
skarnet.org

# The `skadnsd` program

`skadnsd` is the skadns daemon. It reads a series of queries from the client its stdin socket, resolves them asynchronously, and sends the answers back to the client as soon as it gets them. It exits 0 when its stdin closes. It exits 111 on any serious error, writing the error message to stderr.

`skadnsd` is a stub resolver. It reads `/etc/resolv.conf` at start looking for a "nameserver" line containing the address of a DNS cache (aka full resolver). It will exit 111 if it cannot find any valid cache address in `/etc/resolv.conf`. If the `DNSCACHEIP` environment variable is set, its value overrides what `/etc/resolv.conf` says.

## Interface

skadnsd does not fork, does not background itself automatically, and does not use syslog. It is not meant to be run directly by the user: it will be invoked and spawned by the skadns library calls.

There are 2 ways to use skadnsd:

1. (preferred) Use the `skadns_startf()` library call. A `skadnsd` child will then be spawned from your calling process, and automatically reaped when you call `skadns_end()`. It requires care with applications that trap SIGCHLD.
2. Use the `skadns_start()` library call, together with a skadnsd service.

### Running skadnsd as a child process

This is the simplest and safest way of using skadns. Forget about `skadnsd`: just start your library calls with `skadns_startf()` and end them with `skadns_end()`. Be careful though: if you're using SIGCHLD handlers, make sure they do not interfere with the child processes your application has without knowing. This is a general Unix programming rule.

### Running a skadnsd as a daemon: the skadnsd service

In this mode, you set up a daemon listening on a Unix domain socket, and clients connect to this socket to access the service. The advantage of this setup is that it works even with badly written clients that have trouble handling a child process; the drawback is that it requires support from the system administrator.

skadnsd has no "standalone" mode: it is designed to work with a Unix domain superserver, like s6-ipcserver. skadnsd follows the UCSPI interface, it can be directly executed from the superserver.

You should run skadnsd (and its Unix superserver) under a specific user and group, for elementary security reasons; and you should run its dedicated logger as another specific user. Do NOT run skadnsd as root; check your super-server documentation to find how to run it under a specific account.

## Notes

- Users should never invoke `skadnsd` directly. It's an internal program designed to be spawned by the skadns library. It follows skalibs' "skaclient" protocol and is unusable unless spawned by the right client library also using that protocol.
- If a poorly designed client sends a lot of queries and never reads the answers, those will indefinitely queue up in the daemon, eating up memory. You should run your process (or your Unix superserver, if you're using a skadnsd service) under a program like s6-softlimit to set a memory limit to every skadnsd instance. If skadnsd runs out of allowed memory, it will simply die.
- If you're using a skadnsd service: you should configure your Unix superserver to set a maximum number of concurrent skadnsd instances; most Unix superserver implementations provide the `-c` option for this. The s6-ipcserver program also allows you to specify a maximum number of concurrent daemon instances per client.
- The only way to ensure absolute reliability of the skadnsd process is to run it as a child, not as a daemon: use `skadnsd_startf()` when possible.