How to defer things in Exim
Normally, Exim routers will only accept or fail addresses (or be uninterested in them). This is good enough for normal handling of addresses, but if you are using routers to their full power, there are times when you want to force routers to defer addresses instead. There are two general ways to do this.
(Unsuccessful DNS lookups can cause addresses to defer, but this is not normally under your control.)
The straightforward way is to use a separate router to explicitly defer
the address using the :defer:
action of the redirect
driver, like
so:
defer_addr: driver = redirect allow_defer data = :defer:stalling [... whatever condition needed ...]
Using a separate router is straightforward and makes for clear log messages about what is going on. However, it's not always possible (or desirable) to use a separate router. In that case you can abuse string expansion to cause an expansion failure while expanding some option where this will force the router to defer.
This is moderately tricky for two reasons. First, you cannot just force
string expansion to fail explicitly (via an ${if}
or the like),
because explicit failure doesn't wind up causing options to defer this
way; instead, the router generally fails or passes on the address. Only
'natural' expansion failure, for reasons that Exim thinks are outside of
your control, cause this failure. The one case that I know of is if you
use ${readfile}
on a nonexistent file.
Second, you need to pick a router option where expansion failure
causes a deferral and, ideally, that you are not already using.
The Exim documentation is the final authority on what router
options will do for this (see generic options for routers
and check what each option does on non-forced expansion failure);
the one that I have found useful in our mailer configuration is
address_data
. Thus, part of our deliver-to-/var/mail
router
looks like:
postbox: driver = accept transport = local_delivery # make sure it's mounted address_data = ${readfile{/var/mail/.MOUNTED}} [....]
(Our /var/mail
is NFS mounted on the mail server, and obviously
we only want to do deliveries there if it is the real, NFS-mounted
filesystem, not the empty directory that's visible if the mount has
failed for some reason. .MOUNTED
is just an empty file.)
The drawback of this approach is that Exim will log alarmed looking and rather cryptic error messages if the condition every fails and forces messages to be deferred, so it is best reserved for conditions that you don't expect to happen very often.
|
|