Commit Graph

3539 Commits

Author SHA1 Message Date
Wez Furlong 55ec7126ff an integration test around mx_list refreshing
It passes, and I'm not sure that I want to commit it as-is, because
it takes ~17 seconds to run due to the way that config refreshing
works.  The latency is much lower when using epoch based testing,
but we're not sure if either is significant at this time.
2026-03-01 08:17:28 +00:00
Aditya Ganti f0e48bdb27 dkim: fix wrapping issue
It was reported that AWS SES could mark the DKIM signature as failed
when using a specific combination of headers in the header list,
with specific lengths of the other fields.

The reason for this is that we had two passes of wrapping applied
to the header, and they might not agree on the formatting of
the header.

The solution is to remove the second pass and just take a bit more
care to emit the header in a wrapped form in the first instance,
that way there can be no discrepancy or conflict.

closes: https://github.com/KumoCorp/kumomta/pull/483
2026-02-28 08:17:09 +00:00
Wez Furlong 04076707ec http injection: template errors are now reported with status 422
As part of this, we move template compilation to happen before
we queue up deferred generation; the compilation step should
be plenty fast enough that we can reasonably do that synchronously
and report any compilation errors back to the peer.
2026-02-25 14:25:38 +00:00
Wez Furlong 5bb60b06d0 smtp_dispatcher: improve handling of unilateral disconnects
The goal is to treat peer-initiated-unilateral-disconnects as being
somewhat equivalent to the way that we would idle out the connection if
we had no messages for it, on the supposition that the most likely
cause of a disconnect in between command verbs that we send is that
the peer decided that we were idle too long.  That isn't the only
possible reason, but it is the motivating example.

For the idled-out case we should close the current session and
have our message(s) go out on a separate session.  We don't want
to try the next host in the connection plan in case we're talking
to some kind of honey pit configuration where only the first
MX in the plan is valid, and even talking to a secondary can
harm your ability to send to the first in the future.

Handling this is a little tricky because we need to take care of
the distinction between getting a unilateral before or after
we've attempted to send a message.

In the before-case we don't want to blindly assume that we should start
a new session because that would mean that a persistent issue on the
first MX would have us spinning our wheels trying new connections only
to the first MX over and over.

This commit adds a couple of integration tests that contrive situations
where we exercise some pertinent cases.

refs: https://github.com/KumoCorp/kumomta/pull/482
2026-02-25 13:26:17 +00:00
Wez Furlong b018f8f128 machine-info: add docs/examples to jsonschema 2026-02-24 13:59:18 +00:00
Wez Furlong 3bc3da882b cargo update 2026-02-24 13:03:44 +00:00
Wez Furlong 2d1a31741f docs: add a page discussing the Node ID 2026-02-24 12:59:00 +00:00
Wez Furlong d8a7b0170e add new cpu usage metrics
refs: https://github.com/KumoCorp/kumomta/issues/186
2026-02-24 12:19:54 +00:00
Wez Furlong 942d0463b5 Makefile: force alternate node-id for my sink configs
I'd rather that they didn't fall back to synthesizing the same
node-specific id when I run my non-kumod-user test setups.
2026-02-24 12:19:54 +00:00
Wez Furlong 51a50e91c8 kumo-prometheus: re-export Map type for convenience 2026-02-24 12:19:54 +00:00
Wez Furlong 909b1190cd refactor: extract kumo-api-client from kcli
This enables reusing just the http client parts of kcli
in another module in the future.
2026-02-24 12:19:53 +00:00
Wez Furlong 9bd3a5da23 introduce kumo-machine-info crate
This crate queries machine/system information which is intended
to be used in system monitoring.

This information is not centrally collected or retained by kumocorp,
merely reported via an API endpoint which is accessible only to trusted
IPs.

Machine info tries to interrogate information about the running/hosting
cloud platform for the major cloud providers, as well as indicate
whether it is running in a container of some kind.

The full cloud information is not re-exported via the API endpoint at
this time, but a fingerprint that encodes things like the instance-id is
included.
2026-02-24 12:19:53 +00:00
Wez Furlong 698433172e rabbit: fix test wait condition
We'd sometimes get a spurious timeout because we'd wait for
the SMTP message to hit the sink before shutting it down,
but not the AMQP messages to be delivered.
2026-02-24 11:03:44 +00:00
Tobias Horst 719e140f0e mod_nats: integrate nats
Publish messages using the jetstream client.
Supports password and token authentication.

Co-authored-by: Wez Furlong <wez@wezfurlong.org>
Closes: https://github.com/KumoCorp/kumomta/pull/449
2026-02-24 11:03:43 +00:00
Daniel Smith 9dd4078c44 update rules for orange 2026-02-23 13:57:24 -05:00
Daniel Smith ecc2d09d01 update community shaping to use providers 2026-02-23 13:57:24 -05:00
Wez Furlong 9847867dc4 smtp_dispatcher: improve dead connection detection between sends
This is an alternative implementation of
https://github.com/KumoCorp/kumomta/pull/482 that checks for a
unilateral response as part of deciding whether we can re-use
the current connection.

By detecting this condition before we've popped a message, we avoid
classifying that message attempt as a transient connection failure, and
can send it with lower latency overall.

closes: https://github.com/KumoCorp/kumomta/pull/482
2026-02-21 07:25:40 +00:00
Wez Furlong 80decbc08e redis: add redis_operation_latency histogram
This enables tracking the latency and status of redis operations.
2026-02-20 08:15:09 +00:00
Wez Furlong 11e952fa98 shaping.lua: stylua format 2026-02-20 08:08:38 +00:00
Wez Furlong 5f7fae1d6b tsa: add basic /tsa/status endpoint
This simply returns a 200 response and can be used to determine
that TSA service is up.
2026-02-20 06:51:23 +00:00
Wez Furlong 26135a2b53 filter out not-relevant-to-TSA events earlier in the logging
I believe this to be more of a micro optimization, because the
heavy lifting was already being done in the should_enq function,
which filters out before we commit the event to the spool.

Thanks to @smsvip for noticing that there was a discrepancy
between the UNINTERESTING_LOG_RECORD_TYPES and the per-record
configuration; we now use the former to derive the latter.

I've add more obviously irrelevant to TSA types to the config
as part of this commit.

refs: https://github.com/KumoCorp/kumomta/pull/481
refs: https://github.com/KumoCorp/kumomta/issues/478
2026-02-18 15:05:18 +00:00
Wez Furlong b2b3889077 docs: changelog for #480 2026-02-16 11:04:27 +00:00
Edgar Vaitkevicius 77cd5152d3 Avoid overflow when calculating delay 2026-02-16 11:00:30 +00:00
Wez Furlong 6193331a4a http/xfer injection: grab Activity handle for duration of request
I noticed that we weren't grabbing the Activity handle for injection
requests.  Doing so allows us to reject a request that comes in
while we are shutting down the service, rather than accept it to
have it potentially dropped as we shut down.

I also realized that we need to make the xfer injection handler
match the same set of rules for the http injection handler, so
this commit refactors that logic to reuse it in both places.
2026-02-11 06:17:17 +00:00
Wez Furlong 188356e64d http injection: fix early startup race condition w/ spool
If you start up while injectors are actively trying to send,
you might trigger a race condition where the spool isn't fully
assigned by the time that an injection request wants to store
a message to the spool.

Add a similar check for spool readiness to what we have in
the smtp server path.
2026-02-10 06:57:01 +00:00
Wez Furlong c79723d6ef server-common: allow registering middleware layers to http router 2026-02-09 09:02:33 +00:00
Wez Furlong dbd6d85b64 version-info: allow embedding into another project 2026-02-09 07:59:10 +00:00
Wez Furlong 9eeca8de4b cargo update 2026-02-06 07:38:00 +00:00
Wez Furlong c9ae7b5fed docs: changelog for #472 2026-02-06 07:35:00 +00:00
Wez Furlong 1690e6526a refactor: move start_proxy_listener to proxy module
We're keeping a reference to it via kumo.start_proxy_listener briefly,
just in case someone is using that live somewhere.

We don't need to changelog this, as this whole feature hasn't
been in a stable tag yet.

refs: https://github.com/KumoCorp/kumomta/pull/472
2026-02-06 07:31:30 +00:00
Wez Furlong 37111c8036 add auto-gen docs for proxy-server http api and metrics
refs: https://github.com/KumoCorp/kumomta/pull/472
2026-02-06 07:11:56 +00:00
Wez Furlong 18f6f19f10 refactor: fold connections_accepted_for_listener into ProxySessionMetrics
refs: https://github.com/KumoCorp/kumomta/pull/472
2026-02-06 07:11:55 +00:00
Aditya Ganti f898e2a7e6 Add Prometheus metrics to proxy-server
Co-authored-by: Wez Furlong <wez@wezfurlong.org>

closes: https://github.com/KumoCorp/kumomta/pull/472
2026-02-06 07:11:27 +00:00
Wez Furlong 4f636a0fae skip_hosts: downgrade to a transient failure
This is a conceptually breaking change, but shouldn't be harmful
in practice.

Recently, Microsoft hosted domains have had a number of incidences where
the DNS stopped returning IPv4 addresses, which lead to systems that
employ skip_hosts to disable their IPv6 addresses (presumably due to
difficulties in warmup and reputation) to trigger the terminal case
where we would sweep the ready queue away as a permanent routing
failure.

In the context of a transient failure to route ipv4 the permanent
disposition was surprising and unwanted so it feels better to make
the effect of this situation more closely map to how we handle the
case where no MX records are returned.
2026-02-04 13:12:14 +00:00
Wez Furlong 29c0eb0c4b rustfmt 2026-02-04 13:11:53 +00:00
Wez Furlong 87b64c8d2b docs: flesh out docs for a number of metrics
Give some suggestions on how to interpret a number of the metrics,
as well as cross linking to relevant documentation for them.
2026-02-04 11:45:11 +00:00
Wez Furlong b728a97f6c cargo update 2026-02-04 10:16:40 +00:00
Wez Furlong 5efbc8d7c3 docs: link to metrics index from http metrics endpoint docs 2026-02-04 09:10:25 +00:00
Wez Furlong 66e5aa5508 docs: generate a page for each exported metric 2026-02-04 09:10:25 +00:00
Wez Furlong dd41e999c4 introduce declare_metric! macro
This reduces the boilerplate around declaring metrics
(counters, histograms, gauges) in their various forms,
and more or less standardizes them, making the syntax
more regular regardless of how the metrics are actually
stored.

We move the help out to doc comments, making it easier
to write a multi-line exposition on a given metric (in
the future; we're not doing that yet).

linkme is used to form a registry that can be used to
eagerly collect metadata from the various metrics.  This
will be used to drive some automated documentation
extraction for the various metrics in a future commit.
2026-02-04 09:10:25 +00:00
Wez Furlong 828eb68017 tsa: fixup json schema
This makes it possible to load the schema with utoipa's parser.
This will be useful in the next commit which adds generated
docs to the doc build.
2026-02-03 12:23:17 +00:00
Wez Furlong 5d8708daa9 docs: fix typo in the xfer injection endpoint docs 2026-02-03 08:29:11 +00:00
Wez Furlong a1014b952f docs: recurse into anyof elements in jsonschema
This allows showing eg: the XferProtocol::target field inline in the
xfer docs.
2026-02-03 08:29:11 +00:00
Wez Furlong c5a6a1fb00 Adjust docs based on code review 2026-02-03 08:29:00 +00:00
kay ozaki bf6f9104dc exposing memory config parameters 2026-02-03 08:29:00 +00:00
Wez Furlong f53ed1aeae add kumo.xfer.xfer_in_requeue for xfer during requeue
Ordinarily, the logic that calls the requeue_message event is
responsible for increasing the number of attempts, computing the revised
due time, and processing message expiration.

When using XFER to move a message to another node, we capture the
scheduling state at the point that the xfer was initiated.

If we do this inside the requeue_message event callback then we will
capture the scheduling information *prior* to the normal adjustments
that would happen later.

This commit adds kumo.xfer.xfer_in_requeue to handle this case; you pass
through the scheduling information parameters that were added to the
requeue_message event in the prior commit, and it will compute any
revised scheduling for the message before wrapping the message up
in the XFER encapsulation and moving the message to the xfer queue.

This adjusted process ignores message expiration, so if the message
is on its last retry it will be xfer'd to the target host which then
might choose to perform the expiration.  We can't handle the expiration
in the context of `requeue_message` because the event handler doesn't
own the message and has no way to signal that it has reached the end of
its life.

Folks doing xfer in requeue_message will generally be moving the message
well in advance of it being expired, so this minor limitation is not
expected to be a practical problem.
2026-02-02 15:21:43 +00:00
Wez Furlong 722cd85e82 expose more details to the lua requeue_message event 2026-02-02 15:11:15 +00:00
Wez Furlong b963a5b6a8 docs: clarify that api_xfer_inject_v1_post is an internal api 2026-02-02 13:28:00 +00:00
Wez Furlong 12c4a2f880 docs: change http generated doc disclaimer from note -> info 2026-02-02 10:32:02 +00:00
Wez Furlong ef21bfd427 add msg:increment_num_attempts method 2026-02-02 09:12:35 +00:00