server/: Make initialization errors be non-fatal and restartable.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 19 May 2018 21:03:28 +0000 (22:03 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 5 Sep 2019 12:07:21 +0000 (13:07 +0100)
commit9d966eb7af70d029a9b4862efb67b0c90d32688e
tree9c88bd87fd0be47cffc3a6fd13f266b7c9d2847a
parent98b9b13628a7613868e0fda618e6303961932550
server/: Make initialization errors be non-fatal and restartable.

It should now be possible to trap any error during startup, change any
part of the configuration, shut down the affected components, and
restart everything again, without taking down the whole process.

Mostly, this involves replacing the existing calls to `exit' with
goto-cleanup and return codes.  In some cases, the existing
functionality has been reordered to make cleanup easier.  I didn't leave
this for a separate commit, because including those changes here makes
it clearer what they're for and should make it easier to check that
they're the right fixes.

The details are:

  * admin.c (a_listen): Move resetting the `umask' to the end.

    Specifically, after the last part of the function that can fail.
    This avoids a double reset if the final part, the call to listen(2),
    fails.

  * admin.c (a_init): Move creation of the service table to the end.

    This isn't (currently) a thing that can be cleaned up, so do it only
    after the parts that can fail -- specifically, initializing ADNS.

  * keymgmt.c (kh_init): Use `kh->kf' as a flag to prevent double init.

    As mentioned earlier, this is cleared by the static initializer, so
    we can safely assume that `kh->kf' is null if and only if the
    keyhalf requires initialization.

    Also, reorder slightly, to establish the cache hashtable only after
    the keyring file has been read.

  * keymgmt.c (km_init): Refresh before fetching the master key.

    Suppose we fail to initialize because the master key is missing.
    The right fix is to update the keyring file with the proper key, and
    then retry.  But at this point the private keyhalf has been
    initialized; so we must force a refresh of the keyring data.

  * keymgmt.c (km_init): Be idempotent regarding the master key.

    If there's a master key cached, then don't clobber it if we can't
    find it again.  On the other hand, if we find a different one this
    time then switch.
server/admin.c
server/keymgmt.c
server/peer.c
server/privsep.c
server/standalone.c
server/tripe.h
server/tun-slip.c
server/tun-std.c