docs: Minor editing
Fix whitespace in main
cleanup: Clean up some little things
peertable: Simplify code
build: Add V option to makefile for verbose output
serve: Handle GOODBYE messages in a better way

This is a bit of a temporary fix.  GOODBYE messages shouldn't be in this
layer.  They should be in the HSHAKE layer or something.
chat: Remove obsolete CHAT_NACK message type
sanitise: Add support for stack-switching under AddressSanitiser

AddressSanitiser requires some funny wee functions to be called when we
switch stacks so that it can track which stack memory we're meant to be
msg: Rename protocols and create new (n)ack proto
Switch to a fibre-per-peer model in the server

The server now spins off a low-priority fibre for processing handshakes.
When that fibre successfully completes a handshake with a peer, it spins
off a fibre for handling incoming packets from that peer.  The
datagram-handling fibre only calls recvfrom and puts the received
datagram into the correct queue (hshakeq or peer->recvq).
main: Add nullprogram's optparse.h
alice: Use lockedbuf for identity keys
packet: Use queue(3) SLIST in packet_state

The linked lists used for the skipped message keys and the pools of
message keys are hereby reimplemented using the macros in queue.h,
lifted from OpenBSD queue(3).
queue: Bundle OpenBSD queue(3) instead using glibc

musl does not include sys/queue.h, with pretty decent rationale.
OpenBSD queue(3) is well-written and permissively licensed, so it can be
(and now is) included in aether.
util: Simplify errnowrap to use "%m"
build: Add debug musl build (musldebug)
alice: Fix file name bug
fibre: Use queue(3) instead of custom linked lists
Redesign how protocol messages are (de)serialised

Before, messages sent over the network were serialised and deserialised
by means of structs containing uint8_t arrays.  It can be reasonably
assumed that these will be padding-free on every remotely reasonable
platform.  However, that isn't guaranteed and the code ends up being
rather ugly, full of casts between (uint8_t *) and (struct msg_X *).

Now, the persist_load*/persist_store* functions are used to write things
out in a safe and well-defined way.  These functions support loading and
storing uint{8,16,32,64}_t, uint8_t[N] and uint32_t-length-prefixed
variable-length arrays of uint8_t.  Any new features can be added

The other main advantage of doing it this way is that failure handling
is essentially mandatory while still being very flexible.  It is easy to
imagine doing things like this:

ptrdiff_t remaining = size - footer_size;
while (!persist_storebytes(keys, 32, &out, &remaining));
/* still room left for the footer after the maximal number of keys */

which would still work perfectly with a runtime-variable maximum size -
such as the path MTU of the client-server network path.
persist: Expand the supported load/store widths