On Aug 16, 2005, at 6:37 AM, Nick Kew wrote:
Spooling and dealing with multiple recipients are things I'd like to
think about now. ISTR posting about this before: I think each
recipient
needs a separate request processing cycle, because each recipient may
have completely different processing rules. Do you think we can deal
with that by creating a new suprequest for each recipient? If so,
we'll need to allow filter hooks both before and after subrequesting,
and pass each one the spooled input data.
I've thought about this and it has sort of been an avoided topic but
I think the current plan is that in smtpd_run_queue (the hook where
modules should queue or deliver the message) each registered hook
will be called with the recipient list and access to the message
until one of them returns something other than SMTPD_DECLINED or
SMTPD_OK (unlike smtpd_run_rcpt, which will stop when a module
returns SMTPD_OK).
For instance let's say you have a mail message with two recipients:
[EMAIL PROTECTED] and [EMAIL PROTECTED] and you want each to be dealt
with by different modules because one is a local address and one
should be relayed. The modules are mod_smtpd_queue_local and
mod_smtpd_queue_relay. Both of the modules have some means of
configuration which lets them know what email addresses they accept.
When smtpd_run_queue is called on them, they only accept the email
addresses they are configured for and ignore the rest. Of course if
not one module returns SMTPD_OK then we respond with some sort of 4**
error saying that we don't have a queue-er. When a server admin is
configuring the accepted email addresses for each module he should be
sure the their respective lists are mutually exclusive else he'll get
the same addresses being handled by two modules which is probably bad
news.
This design seems to satisfy the modularity that I was expecting from
mod_smtpd. Disabling local delivery or relay can be as simple as not
loading a module in a server config. Maybe mod_smtpd can even specify
a convention for email address acceptance lists like:
SmtpAcceptList my_list1 mysql://foo
SmtpAcceptList my_list2 regex:[EMAIL PROTECTED]
LocalQueueAccept my_list1
RelayQueueAccept my_list2
and mod_smtpd_queue_{local,relay} both know that they accept mail
from my_list1 and my_list2 repectively.
The problem with this design is that you have repetitious string
comparisons for each hook on smtp_run_queue. This is not a big
problem except for when the recipient list is long (~40 recipients)
and you have maybe three modules handling mail queuing. My short term
solution is that each module remove mail addresses from the recipient
list that they handled, so the list grows shorter as each queue hook
is called (this also solves the problem of email addresses handled
twice). Another short term fix for this is having mod_smtpd hash the
recipient list (md5?) as another list passed so comparisons and
lookups are quicker. I think this problem is a trade-off though for
our modularity.
Either way, lacking header parsing in mod_smtpd is being
impractically pedant since probably 99% of SMTP transfers involve
messages in the RFC 2822/MIME formats. Although I think that
maybe there will be a plugin that wants data from the DATA
command verbatim. I still feel this needs some thought.
Agreed. Maybe a hook for DATA could deal with pathological cases,
with
normal header/body handling the default? But I haven't thought it
through: I wasn't even aware of the notion of smtp-without-RFC(2)822.
I figure we'll have an input filter registered and if the data
doesn't look like RFC-(2)822, then it passes it on verbatim.
-rian