* Reuse the tls acceptor stuff from the smtp_server.
We'll automatically generate self-signed certs when
none are provided.
* Add trusted_hosts setting for the http server
* Add an auth middleware that will accept connections from
trusted hosts as pre-authenticated. Other hosts must provide
http authorization.
* Add lua hooks for the policy script to validate either http
basic auth (user+pass), or bearer auth (token).
There's not currently an authentication storage subsystem, but
the lua hook allows for very basic stuff to be configured, and
could also be used to employ eg: looking things up from a database
once we add some lua utility functions for that purpose.
The `/metrics` endpoint will only respond to trusted IPs.
Other endpoints all require some kind of successful authentication.
QueueManager::insert could acquire MANAGER lock then a queue handle
lock.
Meanwhile, the queue maintainer would hold a queue handle lock
and then attempt to acquire MANAGER lock when idling out and removing
itself, leading to a livelock because MANAGER is protected by a
tokio Mutex which ping pongs in and out of the event loop.
A downside of pulling in rocksdb is that it is a pretty big
C++ library and musl/alpine don't really get on with it.
Switch to using the latest ubuntu LTS image as our base.
Adds some plumbing that allows the application to request
a shutdown that is channelled along the same path as ctrl-c
handling.
If we have errors defining spools or during spool start,
then we request a shutdown on the basis that we can't store
anything and it would be unsafe to continue.
This teaches the smtp listener and delivery sides
how to shutdown when a shutdown is requested, as well
as how to indicate when they are still doing important
work.
This doesn't guarantee that any deferred spooling is
done; that will be part 2.
I don't plan to remove compression or to allow it to be disabled: it
makes a massive difference to the size of the log files and saves IO and
storage space.
Same for "rcpt to". The <> are required in the ABNF in the spec,
but they are widely considered to be optional by major implementations,
which makes it convenient when ad-hoc testing via telnet.
We require the <> when ESMTP mail from or rcpt to parameters are
used.
We require that `--user username` be passed and specify
the user id that we should assume instead of running as
root.
We do the magic setup needed to preserve the ability
to bind to port 25 while dropping the other privs.
A fairly sprawling commit:
* Move config to its own crate to facilitate making things more modular
* Crates/modules can now provide a registration function that can be
used to setup functions in the lua environment
* Message crate now has a dkim module with a signer type that can
be loaded from lua; signers are cached (with ttl) and shareable
* Message now has a dkim_sign method that does the signing, as well
as methods for appending and prepending headers that are necessary
to support signing.
Looks pretty good compared to Sled.
|kind | flush | throughput |
+-------------+-------+------------+
|RocksDB | false | 102mm/hr |
|RocksDB | true | 96mm/hr | *
|Sled | false | 96mm/hr |
|Sled | true | 34mm/hr |
|LocalDisk | false | 24mm/hr |
|LocalDisk | true | 1mm/hr |
These numbers are from a 5950x (32 core) with an nvme drive,
as reported by:
```
cargo run --release -p traffic-gen -- --target 127.0.0.1:2025 --duration 20 --concurrency 16024
```
Note that the flush implementation with rocksdb just adjusts the setting
of use_fsync when opening the database.
There is an explicit db-wide flush that can be called, but it is very
aggressive and thorougly tanks performance down to 0.25mm/hr.
Note as well that rocksdb has a number of configuration options that may
work better as a write-once spool than the currently selected defaults;
more analysis could be done, but at the time of writing this commit
message, the defaults are the best performing storage option and going
further isn't a priority.
Add a `kind` and `flush` fields when defining a spool. Add a new
[sled](https://docs.rs/sled/latest/sled/index.html) based spool
implementation.
Initial benchmarking, especially at high concurrency, shows
promising numbers:
|kind | flush | throughput |
+-------------+-------+------------+
|Sled | false | 96mm/hr |
|Sled | true | 34mm/hr |
|LocalDisk | false | 24mm/hr |
|LocalDisk | true | 1mm/hr |
These numbers are from a 5950x (32 core) with an nvme drive,
as reported by:
```
cargo run --release -p traffic-gen -- --target 127.0.0.1:2025 --duration 20 --concurrency 16024
```
What's the catch? sled is considered beta by its authors.
https://github.com/spacejam/sled#known-issues-warnings
At very high concurrency we can get a bit stuck waiting for
the tasks to finish.
Adjust so that we wait for the desired duration and sample the
count at that point, then we'll proceed to report that without
worrying about joining the sender tasks.