Commit Graph
96 Commits
Author SHA1 Message Date
Wez Furlong 7a9a33f836 apply cache-purge-on-low-mem to all LruCaches 2024-11-06 20:50:30 -07:00
Dirkjan Ochtman 197b73330b dkim: migrate to dns-resolver Resolver trait 2024-10-17 09:46:59 -07:00
Dirkjan Ochtman a28721f5ee dns-resolver: replace Resolver enum with a trait 2024-10-15 08:54:24 -07:00
Dirkjan Ochtman e309c8d69a dns-resolver: avoid exposing internal structure 2024-10-15 08:54:24 -07:00
Wez Furlong 379d8aebbd fixup shrinking during low memory
Two issues here:

1. The maintainer would repeatedly try to shrink the ready queue
   each time it woke up during a low memory condition.  This has
   been fixed to trigger whenever we transition to low memory
   instead.

2. At some point during refactoring, we dropped the save part
   of the message shrinking processing, so we'd only successfully
   shrink messages that had previously been saved and stored to
   spool.  Messages that we deferred spooling, or otherwise modified
   post reception, would not be saved and thus not be eligible to
   shrink.

Ideally we'd have an integration test for this, but it is a bit awkward
because we'd need to contrive an appropriate ulimit for just this
instance and generate appropriate load to trip over that limit.  I don't
fancy the chances that such a test wouldn't be flakey.

My ad-hoc test procedure was:

ulimit -m 2028527
./target/release/kumod  --policy simple_policy.lua

then in another window:

./target/release/traffic-gen --target 127.0.0.1:2025 --body-size 100000 --duration 3600 --throttle 15000/s --http

the generator will eventially experience load shedding http responses,
and you can see the shrink procedure triggering in the kumod output.

curl -s 'http://127.0.0.1:8000/metrics' | grep memory

can also be used to check the usage, limit and how many times it trips.

You can also use smtp for this, but the smtp client in traffic gen will
try hard to reconnect without telling you about the shortage, so you
will need to look at the metrics to see it happening.
2024-10-02 14:49:28 -07:00
Wez Furlong f4390fc95a dkim signing: add preliminary support for dkim signing pool
We've been examining a system using http injection where it
appears as though dkim signing might benefit from being broken
out into a dedicated cpu-bound thread pool.

This commit is a fairly quick prototype to allow us to explore
that.

It isn't quite what I'd consider to be the end state for this,
because the pool doesn't export metrics like the others do.
That is because this is a blocking pool rather than an async
pool.

Usage is to define the pool in pre_init:

```
 kumo.on('pre_init', function()
   kumo.dkim.set_signing_threads(24)
 end)
```

If you don't define a pool, then the signing happens
on the calling thread, just as in prior versions.
2024-09-25 12:24:04 -07:00
Dirkjan Ochtman 4df3bfd471 Replace lazy-static with LazyLock 2024-09-24 06:31:21 -07:00
Wez Furlong 7ec15e9b09 message: refactor: split QueueNameComponents into separate module
No functional change
2024-09-12 13:34:36 -07:00
Wez Furlong 0f153774f3 message: reduce MessageInner size from 144 to 32 bytes
A message in the scheduled queue will thus occupy 32 bytes (with
metadata unloaded), plus 8 bytes per Message reference. For TimerWheel
and SkipList queues, that's just 8 bytes. For SingletonTimerWheel it is
2*8 bytes (one for the queue and one for the singleton wheel).  The
singleton usage is overall lower though, because the wheel overheads are
reduced to a single wheel in that mode.
2024-09-02 10:42:14 -07:00
Wez Furlong 3d4a5d2194 mailparsing: relax Content-ID and Message-ID parsing
This is an area where conformance is inconsistently applied by
various clients, so we're relaxing our parser to try the current
strict rules first, which can normalize stuff like `<"foo"@id>`,
but then allow falling back to anything between `<>`.

We will still blow up for wonky stuff like `<<wat>>`, as proven
by our existing test coverage.

closes: #259
2024-08-26 08:11:20 -07:00
Wez Furlong a7cddd64bb message: allowing hashing and taking a weak reference 2024-08-24 17:31:28 -07:00
Wez Furlong ceb54eac6c message: add cache hit/miss/lookup counters for dkim signer 2024-08-22 11:07:08 -07:00
Wez Furlong 6fcb8ca47e add dkim signing histograms to metrics 2024-08-20 10:03:26 -07:00
Wez Furlong 282c67171e message: save 16 bytes per Message handle
Adjust how we track the data in Message to make it a little smaller
and cheaper to maintain multiple clones.

Previously, to avoid locking overhead during debug or other
introspection, we kept the spoolid (a 16-byte uuid) outside of the
Arc<Mutex<Inner>>.  This has the consequence of making a fatter
handle type and there are a number of places (notably, every
time we pass the message into lua) where we might clone the
handle.

This commit introduces another intermediate type so that we can make
Message effectively equivalent to an Arc (size == pointer size)
and then the intermediate type has the spoolid outside of the mutex,
with the mutex protected data alongside it.

This changes the size of Message from 16 + 8 to just 8.
For a single Message handle we don't really save anything overall,
because the same amount of data needs to exist, but for each subsequent
clone we save 16 bytes.
2024-08-19 19:53:08 -07:00
Wez Furlong 9aea77a80b timeq: remove cancellation functionality
We weren't using this outside of the unit tests, and it introduces
additional memory overheads and a layer of indirection that we
can do without, so let's remove it.
2024-08-15 18:32:52 -07:00
Wez Furlong d4ccf76c3a message: add latency histograms for saving and meta/data loading 2024-08-15 15:16:38 -07:00
Wez Furlong c524ef5d11 deps: upgrade mlua from 0.8 -> 0.9
I've been holding off on this for a while, because I remember
this upgrade being a bit of a PITA for wezterm.  Since then
there is a `derive(FromLua)` that makes the transition much
easier.

This upgrade makes it potentially a bit easier/nicer/cheaper for
memoize, because it is now possible to retrieve references to userdata
values (rather than always cloning them), but I haven't done anything
special to take advantage of that in this commit.
2024-06-28 17:28:42 -07:00
Wez Furlong a2d76df7a9 NEW: rebind API and kcli subcommand
refs: https://github.com/KumoCorp/kumomta/issues/209
2024-06-24 12:26:06 -07:00
Wez Furlong 626a7608e4 Fix bad message-id breaking message rebuild
The issue only triggered when there were issues that required
rebuilding the message body in addition to the bad header.

The fix here is to silently ignore any header parsing errors
during a rebuild.

closes: #216
2024-06-17 13:50:53 -07:00
Wez Furlong a1fae3a634 rocksdb: improve write/delete throughput
This adjusts how we do write and delete operations so that we
first try to immediately submit the operation to the WAL,
but if that would block, then we push the operation to
the tokio blocking thread pool in order not to hard-block
the tokio schedule thread when rocksdb needs to perform writes.

While in there, hook up the force-sync flag to the closest
approximation in the WriteOptions for the batch (of size 1).
2024-05-03 20:03:49 -07:00
Wez Furlong e81a5fb6ca fix: msg:set_scheduling didn't immediately recompute due time 2024-04-09 14:34:38 -07:00
Wez Furlong 4cbe681d8d msg: remove stray debug prints from scheduling logic 2024-04-09 14:32:30 -07:00
Wez Furlong 898ed52410 add msg:append_text_html and msg:append_text_html
These can be used to insert tracking pixels/links.

closes: https://github.com/KumoCorp/kumomta/issues/120
2024-03-31 14:04:46 -07:00
Wez Furlong 1fb712e2bf Add msg:set_data()
This method allows replacing the message payload arbitrarily.
This is a building block for more advanced and convenient
modification operations.

refs: https://github.com/KumoCorp/kumomta/issues/117
refs: https://github.com/KumoCorp/kumomta/issues/120
2024-03-31 06:57:59 -07:00
Wez Furlong 78e062ad64 chrono: fixup now-deprecated calls 2024-03-11 07:50:01 -07:00
Wez Furlong 33c7557afb msg: add num_attempts, set_due and queue_name methods
refs: https://github.com/KumoCorp/kumomta/issues/149
2024-03-08 13:35:03 -07:00
Wez Furlong 81a79ace76 add more context to "Data is not ASCII or UTF-8" errors
We've had a report that `msg:from_header().domain` is failing
on an input in an unexpected way with this error message,
so let's try to get a bit more context on what is happening.
2024-02-27 06:46:29 -07:00
ncai c3c5e34067 add default to dkim over_sign 2024-01-26 05:59:11 -07:00
Wez Furlong 02cd1ef7bf NEW: dkim over signing by setting over_sign = true in the signer
refs: https://github.com/KumoCorp/kumomta/issues/111
2024-01-18 12:59:41 -07:00
Wez Furlong e6973c2a04 slim down some deps
This helps to remove "false" deps on things like openssl; now that
is linked in only to those components that need it (eg: things that
use unbound for dnssec, or the smtp client for DANE).

This makes the binaries other than kumod (which still has max deps)
a few MB smaller; not a massive win, but nice all the same.
2023-12-22 10:24:30 -07:00
Wez Furlong e9ec19fd23 fix an issue where msg:[sg]et_meta would not round-trip nil values 2023-12-13 14:21:12 -07:00
Wez Furlong 06bb8d0492 add msg:add_authentication_results
This method will prepend an Authentication-Results header
to the message with the specified set of results and
local server name.

We need a more convenient way to default the server name;
ideally we'd pick this up from the listener, but that is currently
awkward in the policy.

refs: https://github.com/KumoCorp/kumomta/issues/82
2023-09-14 13:03:41 -07:00
Wez Furlong e4bb5d674d add msg:dkim_verify()
This method returns an array of AuthenticationResult reflecting
the verification status.

refs: https://github.com/KumoCorp/kumomta/issues/82
2023-09-14 13:03:41 -07:00
Wez Furlong 134014d988 message: avoid rebuilding when the fix only requires adding headers 2023-08-29 17:22:09 -07:00
Wez Furlong 0b21193b8a add msg:check_fix_conformance()
This is for check and/or fixing message conformance issues.
2023-08-29 16:18:59 -07:00
Wez Furlong a36eee80f0 message: make retain_headers more efficient
Avoid an intermediate string allocation; we can write directly
to the new buffer.
2023-08-25 08:55:30 -07:00
Wez Furlong ff9937d8db message: replace mailparse dep with our mailparsing crate
The tests that are fixed up as part of this show that we're doing a
better job at preserving technically bogus stuff like `Name :value`.
2023-08-25 08:55:29 -07:00
Wez Furlong ce8596f248 message: mostly adopt mailparsing
This doesn't replace the retain/remove methods,
because we don't have that aspect of the API fleshed out
yet.
2023-08-25 08:55:29 -07:00
Wez Furlong e03ee5badf message: replace mailparser dep with mailparsing
Use our own parser
2023-08-25 08:55:28 -07:00
Wez Furlong 909cc95001 dkim: improve error reporting around message parsing
Use Result rather than Option.
Bubble up non-canonical line endings explicitly as an issue.
2023-08-25 08:55:28 -07:00
Wez Furlong 452bede2e1 dkim: switch to our own mailparsing implementation 2023-08-25 08:55:28 -07:00
Wez Furlong 6fead2d6b2 rename our forked dkim crate
We're diverging a decent amount, so let's use our own name
2023-08-25 08:55:28 -07:00
Wez Furlong 05e52d4ce6 message: switch ed25519 dkim signing to cfdkim
With the upgraded ed25519-dalek crate, it's now possible to
pass in either DER or PEM encoded PKCS8 signing keys, which
makes it feasible to remove the mail-auth dep from this crate.

That in turns reduces the amount of code in here, which is nice.
2023-08-22 17:27:06 -07:00
Wez Furlong 71924490d3 message: add set_recipient and set_sender methods 2023-08-15 14:51:35 -07:00
Wez Furlong 3fd76dd45a introduce routing_domain concept
Augments our queue name format to be
`campaign:tenant@domain!routing_domain`.

The routing_domain is optional.  If the routing_domain is not set, its
effective value is that of the recipient domain.

You can `msg:set_meta('routing_domain', 'bar.com')` to set the
routing_domain for a message, so if the original recipient was
`user@foo.com`, that would cause the computed queue name for it to be
`foo.com!bar.com`.

The routing_domain is used when deciding on the ready_queue name
and destination MXs, so continuing our example, instead of resolving
`foo.com` MX records we'd resolve `bar.com` and deliver to that site.

The `get_egress_path_config` event `domain` parameter is redefined to be
the effective `routing_domain`.

The `get_queue_config` event `domain` parameter is the regular recipient
domain. The `routing_domain` is not currently made available to
`get_queue_config`. If/when we expose it, it will likely be via a
queue name object instead of adding an additional parameter. That would
be a breaking change.

The consequence of not exposing this parameter is that per-message
routing scenarios for the same domain (but different routing domains)
cannot vary the scheduled queue parmeters (eg: retry intervals). Even
though they would have separate scheduled queue instances, those
instances would have the same scheduled queue parameters.  If you need
to be able to do that, then explicitly setting the domain portion of the
queue name would be a way to do that: `msg:set_meta('queue',
'foo.com-via-bar.com!bar.com')`.  `get_queue_config` would then be
called with `domain='foo.com-via-bar.com'` and your policy could then
respond accordingly.
2023-08-10 08:43:20 -07:00
Wez Furlong 927e18dd58 kcli queue-summary: use emoji to indicate suspensions and bounces
Use the pause emoji for suspensions, and the wastebasket emoji for
bounces.  These are shown in the final column of the respective
sections.

Note that for bounces there will only be a short time window where you
will see a bounced domain show up in the list because the bounce will
remove it from the system fairly quickly.
2023-08-05 13:43:58 -07:00
Wez Furlong 61b84099f0 deps: update bitflags 2023-07-20 13:18:33 -07:00
Wez Furlong dde4b29fba api/cli: add inspect-message API for looking at a message by id
More detailed docs will follow once some other similar APIs are
completed.
2023-07-18 11:22:57 -07:00
M.L. Oelering c7be51ce9e Pluralize remove_all_named_header 2023-07-06 14:29:59 -07:00
M.L. Oelering 72f61662f5 Run make fmt to fix formatting issue 2023-07-06 14:29:59 -07:00